Xss Cross Site Scripting in Echo Go with Dynamodb
Xss Cross Site Scripting in Echo Go with Dynamodb — how this specific combination creates or exposes the vulnerability
Cross-site scripting (XSS) in an Echo Go service that uses DynamoDB typically occurs when data stored in DynamoDB is later rendered in an HTTP response without proper escaping. If user-controlled input is written to DynamoDB and later included in HTML, JSON responses consumed by a browser, or URL context without validation or escaping, reflected or stored XSS can occur. The DynamoDB layer does not introduce XSS by itself, but the way data is retrieved and presented in Go handlers determines whether XSS is possible.
Consider an Echo Go endpoint that stores a user profile field into DynamoDB and then retrieves it to embed in an HTML page. If the input contains a script payload (e.g., <script>alert(1)</script>) and the application places this value directly into the HTML response, the browser will execute it. DynamoDB may store the raw payload; the vulnerability is in the Go code that reads the item and constructs the response. Similarly, if an item attribute is used in a JSON response that is later accessed by a frontend framework, improper escaping can enable script injection via unsafe serialization. SSRF and server-side risks are separate, but the data path from DynamoDB to HTTP output is where XSS relevance arises.
In the context of a scan, middleBrick tests the unauthenticated attack surface of an Echo Go API that uses DynamoDB by submitting inputs designed to detect missing output encoding. For example, it may inject test payloads into query parameters that eventually map to DynamoDB queries and then checks whether those payloads appear unescaped in responses. Because DynamoDB does not perform HTML or JavaScript escaping, the responsibility falls to the Go application to ensure that any data rendered in a browser context is properly encoded based on the output context (HTML body, attribute, JavaScript, or URL).
Dynamodb-Specific Remediation in Echo Go — concrete code fixes
To prevent XSS when using DynamoDB with Echo Go, ensure that data retrieved from DynamoDB is never directly concatenated into HTML, JavaScript, or CSS. Apply context-aware escaping before rendering. Below are concrete examples that demonstrate secure handling patterns.
1. Safe HTML rendering using html/template
Use Go’s html/template package to automatically escape dynamic values. Do not use the standard text/template for HTML output. Define a handler that retrieves an item from DynamoDB and passes it to a template that escapes content.
import (
"github.com/labstack/echo/v4"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue"
"html/template"
"net/http"
)
type Profile struct {
UserID string `dynamodbav:"user_id"`
Bio string `dynamodbav:"bio"`
}
func getProfileHandler(c echo.Context) error {
client := dynamodb.NewFromConfig(cfg)
out, err := client.GetItem(c.Request().Context(), &dynamodb.GetItemInput{
TableName: aws.String("Profiles"),
Key: map[string]dynamodb.AttributeValue{
"user_id": &dynamodb.AttributeValueMemberS{Value: c.Param("user_id")},
},
})
if err != nil {
return c.String(http.StatusInternalServerError, err.Error())
}
var profile Profile
err = attributevalue.UnmarshalMap(out.Item, &profile)
if err != nil {
return c.String(http.StatusInternalServerError, err.Error())
}
tmpl, err := template.New("profile").Parse(`
<div>
<h1>{{.UserID}}</h1>
<p>{{.Bio}}</p>
</div>
`)
if err != nil {
return c.String(http.StatusInternalServerError, err.Error())
}
return tmpl.Execute(c.Response().Writer, profile)
}
The template engine automatically escapes the Bio field, neutralizing any embedded script tags.
2. JSON responses with proper Content-Type
When serving JSON, set the correct Content-Type and avoid embedding untrusted data in JavaScript URLs or inline scripts. If a frontend consumes the JSON, ensure the frontend context is also safe.
func getProfileJSONHandler(c echo.Context) error {
client := dynamodb.NewFromConfig(cfg)
out, err := client.GetItem(c.Request().Context(), &dynamodb.GetItemInput{
TableName: aws.String("Profiles"),
Key: map[string]dynamodb.AttributeValue{
"user_id": &dynamodb.AttributeValueMemberS{Value: c.Param("user_id")},
},
})
if err != nil {
return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
}
var profile Profile
err = attributevalue.UnmarshalMap(out.Item, &profile)
if err != nil {
return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
}
// Ensure no raw HTML is placed in fields that a frontend might eval.
return c.JSON(http.StatusOK, profile)
}
3. Input validation and sanitization before writing to DynamoDB
While escaping at output is essential, consider validating and sanitizing user input at entry to reduce risk. For example, reject or encode potentially dangerous characters if they are not expected.
import "regexp"
var scriptTag = regexp.MustCompile(`(?i)<script[>]`)
func sanitizeInput(raw string) string {
return scriptTag.ReplaceAllString(raw, "<script>")
}
func putProfileHandler(c echo.Context) error {
userID := c.Param("user_id")
rawBio := c.FormValue("bio")
safeBio := sanitizeInput(rawBio)
client := dynamodb.NewFromConfig(cfg)
_, err := client.PutItem(c.Request().Context(), &dynamodb.PutItemInput{
TableName: aws.String("Profiles"),
Item: map[string]dynamodb.AttributeValue{
"user_id": &dynamodb.AttributeValueMemberS{Value: userID},
"bio": &dynamodb.AttributeValueMemberS{Value: safeBio},
},
})
if err != nil {
return c.String(http.StatusInternalServerError, err.Error())
}
return c.NoContent(http.StatusOK)
}
These patterns align with remediations for CWE-79 and help ensure that data stored in DynamoDB does not become a vector for XSS when consumed by Echo Go handlers.
Related CWEs: inputValidation
| CWE ID | Name | Severity |
|---|---|---|
| CWE-20 | Improper Input Validation | HIGH |
| CWE-22 | Path Traversal | HIGH |
| CWE-74 | Injection | CRITICAL |
| CWE-77 | Command Injection | CRITICAL |
| CWE-78 | OS Command Injection | CRITICAL |
| CWE-79 | Cross-site Scripting (XSS) | HIGH |
| CWE-89 | SQL Injection | CRITICAL |
| CWE-90 | LDAP Injection | HIGH |
| CWE-91 | XML Injection | HIGH |
| CWE-94 | Code Injection | CRITICAL |