Regex Dos in Fiber with Dynamodb
Regex Dos in Fiber with Dynamodb — how this specific combination creates or exposes the vulnerability
A Regular Expression Denial of Service (Regex DoS) occurs when an attacker provides input that causes a regular expression to exhibit catastrophic backtracking, consuming excessive CPU time and degrading service. In a Fiber application that interacts with DynamoDB, this risk arises when user-controlled data (e.g., query parameters, path variables, or request bodies) is used to construct regex patterns for validation before issuing DynamoDB operations.
Consider a scenario where an API endpoint accepts a filter pattern for a DynamoDB query parameter and builds a regex dynamically without limiting complexity:
package main
import (
"github.com/gofiber/fiber/v2"
"regexp"
)
func main() {
app := fiber.New()
app.Get("/search", func(c *fiber.Ctx) error {
pattern := c.Query("q", "")
// Unsafe: user input directly embedded in regex
re := regexp.MustCompile(pattern)
if !re.MatchString(c.Query("input", "")) {
return c.Status(fiber.StatusBadRequest).SendString("invalid input")
}
// Proceed to call DynamoDB with the input
return c.SendString("ok")
})
app.Listen(":3000")
}If an attacker sends a crafted pattern such as ((a+)+)$ paired with a long input like aaaaaaaaaaaaaaaaaaaa!, the regex engine can enter exponential backtracking, causing high CPU and request delays. This becomes critical when the endpoint also performs DynamoDB operations, as the service may appear unresponsive under load. The vulnerability is not in DynamoDB itself but in how regex validation is applied to inputs that eventually inform DynamoDB query parameters, such as partition key filters or conditional expressions.
In a black-box scan by middleBrick, unauthenticated endpoints that accept user-controlled regex-like inputs and subsequently invoke DynamoDB actions are flagged under Input Validation and Unsafe Consumption checks. The scanner does not inspect internal logic but detects patterns where overly permissive regex usage intersects with downstream database calls, indicating a potential vector for resource exhaustion.
Additionally, if regex-derived values are used to construct DynamoDB expression attribute values without proper sanitization, it may contribute to injection-related findings under Injection or Property Authorization checks, though Regex DoS is primarily a CPU exhaustion concern rather than a direct injection issue.
Dynamodb-Specific Remediation in Fiber — concrete code fixes
To mitigate Regex DoS in a Fiber service that interacts with DynamoDB, avoid constructing regex patterns directly from user input. Instead, use static patterns or safely bounded alternatives, and validate input structure before any DynamoDB operation.
1. Use a static regex with pre-compilation
Define regex patterns at initialization time rather than per request. If dynamic patterns are necessary, use a restricted syntax and validate complexity:
package main
import (
"github.com/golang/regex/syntax" // for safe parsing
"github.com/gofiber/fiber/v2"
"regexp"
)
var safePattern = regexp.MustCompile(`^[a-zA-Z0-9_-]{1,50}$`)
func compileRestricted(pattern string) (*regexp.Regexp, error) {
// Reject patterns with nested quantifiers or excessive backtracking risk
ast, err := syntax.Parse(pattern, syntax.Perl)
if err != nil {
return nil, err
}
// Example guard: disallow patterns with ambiguous repetition
if ast.Op == syntax.OpConcat || ast.Op == syntax.OpAlternate {
// Further walk AST if needed; simplified check
}
return regexp.Compile(pattern)
}
func main() {
app := fiber.New()
app.Get("/search-safe", func(c *fiber.Ctx) error {
input := c.Query("input", "")
if !safePattern.MatchString(input) {
return c.Status(fiber.StatusBadRequest).SendString("invalid input format")
}
// Safe to use input in DynamoDB conditionals or key expressions
// dynamodb.GetItem with input as key
return c.SendString("ok")
})
app.Listen(":3000")
}2. Validate input against a whitelist or schema
For DynamoDB queries, prefer parameterized expressions and avoid regex for validation when possible. Use structured validation libraries and ensure input length and content are bounded:
package main
import (
"github.com/gofiber/fiber/v2"
"github.com/aws/aws-sdk-go/service/dynamodb"
)
func isValidPartitionKey(value string) bool {
if len(value) == 0 || len(value) > 200 {
return false
}
// Allow only alphanumeric, underscore, hyphen
for _, r := range value {
if !(('a' <= r && r <= 'z') || ('A' <= r && r <= 'Z') || ('0' <= r && r <= '9') || r == '_' || r == '-') {
return false
}
}
return true
}
func main() {
app := fiber.New()
app.Get("/item", func(c *fiber.Ctx) error {
pk := c.Query("pk")
if !isValidPartitionKey(pk) {
return c.Status(fiber.StatusBadRequest).SendString("invalid partition key")
}
// Proceed with a static DynamoDB query using pk as key
// Example: dynamodb.GetItem with Key {"PK": {S: aws.String(pk)}}
return c.SendString("ok")
})
app.Listen(":3000")
}These approaches reduce the risk of Regex DoS by removing unbounded regex construction from the request path and ensuring DynamoDB interactions use controlled, predictable inputs. middleBrick’s scans can verify that endpoints no longer reflect user input into regex patterns and that validation logic is present and conservative.
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 |