Format String on Cloudflare
How Format String Manifests in Cloudflare — specific attack patterns, Cloudflare-specific code paths where this appears
Format string vulnerabilities arise when untrusted input is used directly in functions that interpret format specifiers, such as printf, sprintf, or snprintf. In Cloudflare Workers, this typically surfaces in JavaScript/TypeScript code that builds log messages or error strings using user-controlled data without proper sanitization. For example, a Worker that uses util.format (Node.js-style formatting) or a custom logging helper can be tricked into interpreting attacker-supplied format tokens like %s, %d, or %n. The %n specifier is especially dangerous because it writes the number of characters written so far into a corresponding argument, enabling memory manipulation in native bindings or when interfacing with WASM modules. In Cloudflare’s edge runtime, such issues can appear in custom logging pipelines, diagnostic endpoints, or when generating error responses that embed request parameters directly into format strings.
Attack patterns specific to Cloudflare include crafting HTTP requests where query parameters or headers are interpolated into format strings. An example is a Worker that constructs a response message using const message = util.format('Hello %s', userInput). If userInput contains %s or %d, additional arguments may be consumed unpredictably, leading to information disclosure or instability. In more severe cases, if the Worker interacts with native addons or uses new Function with concatenated strings, format specifiers can alter execution flow. While Cloudflare’s sandboxed Workers isolate memory, format string bugs can still lead to denial of service or facilitate further exploit chains when combined with other weaknesses such as SSRF or insecure deserialization.
Cloudflare-Specific Detection — how to identify this issue, including scanning with middleBrick
Detecting format string issues in Cloudflare Workers requires analyzing how dynamic data is incorporated into string construction. Static analysis should flag uses of util.format, console.log with concatenated variables, or templating functions that accept format-like patterns. Runtime detection involves observing unexpected behavior when inputs contain format tokens; for example, a Worker might return malformed responses or throw exceptions when %n is present. middleBrick’s unauthenticated scans include checks for unsafe string construction patterns across the API surface, including header manipulation, query parsing, and response generation. By correlating OpenAPI specifications with runtime probes, middleBrick can identify endpoints where user-controlled fields are passed into formatting routines without sanitization.
Using the middleBrick CLI, you can scan a Cloudflare Worker endpoint with middlebrick scan https://your-worker.example.com/api to receive a security risk score and findings related to format string risks among other checks. The report will highlight vulnerable code paths, provide severity ratings, and map findings to frameworks like OWASP API Top 10. The LLM/AI Security module of middleBrick further tests for prompt injection and system prompt leakage, which is distinct but complementary to format string detection. For continuous protection, the Pro plan enables scheduled scans and alerts when new format string patterns appear in updated endpoints, helping teams catch regressions before deployment.
Cloudflare-Specific Remediation — code fixes using Cloudflare's native features/libraries
Remediation focuses on avoiding format-like interpolation of untrusted data. Instead of using util.format, construct strings using explicit concatenation or template literals with proper escaping. For logging, prefer structured logging with JSON output, which avoids interpretation of format tokens. When generating error messages, validate and sanitize all inputs, and use functions that do not interpret format specifiers.
Example of vulnerable code in a Cloudflare Worker:
addEventListener('fetch', event => {
event.respondWith(handleRequest(event))
})
async function handleRequest(event) {
const userInput = event.request.headers.get('X-Name')
const message = util.format('Welcome, %s!', userInput)
return new Response(message)
}
Revised version using safe string construction:
addEventListener('fetch', event => {
event.respondWith(handleRequest(event))
})
async function handleRequest(event) {
const userInput = event.request.headers.get('X-Name')
const safeName = userInput ? userInput.replace(/[^a-zA-Z0-9_\-\s]/g, '') : 'Guest'
const message = `Welcome, ${safeName}!`
return new Response(message)
}
For structured logging, use JSON output instead of format strings:
addEventListener('fetch', event => {
event.respondWith(handleRequest(event))
})
async function handleRequest(event) {
const userInput = event.request.headers.get('X-Name')
const logEntry = {
event: 'request_received',
name: userInput || 'unknown',
timestamp: new Date().toISOString()
}
console.log(JSON.stringify(logEntry))
return new Response('OK')
}
These practices align with secure coding guidelines and reduce the risk of format string exploits in Cloudflare Workers.