HIGH session fixationecho godynamodb

Session Fixation in Echo Go with Dynamodb

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

Session fixation occurs when an application accepts a session identifier provided by the client without validation. In Echo Go applications that use DynamoDB as the session store, this typically arises when session IDs are generated client-side (e.g., set via a cookie by JavaScript) or accepted via query parameters or headers without server-side assignment. If the server reads a session ID from the request and uses it as the key in DynamoDB without ensuring it was freshly generated server-side, an attacker can fixate that ID on a victim’s browser and later hijack the authenticated session.

DynamoDB specifics matter here: session entries are stored as items with a partition key (often session_id) and attributes such as user_id, expires_at, and issued_at. If the application trusts incoming identifiers, an attacker can craft a URL like https://api.example.com/auth/login?session_id=attacker123 and, once the victim authenticates, the attacker can read/write that DynamoDB item (assuming additional access control gaps). Even without direct DynamoDB access, fixation enables session hijacking because the server uses the attacker-chosen ID, making it easier to monitor login success via polling or webhooks that reference that ID.

Echo’s middleware flow plays a role: if Next() is called before session validation or cookie assignment, the request may proceed with an untrusted ID. A common anti-pattern is to call echo.Wrap(nextHandler) with a session middleware that reads req.Cookies() and, if missing, does not immediately issue a new server-generated ID but instead proceeds and later writes to DynamoDB using a client-provided value. This mismatch between Echo’s request lifecycle and DynamoDB item keys creates a window where the session identifier is not bound to a fresh server-side secret.

To detect this pattern via middleBrick, a scan against an endpoint like POST /auth/login that accepts or sets session cookies will flag missing server-side session regeneration and highlight the risk of fixation. The scan does not fix the issue but provides remediation guidance, such as always generating a cryptographically random session ID on the server before any authentication and ensuring DynamoDB writes use that server-generated ID only.

Dynamodb-Specific Remediation in Echo Go — concrete code fixes

Remediation centers on ensuring session IDs are generated server-side and never derived from client-controlled data. Below is a minimal, idiomatic Echo Go example using the AWS SDK for Go v2 to interact with DynamoDB, with secure session creation and validation.

import (
	"context"
	"crypto/rand"
	"encoding/hex"
	"net/http"
	"time"

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

const (
	tableName = "AppSessions"
	sessionTTL = 30 * 24 * time.Hour
)

func generateSessionID() (string, error) {
	b := make([]byte, 16)
	if _, err := rand.Read(b); err != nil {
		return "", err
	}
	return hex.EncodeToString(b), nil
}

func newSessionHandler(db *dynamodb.Client) echo.HandlerFunc {
	return func(c echo.Context) error {
		sessionID, err := generateSessionID()
		if err != nil {
			return echo.NewHTTPError(http.StatusInternalServerError, "failed to generate session")
		}

		ctx := c.Request().Context()
		expiresAt := time.Now().Add(sessionTTL).Unix()

		item := map[string]types.AttributeValue{
			"session_id": &types.AttributeValueMemberS{Value: sessionID},
			"user_id":    &types.AttributeValueMemberS{Value: "PLACEHOLDER_USER_ID"},
			"expires_at": &types.AttributeValueMemberN{Value: aws.String(string(expiresAt))},
			"issued_at":  &types.AttributeValueMemberN{Value: aws.String(string(time.Now().Unix()))},
		}

		_, err = db.PutItem(ctx, &dynamodb.PutItemInput{
			TableName: aws.String(tableName),
			Item:      item,
		})
		if err != nil {
			return echo.NewHTTPError(http.StatusInternalServerError, "failed to create session")
		}

		// Set secure, httpOnly cookie with server-generated session ID
		cookie := new(http.Cookie)
		cookie.Name = "session_id"
		cookie.Value = sessionID
		cookie.HttpOnly = true
		cookie.Secure = true
		cookie.SameSite = http.SameSiteStrictMode
		cookie.Expires = time.Now().Add(sessionTTL)
		cookie.Path = "/"
		http.SetCookie(c.Response(), cookie)

		return c.JSON(http.StatusOK, map[string]string{"session_id": sessionID})
	}
}

func validateSession(db *dynamodb.Client) echo.HandlerFunc {
	return func(c echo.Context) error {
		cookie, err := c.Cookie("session_id")
		if err != nil {
			return echo.NewHTTPError(http.StatusUnauthorized, "missing session")
		}

		ctx := c.Request().Context()
		out, err := db.GetItem(ctx, &dynamodb.GetItemInput{
			TableName: aws.String(tableName),
			Key: map[string]types.AttributeValue{
				"session_id": &types.AttributeValueMemberS{Value: cookie.Value},
			},
		})
		if err != nil || out.Item == nil {
			return echo.NewHTTPError(http.StatusUnauthorized, "invalid session")
		}

		// Optional: check expiry and refresh logic here
		return c.Next()
	}
}

Key points: generateSessionID uses crypto/rand to ensure unpredictability; the ID is set in an httpOnly, Secure cookie; and DynamoDB writes/reads use the server-generated ID only. Avoid accepting session IDs from query parameters, headers, or body when authentication is involved.

In the dashboard, you can track scans over time to verify that session fixation findings no longer appear after remediation. The CLI can be used in scripts: middlebrick scan https://api.example.com to validate endpoint behavior. For teams with many services, the Pro plan’s continuous monitoring can alert when a regression in session handling is detected across scanned APIs.

Frequently Asked Questions

Can DynamoDB item keys be derived from user input in a secure way?
No. Session identifiers used as DynamoDB partition keys must be server-generated random values. Never use user-controlled values such as usernames, emails, or client-supplied tokens directly as keys, even if they are unique, because this enables fixation and other injection-based attacks.
Does middleBrick fix session fixation issues automatically?
No. middleBrick detects and reports findings with remediation guidance, but it does not fix, patch, or block issues. Developers must implement server-side session ID generation and ensure DynamoDB writes use only those server-generated IDs.