HIGH xml external entitiesgindynamodb

Xml External Entities in Gin with Dynamodb

Xml External Entities in Gin with Dynamodb — how this specific combination creates or exposes the vulnerability

XML External Entity (XXE) injection occurs when an application processes XML input that references external entities, and the server-side parser is configured to resolve them. In a Gin-based Go service that interacts with DynamoDB, this typically manifests when XML payloads are accepted—for example, in admin import endpoints or legacy SOAP integrations—and forwarded to an AWS SDK call that uses the received data as a key or filter value.

Consider a Gin handler that reads an XML upload containing a TableName field and uses it to call GetItem against DynamoDB. If the XML parser resolves external entities, an attacker can provide an entity that expands to sensitive file paths, cloud metadata URLs (e.g., http://169.254.169.254/latest/meta-data/iam/security-credentials/), or even cause billion laughs decompression bombs. The DynamoDB request itself may not be directly exploitable for injection, but the XXE vector can disclose environment credentials or source code, which in turn enables more precise attacks against the DynamoDB table (such as crafting condition-expressions or scanning via injected metadata).

An example malicious XML payload might define an external entity SYSTEM pointing to /etc/passwd and reference it in a field that ends up as a request parameter. When Gin parses the XML with default settings, the entity is resolved, and the content is included in logs, error messages, or used to construct a DynamoDB API call. Because Gin does not enforce schema-level constraints on XML by default, developers must explicitly disable external entity processing to prevent this path. The combination of a general-purpose XML parser, user-controlled data, and AWS SDK calls creates a realistic and high-impact attack surface.

In practice, scanning a Gin endpoint with external XML input via middleBrick would surface this as a finding under Input Validation and Data Exposure checks, mapping to OWASP API Top 10 A03:2023 (Injection) and A05:2023 (Security Misconfiguration). The scanner does not fix the parser behavior, but it highlights the need to treat XML as untrusted and to validate and sanitize all inputs that influence AWS resource identifiers.

Dynamodb-Specific Remediation in Gin — concrete code fixes

To secure a Gin application that interacts with DynamoDB, disable external entity resolution at the XML parser level and treat all inputs as untrusted. Use strict allowlists for table names and key attributes, and avoid reflecting XML fields directly into AWS SDK calls.

Below is a safe Gin handler that reads JSON (preferred over XML for APIs), validates the table name against an allowlist, and performs a GetItem call using the AWS SDK for Go v2. No XML parsing occurs, and user input never reaches DynamoDB without validation.

package main

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

    "github.com/gin-gonic/gin"
    "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"
    "github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
)

var allowedTables = map[string]bool{
    "users_prod": true,
    "config":     true,
}

func getItemHandler(c *gin.Context) {
    var req struct {
        TableName string `json:"table_name"`
        Key       map[string]types.AttributeValue `json:"key"`
    }
    if err := c.BindJSON(&req); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": "invalid_json"})
        return
    }

    if !allowedTables[req.TableName] {
        c.JSON(http.StatusBadRequest, gin.H{"error": "table_not_allowed"})
        return
    }

    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "unable_load_aws_config"})
        return
    }

    client := dynamodb.NewFromConfig(cfg)
    out, err := client.GetItem(context.TODO(), &dynamodb.GetItemInput{
        TableName: aws.String(req.TableName),
        Key:       req.Key,
    })
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "dynamodb_error"})
        return
    }

    c.JSON(http.StatusOK, out.Item)
}

If XML support is strictly required (for example, to consume an external vendor format), use a parser that explicitly disables external entities. For the standard Go encoding/xml decoder, set Decoder.Entity to a custom resolver that rejects external references, and avoid Decoder.Strict relaxations. Never pass raw XML field values to DynamoDB SDK fields without allowlist checks.

Using middleBrick’s GitHub Action in CI/CD can help enforce that Gin endpoints do not accept risky XML configurations. The action scans unauthenticated attack surfaces and flags inputs that enable XXE, providing prioritized remediation guidance aligned with OWASP API Top 10 and compliance frameworks like SOC2 and GDPR.

Frequently Asked Questions

Why is XML parsing a risk in Gin applications that use DynamoDB?
If an XML parser resolves external entities, it can disclose server-side files or metadata, which may lead to credential leakage that aids further attacks against DynamoDB. Always disable external entity resolution and validate inputs before using them in AWS SDK calls.
Can middleBrick fix XXE issues in my Gin API?
middleBrick detects and reports XXE-related Input Validation and Data Exposure findings with remediation guidance. It does not modify code or block requests; developers must apply the suggested fixes, such as disabling external entities and tightening input allowlists.