A Low-Effort, High-Impact DoS Vulnerability in the Expr Language Engine
Vulnerability Summary
- CVE Identifier: CVE-2025-68156
- Vendor / Project: Expr Project
- Product: Expr Expression Language Library
- Disclosure Date: December 27, 2025
- Vulnerability Type: Uncontrolled Recursion (CWE-674)
- Severity Rating: HIGH
- CVSS v3.1 Base Score: 7.5 (High)
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
- Exploitability: High (low complexity, no authentication, no privileges)
- Exploit Availability: Publicly achievable proof-of-concept patterns
- Primary Impact: Stack exhaustion leading to full process crash (Denial of Service)
Affected Products and Platforms
Vulnerable Versions
- Expr expression language library versions 1.0.0 through 1.17.6
- All Go-based applications invoking vulnerable aggregation functions
- Applications using Expr for dynamic expression evaluation or rule processing
Fixed Version
- Expr version 1.17.7 and later
Platforms Impacted
- Go applications running on Linux, Windows, macOS
- Containerized and cloud-native deployments
- Microservices, APIs, rule engines, and data-processing services using Expr
Technical Overview (What’s Going Wrong)
This vulnerability exists in the way Expr handles nested arrays and aggregate functions during expression evaluation. Several commonly used functions rely on recursive logic to process arrays. However, prior to version 1.17.7, the library did not enforce recursion depth limits or detect excessive nesting.
The vulnerable functions are:
flattenminmaxmeanmedian
When Expr encounters deeply nested arrays, it recursively evaluates each level without any safety checks. An attacker can intentionally supply expressions with extreme nesting depth, forcing the evaluator to recurse repeatedly until the application runs out of stack space.
Once the stack limit is reached, the Go runtime terminates the process. The crash is abrupt and typically unrecoverable without a restart, resulting in immediate denial of service.
What makes this issue especially serious is how Expr is commonly used. Many applications expose expression evaluation to users for:
- Dynamic filtering
- Custom calculations
- Business rule definitions
- Query logic in APIs
This means attackers can often reach the vulnerable code path through normal application functionality, without authentication or elevated privileges.
How an Attack Unfolds
Attack Prerequisites
- Network access to an application endpoint that evaluates Expr expressions
- Ability to submit user-controlled expressions
- No authentication or special permissions required
Exploitation Flow
- The attacker identifies an API, UI field, or configuration endpoint that accepts Expr expressions.
- A malicious expression is crafted with deeply nested arrays.
- The expression is submitted in a single request.
- Expr begins recursive evaluation of the nested structure.
- Stack memory grows rapidly and exceeds system limits.
- The application process crashes with a stack overflow or segmentation fault.
A single request is sufficient to trigger the crash.
Example Exploitation Patterns
Basic Payload
flatten([[[[[[[[[[[[[[[[[[[[1]]]]]]]]]]]]]]]]]]])
Disguised Business Logic
mean([10, 20, [30, [40, [50, [60, [70, [80, [90, [100]]]]]]]]], 110])
Chained Function Abuse
max(min([[[[[[1]]]]]]]), flatten([[[[[2]]]]]]))
These expressions appear syntactically valid and often resemble legitimate logic, which makes simple filtering ineffective.
MITRE ATT&CK Mapping
- Tactic: Impact (TA0040)
- Primary Technique: Endpoint / Application Denial of Service (T1499)
- Sub-Technique: Application Exhaustion Flood (T1499.003)
Related Techniques:
- Exploit Public-Facing Application (T1190)
- Impair Defenses (T1562) through crashing monitoring or control services
This attack fits a classic resource exhaustion pattern where application logic, not network bandwidth, is abused.
Detection and Monitoring Guidance
Key Challenge
Malicious expressions are often valid and only become dangerous due to their depth. Many applications crash before logging the full payload, leaving limited forensic evidence.
What to Watch For
- Sudden application crashes or restarts
- Stack overflow or segmentation fault errors
- Requests immediately preceding process termination
- Expressions containing excessive bracket nesting
- Use of
flatten,min,max,mean, ormedianwith unusually complex arrays
Recommended Log Sources
- Web Application Firewall (WAF) logs with request body inspection
- API gateway and application access logs
- Application runtime and error logs
- Process monitoring and crash reports
- Network traffic captures (where available)
Practical Detection Logic
- Flag expressions with more than 10–15 nested brackets
- Alert when vulnerable function names appear alongside deep nesting
- Correlate application crashes with recent expression-based requests (within 5 seconds)
Detection Rules
Splunk SPL Query:
index=application_logs OR index=web_logs
| where (request_body LIKE "%flatten(%" OR request_body LIKE "%mean(%" OR request_body LIKE "%median(%" OR request_body LIKE "%min(%" OR request_body LIKE "%max(%")
| rex field=request_body max_match=0 "(?<bracket_sequences>\[{10,})"
| where isnotnull(bracket_sequences)
| eval bracket_count=mvcount(bracket_sequences)
| where bracket_count > 0
| stats count by src_ip, request_url, request_body, _time
| where count > 0
Microsoft Sentinel KQL Query:
let VulnerableFunctions = dynamic(["flatten", "mean", "median", "min", "max"]);
let SuspiciousPattern = @"\[{10,}";
union AppLogs, WebLogs
| where TimeGenerated > ago(1h)
| where RequestBody has_any (VulnerableFunctions)
| where RequestBody matches regex SuspiciousPattern
| extend BracketDepth = extract_all(@"\[+", RequestBody)
| extend MaxDepth = array_length(BracketDepth)
| where MaxDepth > 10
| project TimeGenerated, SourceIP, RequestURL, RequestBody, MaxDepth, ResponseCode
| order by TimeGenerated desc
Remediation and Mitigation
Immediate Action (Strongly Recommended)
Upgrade all affected applications to:
Expr version 1.17.7
This release introduces recursion depth limits and safely aborts evaluation when limits are exceeded, returning controlled errors instead of crashing.
Official Patch
- Release: Expr v1.17.7
- Patch Source:
https://github.com/expr-lang/expr/releases/tag/v1.17.7
Go Module Update:
go get -u github.com/expr-lang/[email protected]
Temporary Safeguards (If Patch Is Delayed)
- Enforce maximum expression size and nesting depth
- Reject expressions exceeding reasonable complexity
- Apply WAF rules blocking excessive bracket nesting
- Rate-limit expression evaluation endpoints
- Isolate expression evaluation into sandboxed worker processes
- Enable automatic restart with alerting for crashed services
Business and Risk Impact
Although this vulnerability does not expose data or allow code execution, its availability impact is severe. Successful exploitation results in immediate downtime, which can:
- Disrupt customer-facing services
- Violate SLAs
- Cause financial and reputational damage
Because exploitation is trivial and does not require authentication, organizations should assume active scanning and abuse against internet-facing systems.
For critical environments, this issue should be treated with critical priority, even though the CVSS score is 7.5.
Final Assessment
CVE-2025-68156 is a straightforward but highly disruptive vulnerability. Its simplicity, reliability, and exposure through normal application features make it attractive to attackers. Any system using vulnerable versions of Expr should be patched without delay.
Upgrading to Expr 1.17.7 is the only complete and reliable fix.
