Regex Dos in Actix with Bearer Tokens
Regex Dos in Actix with Bearer Tokens — 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. In Actix web applications, this risk is heightened when regex-based validation is applied to bearer tokens in authentication paths. Bearer tokens are typically long, opaque strings that may contain characters such as alphanumeric sequences, dots, underscores, and hyphens. If a developer uses an overly permissive or recursive regex to validate these tokens, crafted input can force the regex engine into exponential backtracking, leading to high CPU usage and degraded service for legitimate requests.
Consider an endpoint that expects a bearer token in the Authorization header and uses a Rust regex to perform format checks. A vulnerable pattern might attempt to validate token structure with nested quantifiers or ambiguous character classes, for example: ^(?:[a-zA-Z0-9_\-\.]+)*$. When an attacker sends a carefully constructed token like a(a?)+ (or a long sequence that triggers overlapping quantifiers), the regex engine can enter a pathological matching loop. Because Actix routes often apply such regex checks synchronously within request handlers, this can block worker threads and increase latency for other users.
The combination of bearer token validation and regex becomes particularly risky when the regex is applied to untrusted input without length or complexity constraints. Bearer tokens can be hundreds of characters long, and if the regex is not linear-time, processing them may take disproportionately long. This issue is not unique to Actix, but the framework’s typical usage patterns—such as middleware or extractor-level validation—mean that problematic regex can affect many requests per second. Real-world patterns seen in the wild include repeated optional groups and ambiguous alternations that interact poorly with certain token formats, leading to delays that resemble a denial-of-service condition.
In practice, an attacker does not need to understand the internals of Actix to exploit this; they only need to send a high-volume request with a malicious token. Because the scan methodology of tools like middleBrick includes checks for unsafe consumption patterns and input validation, such regex issues can be surfaced during automated testing. The scanner evaluates the API surface without credentials and can identify endpoints where long, unstructured input is processed by regex-heavy logic, flagging the risk even in a black-box scenario.
It is important to note that this risk exists independently of authentication correctness: even if the token format is accepted, the method of validation can be unsafe. Security-focused scanning approaches that examine API definitions and runtime behavior—such as those provided by middleBrick—can highlight these concerns by correlating OpenAPI specs with observed input handling. This helps teams recognize that seemingly harmless validation rules can become leverage points for abuse when regex complexity is not carefully managed.
Bearer Tokens-Specific Remediation in Actix — concrete code fixes
To remediate Regex DoS risks when validating bearer tokens in Actix, prefer simple, linear-time checks over complex regular expressions. For many token formats, basic structural validation can be achieved without backtracking-prone patterns. When regex is necessary, ensure it avoids nested quantifiers and ambiguous repetition, and enforce strict length limits on the input.
Example of a vulnerable route
use actix_web::{web, HttpResponse, Responder};
use regex::Regex;
fn validate_token_regex(token: &str) -> bool {
// Vulnerable: nested quantifiers can cause catastrophic backtracking
let re = Regex::new(rquot;^(?:[a-zA-Z0-9_\-\.]+)*$quot;).unwrap();
re.is_match(token)
}
async fn auth_route(headers: web::Header<actix_web::http::header::Authorization<actix_web::http::header::Bearer>>) -> impl Responder {
if let Some(token) = headers.into_inner().map(|h| h.token()) {
if validate_token_regex(token) {
HttpResponse::Ok().body("Authorized")
} else {
HttpResponse::Unauthorized().body("Invalid token")
}
} else {
HttpResponse::Unauthorized().finish()
}
}
Remediation: use a simple length and character check instead of regex
use actix_web::{web, HttpResponse, Responder};
fn validate_token_simple(token: &str) -> bool {
// Safe: linear-time checks, no backtracking
if token.len() < 10 || token.len() > 4096 {
return false;
}
token.chars().all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_' || c == '.' || c == '~')
}
async fn auth_route_safe(headers: web::Header<actix_web::http::header::Authorization<actix_web::http::header::Bearer>>) -> impl Responder {
if let Some(token) = headers.into_inner().map(|h| h.token()) {
if validate_token_simple(token) {
HttpResponse::Ok().body("Authorized")
} else {
HttpResponse::Unauthorized().body("Invalid token")
}
} else {
HttpResponse::Unauthorized().finish()
}
}
When regex is unavoidable: use the regex crate’s set_size_limit and avoid ambiguous patterns
use actix_web::{web, HttpResponse, Responder};
use regex::RegexBuilder;
fn validate_token_with_limits(token: &str) -> bool {
// Limit backtracking by bounding group repetition and input length
let re = RegexBuilder::new(rquot;^[a-zA-Z0-9._~-]{1,512}(?:\.[a-zA-Z0-9._~-]{1,512})?$")
.size_limit(10_000_000) // cap internal automaton size
.build()
.unwrap_or_else(|_| Regex::new(rquot;^.+$").unwrap()); // fallback safe pattern
re.is_match(token)
}
async fn auth_route_limited(headers: web::Header<actix_web::http::header::Authorization<actix_web::http::header::Bearer>>) -> impl Responder {
if let Some(token) = headers.into_inner().map(|h| h.token()) {
if validate_token_with_limits(token) {
HttpResponse::Ok().body("Authorized")
} else {
HttpResponse::Unauthorized().body("Invalid token")
}
} else {
HttpResponse::Unauthorized().finish()
}
}
These examples demonstrate concrete fixes that eliminate or reduce regex-related risk. The preferred approach is to avoid regex entirely for bearer token validation, using straightforward character and length checks. If regex is required, constrain size limits and avoid patterns that enable exponential backtracking. By applying these practices, teams can mitigate DoS risks while still validating bearer tokens effectively within Actix routes.
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 |