HIGH denial of serviceecho godynamodb

Denial Of Service in Echo Go with Dynamodb

Denial Of Service in Echo Go with Dynamodb — how this specific combination creates or exposes the vulnerability

A Denial of Service (DoS) scenario in an Echo Go service that uses DynamoDB typically arises from unbounded or inefficient access patterns combined with resource-intensive request handling. Echo is a minimalist HTTP framework, so developers are responsible for ensuring that handlers do not block or consume excessive resources. When DynamoDB is involved, common DoS risks include:

  • Thundering herd on cold starts: If many concurrent requests trigger initialization logic (for example, establishing SDK clients or loading configuration), the service can become unresponsive.
  • Uncontrolled query fan-out: Making multiple sequential or uncontrolled parallel requests to DynamoDB within a single handler can saturate goroutines and memory, especially if queries lack pagination or filtering.
  • Large payload handling: Reading or writing large items or batches without size limits can cause high latency and memory pressure, leading to slow responses or timeouts.
  • Error handling loops: Retrying failed DynamoDB calls aggressively without backoff or circuit breaking can amplify load on both the service and the database, worsening availability.

In an unauthenticated scan, middleBrick tests for Rate Limiting and other controls that can mitigate such DoS behaviors. Without proper rate limiting, input validation, and efficient query design, an Echo Go + DynamoDB endpoint can be overwhelmed, resulting in timeouts or service unavailability for legitimate users.

Dynamodb-Specific Remediation in Echo Go — concrete code fixes

Apply the following patterns in your Echo Go handlers to reduce DoS risk when working with DynamoDB:

  • Use context timeouts and reasonable DynamoDB client settings to prevent hanging requests.
  • Limit payload sizes and validate input before issuing requests.
  • Use pagination and filter expressions to avoid retrieving excessive data.
  • Implement backoff and limit concurrency to reduce pressure on DynamoDB and the service.

Example: Safe DynamoDB GetItem with timeout and input validation in Echo Go

// handler.go
package handlers

import (
	"context"
	"net/http"
	"time"

	"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"
	"github.com/labstack/echo/v4"
)

// Define a reasonable timeout per request
dbTimeout := 2 * time.Second

// Configure the SDK with a custom client that respects timeouts.
// In production, share a single client across requests.
func newDynamoClient() *dynamodb.Client {
	cfg, err := config.LoadDefaultConfig(context.Background(),
		config.WithRegion("us-east-1"),
	)
	if err != nil {
		// Handle error appropriately (log, panic in init, etc.)
	}
	// Use a custom HTTP client with timeouts in your real code.
	// Here we focus on context timeout usage per call.
	return dynamodb.NewFromConfig(cfg)
}

// GetItemByPK safely retrieves an item with context timeout and validation.
func GetItemByPK(c echo.Context) error {
	table := c.Param("table")
	pk := c.QueryParam("pk")
	if table == "" || pk == "" {
		return echo.NewHTTPError(http.StatusBadRequest, "table and pk are required")
	}
	// Basic length/type validation to avoid excessively large inputs
	if len(table) > 255 || len(pk) > 255 {
		return echo.NewHTTPError(http.StatusBadRequest, "input too long")
	}

	client := newDynamoClient()
	ctx, cancel := context.WithTimeout(c.Request().Context(), dbTimeout)
	defer cancel()

	input := &dynamodb.GetItemInput{
		TableName: aws.String(table),
		Key: map[string]types.AttributeValue{
			"pk": &types.AttributeValueMemberS{Value: pk},
		},
	}

	result, err := client.GetItem(ctx, input)
	if err != nil {
		// Log the error; avoid exposing internals to the client
		return echo.NewHTTPError(http.StatusInternalServerError, "unable to retrieve item")
	}
	if result.Item == nil {
		return echo.NewHTTPError(http.StatusNotFound, "item not found")
	}
	return c.JSON(result.Item)
}

// Example: Paginated scan with limit to avoid large payloads
func ScanWithLimit(c echo.Context) error {
	table := c.Param("table")
	if table == "" {
		return echo.NewHTTPError(http.StatusBadRequest, "table is required")
	}
	limit := 100
	if l := c.QueryParam("limit"); l != "" {
		var err error
		limit, err = parseIntLimit(l, 1, 1000)
		if err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, "invalid limit")
		}
	}

	client := newDynamoClient()
	ctx, cancel := context.WithTimeout(c.Request().Context(), 5*time.Second)
	defer cancel()

	var items []map[string]types.AttributeValue
	input := &dynamodb.ScanInput{
		TableName:                 aws.String(table),
		Limit:                     int32(limit),
		ReturnConsumedCapacity:    aws.String("NONE"),
		Segment:                   int32(0),
		TotalSegments:             int32(1),
	}

	for {
		output, err := client.Scan(ctx, input)
		if err != nil {
			return echo.NewHTTPError(http.StatusInternalServerError, "scan failed")
		}
		items = append(items, output.Items...)
		if output.LastEvaluatedKey == nil {
			break
		}
		input.ExclusiveStartKey = output.LastEvaluatedKey
		if len(items) >= limit {
			break
		}
	}
	return c.JSON(map[string]interface{}{"items": items})
}

func parseIntLimit(s string, min, max int) (int, error) {
	var v int
	_, err := fmt.Sscanf(s, "%d", &v)
	if err != nil || v < min || v > max {
		return 0, err
	}
	return v, nil
}

Additional practices:

  • Set per-request timeouts and enforce overall HTTP timeouts in Echo to bound handler duration.
  • Apply rate limiting at the HTTP layer (e.g., Echo middleware) to protect against traffic spikes.
  • Use exponential backoff with jitter for retries, and employ circuit breakers to avoid amplifying failures.
  • Monitor returned consumed capacity and error rates to detect abnormal patterns that may precede DoS conditions.

Related CWEs: resourceConsumption

CWE IDNameSeverity
CWE-400Uncontrolled Resource Consumption HIGH
CWE-770Allocation of Resources Without Limits MEDIUM
CWE-799Improper Control of Interaction Frequency MEDIUM
CWE-835Infinite Loop HIGH
CWE-1050Excessive Platform Resource Consumption MEDIUM

Frequently Asked Questions

Can middleBrick detect DoS risks in an Echo Go + DynamoDB setup?
Yes. middleBrick runs unauthenticated scans that include Rate Limiting and related checks. It reports findings such as missing rate limits, long timeouts, and inefficient query patterns that can contribute to DoS, along with remediation guidance.
Does middleBrick provide automatic fixes for DoS issues?
No. middleBrick detects and reports issues with detailed remediation guidance. It does not fix, patch, block, or remediate. Developers should apply the suggested patterns, such as timeouts, input validation, and backoff, in their Echo Go service.