HIGH cors wildcardgorilla muxdynamodb

Cors Wildcard in Gorilla Mux with Dynamodb

Cors Wildcard in Gorilla Mux with Dynamodb — how this specific combination creates or exposes the vulnerability

A CORS wildcard (*) in a Gorilla Mux router becomes a exposure vector when responses originate from or reference data stored in DynamoDB. With a wildcard, the Access-Control-Allow-Origin header is sent for every origin, which can unintentionally expose authenticated API responses that include sensitive DynamoDB payloads. If your handlers construct responses directly from DynamoDB query results and allow credentials via Access-Control-Allow-Credentials: true, browsers will deliver those responses to any site, enabling cross-origin data reads.

Consider a pattern where a handler queries a DynamoDB table and writes results into the response writer. With a wildcard CORS policy and credentials allowed, any webpage on any origin can make authenticated requests and read the returned item attributes, including potentially primary keys or sensitive metadata. This violates the principle of least privilege and maps to the OWASP API Top 10 API1:2023 – Broken Object Level Authorization when combined with BOLA/IDOR risks, because the broad CORS rule removes the same-origin check that would otherwise limit exposure.

In a real-world scenario, an endpoint like /items/{id} fetches an item from DynamoDB by primary key. If CORS permits all origins and the response includes an Access-Control-Allow-Origin: * header along with Access-Control-Allow-Credentials: true, a malicious site can embed a script that calls this endpoint on behalf of an authenticated user. The browser includes cookies or tokens, the handler returns the DynamoDB item, and the attacker’s script reads it. Even if the endpoint enforces its own authorization, the CORS layer effectively bypasses same-origin enforcement, turning a correctly authorized DynamoDB lookup into a data leak.

Middleware-style logging or tracing that echoes request IDs or table names in headers or response bodies compounds the risk. If those values are derived from or linked to DynamoDB attributes, they may expose internal schema details cross-origin. Therefore, combining a wildcard CORS setup with any data source—especially a centralized store like DynamoDB—requires precise origin specification and careful handling of credentials to prevent unintended data exposure across origins.

Dynamodb-Specific Remediation in Gorilla Mux — concrete code fixes

Remediation centers on replacing the wildcard with an explicit origin and ensuring credentials are only allowed when necessary. In Gorilla Mux, set CORS headers in a dedicated handler or middleware so that responses include a specific origin rather than *. When credentials are not required, omit Access-Control-Allow-Credentials entirely. When credentials are required, validate the incoming Origin against an allowlist and echo it back in the header.

Below is a concise, working example of a CORS middleware for Gorilla Mux that reads from a DynamoDB table to enforce origin policies at runtime. This approach ensures that only approved origins can access responses that may include DynamoDB data, and it avoids exposing items to arbitrary web pages.

// main.go
package main

import (
    "context"
    "encoding/json"
    "net/http"
    "strings"

    "github.com/gorilla/mux"
    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/dynamodb"
)

// OriginRecord models a row in an allowlist table.
// Table: CORSAllowlist  PartitionKey: Origin (string)
type OriginRecord struct {
    Origin string `json:"origin"`
}

var cfg, _ = config.LoadDefaultConfig(context.TODO())
ddb := dynamodb.NewFromConfig(cfg)

const allowlistTable = "CORSAllowlist"

// isOriginAllowed checks DynamoDB for the given origin.
func isOriginAllowed(origin string) (bool, error) {
    out, err := ddb.GetItem(context.TODO(), &dynamodb.GetItemInput{
        TableName: aws.String(allowlistTable),
        Key: map[string]aws.AttributeValue{
            "origin": &aws.StringAttributeValue{Value: origin},
        },
    })
    if err != nil {
        return false, err
    }
    return out.Item != nil, nil
}

// corsMiddleware adds safe CORS headers based on DynamoDB allowlist.
func corsMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        reqOrigin := r.Header.Get("Origin")
        if reqOrigin == "" {
            next.ServeHTTP(w, r)
            return
        }

        allowed, err := isOriginAllowed(reqOrigin)
        if err != nil || !allowed {
            next.ServeHTTP(w, r)
            return
        }

        w.Header().Set("Access-Control-Allow-Origin", reqOrigin)
        w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS")
        w.Header().Set("Access-Control-Allow-Headers", "Authorization, Content-Type")
        // Only include credentials when you truly need them.
        // w.Header().Set("Access-Control-Allow-Credentials", "true")

        if r.Method == "OPTIONS" {
            w.WriteHeader(http.StatusOK)
            return
        }

        next.ServeHTTP(w, r)
    })
}

// getItemHandler fetches an item from DynamoDB and returns it.
func getItemHandler(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    id := vars["id"]

    out, err := ddb.GetItem(context.TODO(), &dynamodb.GetItemInput{
        TableName: aws.String("ItemsTable"),
        Key: map[string]aws.AttributeValue{
            "id": &aws.StringAttributeValue{Value: id},
        },
    })
    if err != nil || out.Item == nil {
        http.Error(w, `{"error":"not found"}`, http.StatusNotFound)
        return
    }

    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(out.Item)
}

func main() {
    r := mux.NewRouter()
    r.Use(corsMiddleware)
    r.HandleFunc("/items/{{id}}", getItemHandler).Methods("GET")
    http.ListenAndServe(":8080", r)
}

Key points specific to DynamoDB: ensure your allowlist table uses a simple schema (Origin as partition key) for fast lookups, and keep item responses minimal to reduce exposure surface. Avoid returning entire items when only a subset of attributes is needed; project only required fields at the DynamoDB level using expression attribute names if necessary. Combine this origin validation with per-endpoint authorization checks to defend against BOLA even if CORS is correctly configured.

For production, rotate credentials used by this middleware, enable AWS SDK tracing for debugging, and monitor failed origin lookups to detect scanning attempts. Using an explicit origin list stored in DynamoDB gives you an auditable, runtime-managed allowlist that adapts without redeploying your Gorilla Mux service.

Related CWEs: dataExposure

CWE IDNameSeverity
CWE-200Exposure of Sensitive Information HIGH
CWE-209Error Information Disclosure MEDIUM
CWE-213Exposure of Sensitive Information Due to Incompatible Policies HIGH
CWE-215Insertion of Sensitive Information Into Debugging Code MEDIUM
CWE-312Cleartext Storage of Sensitive Information HIGH
CWE-359Exposure of Private Personal Information (PII) HIGH
CWE-522Insufficiently Protected Credentials CRITICAL
CWE-532Insertion of Sensitive Information into Log File MEDIUM
CWE-538Insertion of Sensitive Information into Externally-Accessible File HIGH
CWE-540Inclusion of Sensitive Information in Source Code HIGH

Frequently Asked Questions

Why is a CORS wildcard risky when serving responses that include DynamoDB data?
A wildcard allows any origin to receive responses. If those responses contain sensitive DynamoDB data and credentials are permitted, any website can read that data, bypassing same-origin protections and exposing items, keys, or schema details.
How does checking an allowlist in DynamoDB improve CORS safety compared to a static origin list?
Storing allowed origins in DynamoDB enables runtime updates without redeploying your Gorilla Mux service, supports delegation to an operations team, and provides an auditable source of truth that can be tied to IAM policies and change management processes.