HIGH ssrfecho godynamodb

Ssrf in Echo Go with Dynamodb

Ssrf in Echo Go with Dynamodb — how this specific combination creates or exposes the vulnerability

Server-Side Request Forgery (SSRF) occurs when an attacker forces a server to make unintended requests to internal or external resources. In an Echo Go service that interacts with DynamoDB, SSRF can arise when user-supplied input is used to construct AWS SDK requests, particularly metadata service calls or endpoint overrides. For example, if an application accepts a URL or host parameter and uses it to configure an HTTP client or to query DynamoDB via the AWS SDK for Go, an attacker may supply a malicious address such as http://169.254.169.254/latest/meta-data/iam/security-credentials/ to probe internal AWS instance metadata. Because the AWS SDK for Go allows customization of the underlying HTTP client, an Echo Go route that passes a user-controlled URL into aws.NewSession or a custom http.RoundTripper can inadvertently route SDK requests through that endpoint.

In Echo Go with DynamoDB, the vulnerability surface often appears when developers use environment variables or request parameters to influence service endpoints, region resolution, or credential providers. The AWS SDK for Go v2 retrieves credentials and configuration from the environment and shared config files, but if the code overrides the endpoint resolver using user input, an attacker can redirect SDK traffic. A typical vulnerable pattern is a handler that accepts a dynamoEndpoint query parameter and applies it via funcopt.WithEndpointResolver. This enables SSRF by tricking the service into making AWS SDK calls to attacker-controlled hosts, potentially reaching the EC2 instance metadata service or internal services that accept untrusted input. Even when the application only intends to interact with DynamoDB, SSRF can expose internal AWS metadata, reveal service-linked roles, or facilitate pivoting to other internal resources.

Because middleBrick tests unauthenticated attack surfaces and includes SSRF in its 12 security checks, it can detect whether an Echo Go endpoint with DynamoDB integration exposes metadata or internal endpoints through manipulated inputs. Attack patterns such as IMDSv1 token requests or SSRF-to-SSRF chains are observable when the scanner provides crafted inputs that attempt to reach reserved AWS metadata addresses. The scanner validates whether the service prevents redirection to sensitive internal hosts and whether responses include unintended data exposure. Developers should ensure that endpoint resolvers, HTTP clients, and credential sources are fixed and not influenced by external input to mitigate SSRR in this specific stack.

Dynamodb-Specific Remediation in Echo Go — concrete code fixes

To remediate SSRF in Echo Go with DynamoDB, remove any ability for user input to influence AWS SDK configuration, especially endpoint resolution and credential sources. Use the AWS SDK for Go v2 with a fixed endpoint and default credential chain, and avoid passing external strings into configuration functions. Below are concrete, working code examples that demonstrate a secure setup.

Vulnerable pattern (do not use):

// DO NOT USE: user input directly influences the DynamoDB endpoint
type inputParams struct {
    DynamoEndpoint string `query:"endpoint"`
}

func handler(c echo.Context) error {
    var p inputParams
    if err := c.Bind(&p); err != nil {
        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
    }
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
    }
    // Dangerous: endpoint overridden by user input
    resolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
        return aws.Endpoint{URL: p.DynamoEndpoint, SigningRegion: region}, nil
    })
    client := dynamodb.NewFromConfig(cfg, func(o *Options) {
        o.EndpointResolver = resolver
    })
    // Use client...
    return c.JSON(http.StatusOK, map[string]string{"msg": "ok"})
}

Secure pattern: fixed endpoint and default configuration

import (
    "context"
    "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/labstack/echo/v4"
)

type secureParams struct {
    // No endpoint parameter exposed to the user
    Key   string `query:"key"`
    Table string `query:"table"`
}

func secureHandler(c echo.Context) error {
    var p secureParams
    if err := c.Bind(&p); err != nil {
        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
    }

    // Load default configuration without overriding endpoint from user input
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        return echo.NewHTTPError(http.StatusInternalServerError, "unable to load AWS config")
    }

    // Create DynamoDB client with fixed, trusted configuration
    client := dynamodb.NewFromConfig(cfg)

    // Example: GetItem using fixed table name from query (validate against allowlist)
    // Validate table name to prevent SSRF via DynamoDB API misuse
    allowedTables := map[string]bool{"users": true, "orders": true}
    if !allowedTables[p.Table] {
        return echo.NewHTTPError(http.StatusBadRequest, "invalid table")
    }

    // Build GetItemInput safely; do not allow raw URL-based endpoint manipulation
    input := &dynamodb.GetItemInput{
        TableName: aws.String(p.Table),
        Key: map[string]types.AttributeValue{
            "id": &types.AttributeValueMemberS{Value: p.Key},
        },
    }

    out, err := client.GetItem(c.Request().Context(), input)
    if err != nil {
        return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
    }
    return c.JSON(http.StatusOK, out.Item)
}

Key remediation points:

  • Do not expose endpoint or region parameters derived from user input.
  • Use config.LoadDefaultConfig without custom endpoint resolvers unless absolutely necessary, and if required, validate endpoints against a strict allowlist of internal service targets.
  • Validate and restrict DynamoDB table names to a predefined allowlist to prevent misuse via parameter tampering.
  • Ensure the HTTP client used by the AWS SDK does not follow redirects to internal metadata services; this is typically handled by the runtime environment, but avoid configurations that encourage redirect following to sensitive addresses.

middleBrick can verify that these fixes prevent SSRF by testing endpoints with crafted inputs aimed at internal AWS metadata and observing whether unintended interactions occur.

Related CWEs: ssrf

CWE IDNameSeverity
CWE-918Server-Side Request Forgery (SSRF) CRITICAL
CWE-441Unintended Proxy or Intermediary (Confused Deputy) HIGH

Frequently Asked Questions

How does middleBrick detect SSRF in Echo Go services using DynamoDB?
middleBrick sends crafted inputs that attempt to redirect AWS SDK calls to internal metadata endpoints (e.g., 169.254.169.254) and checks whether the service follows these redirects or returns unintended data, indicating SSRF.
Can middleBrick map SSRF findings to compliance frameworks?
Yes, middleBrick maps findings to compliance frameworks such as OWASP API Top 10, PCI-DSS, SOC2, HIPAA, and GDPR, helping teams understand the regulatory relevance of SSRF and other API security issues.