TL;DR: An AI pentesting engine found pre-auth SpEL-based RCE and a WAF bypass in a Spring JSP portal by reading source code, reasoning about expression evaluation, and rebuilding the exploit live, according to Escape. The result is a reminder that signature-based DAST and annual testing can miss context-driven injection paths.
At a glance
What this is: This is an analysis of how an AI pentesting tool found unauthenticated Spring SpEL injection and a WAF bypass in a JSP portal by tracing source-code flows and confirming exploitability.
Why it matters: It matters because application security teams cannot rely on payload libraries and firewall rules alone when attacker reasoning can adapt payloads to the evaluation context and reach a live injection sink.
👉 Read Escape's analysis of pre-auth SpEL RCE and WAF bypass in a Spring JSP portal
Context
Spring expression injection is a governance problem as much as a coding defect: once user input reaches an evaluator, the control boundary moves from string handling to code execution. In this case, the risk was amplified by a global JSP template and by a web application firewall that only inspected raw request bytes, not what the expression engine would reconstruct at runtime.
The primary identity angle is indirect but real. This is not an IAM or NHI story, yet it shows how quickly an application-level flaw can become credential theft, session abuse, or workload compromise if a server-side command execution path is exposed. For teams running application security, the lesson is that execution context, not just payload syntax, determines whether a control is meaningful.
The article’s starting position is typical of modern web application risk: known vulnerability classes become dangerous when source-aware testing proves that they are reachable in the specific application path.
Key questions
Q: How should security teams test for expression injection in Spring applications?
A: They should test the full data flow from request parameter to expression parser, not just the endpoint response. That means checking whether user input reaches a template or evaluator before parsing, then confirming whether the runtime can access methods, classes, or command execution. Source-aware testing is essential because blind payload lists often miss context-specific injection paths.
Q: Why do WAFs often miss obfuscated injection payloads?
A: WAFs usually inspect raw request strings, so they are weak against payloads that assemble dangerous keywords after parsing. If the application reconstructs the malicious expression at runtime, the firewall may never see the final string. That is why obfuscation, reflection, and character conversion can bypass controls that rely on signature matching alone.
Q: What breaks when application security testing ignores code context?
A: Teams lose the ability to tell whether a suspected issue is actually reachable in the deployed application. A scanner can report a clean result after a parse error, while source review would show that the parameter lands in a dangerous evaluation sink. Without code context, false negatives become routine and exploitable paths remain invisible.
Q: Who is accountable when pre-auth RCE is reachable through a template engine?
A: Accountability usually sits with the application owner, security engineering, and the team operating release controls, because the failure spans design, code review, and runtime protection. The relevant standards focus on secure coding, least privilege, and validation of security controls, not on the attacker’s technique. Governance must require proof that controls work in the deployed execution path.
Technical breakdown
Why SpEL becomes dangerous when user input reaches a JSP template
Spring Expression Language, or SpEL, is designed to evaluate expressions that can access objects, call methods, and invoke static APIs. That flexibility is useful for templating, but it becomes a code execution path when attacker-controlled data is inserted before the evaluator parses the expression. In the article’s case, the JSP engine substituted the parameter into the expression source first, so the payload was no longer a value inside quotes. It had become part of the executable expression itself. Under a StandardEvaluationContext, those capabilities are largely unconstrained, which is why a simple request could reach Runtime.exec().
Practical implication: remove attacker-controlled data from expression sources and review every template path that can reach an evaluator.
How WAF bypasses emerge when dangerous strings are built at runtime
A WAF usually inspects the raw HTTP request for known-bad strings and patterns. That model fails when the dangerous value does not exist in the request at all, but is assembled inside the application runtime after parsing. The technique described here uses integer-to-character conversion, reflection, and concatenation to rebuild class and method names such as java.lang.Runtime and getRuntime without writing them literally into the payload. The WAF sees numbers and method calls. The expression engine sees executable Java semantics. This is why payload obfuscation remains effective against pattern-matching defenses that do not understand language runtime behavior.
Practical implication: test whether defensive controls inspect semantics, not just raw strings, before trusting them to block injection.
Why source-code-aware testing changes exploit discovery
Traditional DAST tools are optimized for known payloads and response signatures. They can confirm a vulnerability when the exploit shape already matches a rule, but they struggle when the attacker must reason about data flow, parser order, and context-specific quoting. The article’s AI pentesting engine inspected the template, traced the ref parameter to the sink, and then adapted the payload when the WAF blocked the obvious form. That is fundamentally different from blind fuzzing. It is closer to a human code review plus live exploitation attempt, which is why it found both the clean RCE and the obfuscated bypass in the same application.
Practical implication: use testing that combines source understanding with runtime confirmation, not just signature-driven endpoint fuzzing.
Threat narrative
Attacker objective: The attacker wants unauthenticated remote command execution on the application server, with the ability to pivot into broader host compromise or downstream credential theft.
- Entry occurs when an unauthenticated request reaches a shared JSP template that inserts the ref parameter into a SpEL expression.
- Credential access is not needed because the attacker gains server-side command execution directly through expression injection and reflection.
- Escalation occurs when the payload is rebuilt at runtime to bypass WAF string matching and invoke Runtime.exec() without literal dangerous keywords.
NHI Mgmt Group analysis
Context-aware exploitation is now the differentiator between a surfaced bug and a real risk. The article shows that known vulnerability classes do not become less dangerous because they are documented; they become more dangerous when testing can prove reachability in the actual application flow. Signature-matching tools can miss that distinction entirely. Practitioners should treat source-aware validation as a required control layer, not a premium enhancement.
Expression injection is a control boundary failure, not just an input-validation defect. The important failure is that untrusted input crossed from data into executable expression source. That is a governance issue because the application owner assumed the WAF and scanner would contain the blast radius after deployment. In reality, the dangerous boundary sat inside the template engine. Teams should review any path where user data reaches an interpreter, evaluator, or reflection surface.
Runtime obfuscation defeats controls that only understand syntax, not semantics. The WAF blocked the obvious payload, but the article demonstrates that the application could still be made to reconstruct the same malicious intent at runtime. That is the same pattern defenders see in other injection families, including script injection and deserialisation abuse. The practitioner lesson is that detection and prevention must account for parser behaviour, not just string indicators.
AI-powered offensive testing is forcing a reset in application security assurance. This is not because AI creates new vulnerability classes, but because it shortens the path from source inspection to working exploit. The first meaningful use case is not autonomous magic; it is better reasoning over code, context, and control bypass. Security programmes should assume that attacker tooling will keep improving its ability to chain analysis and exploitation, and they should raise their own validation standard accordingly.
What this signals
Application security programmes should expect more findings that only emerge when source understanding is combined with runtime confirmation. The operational shift is away from periodic scan results and toward continuous validation of whether a control still works after code changes, template changes, or framework upgrades.
Execution-context drift: this is the gap that opens when a control looks effective in raw traffic but fails after parsing or evaluation. Teams should watch for any control that only proves it can block known strings, because that control may not be protecting the executable path the application actually uses.
For practitioners
- Remove user input from evaluator source Audit every JSP, template, and server-side expression path where request parameters are concatenated into evaluation strings. Replace dynamic expression construction with fixed expressions and server-side allowlists.
- Review WAF coverage against runtime reconstruction Test whether the WAF still blocks payloads when dangerous identifiers are assembled through concatenation, reflection, or character conversion at runtime. Treat a block on literal keywords as an incomplete control.
- Add source-to-sink verification to appsec testing Prioritise testing that traces request parameters from source code to sink, then confirms exploitability in the running application. Use it for expression engines, template helpers, and any reflection-heavy code paths.
- Map expression engines to privileged execution paths Inventory where evaluators can reach OS command execution, file access, or privileged framework methods. Escalate any such path into the same review lane you would use for exposed admin interfaces.
Key takeaways
- The article shows that known framework flaws become critical when user input reaches an evaluator before parsing.
- The WAF bypass demonstrates that syntax-based blocking cannot be trusted against runtime reconstruction and reflection.
- Application security teams need source-to-sink verification, not just payload-driven scanning, to avoid false confidence.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
MITRE ATT&CK address the attack surface, NIST CSF 2.0, NIST SP 800-53 Rev 5 and CIS Controls v8 set the technical controls, and ISO/IEC 27001:2022 define the regulatory obligations.
| Framework | Control / Reference | Relevance |
|---|---|---|
| MITRE ATT&CK | TA0001 , Initial Access; TA0006 , Credential Access; TA0008 , Lateral Movement | The attack chain centers on unauthenticated code execution and possible downstream movement. |
| NIST CSF 2.0 | PR.AC-3 | Application access control failed to prevent untrusted input from reaching an execution sink. |
| NIST SP 800-53 Rev 5 | SI-10 | Input validation and safe handling are central to preventing expression injection. |
| CIS Controls v8 | CIS-16 , Application Software Security | The issue sits in application-layer security testing and secure coding assurance. |
| ISO/IEC 27001:2022 | A.8.25 | Secure development lifecycle controls apply to framework and template code handling untrusted input. |
Map injection-driven execution paths to ATT&CK and prioritise controls that block initial access and lateral movement.
Key terms
- SpEL Injection: SpEL injection happens when attacker-controlled data is inserted into a Spring Expression Language expression and the evaluator treats it as executable syntax. That can expose object access, reflection, and method invocation, turning a template issue into server-side command execution.
- StandardEvaluationContext: StandardEvaluationContext is Spring’s general-purpose expression evaluation context. It exposes broad language capabilities, including type references and method calls, which makes it dangerous when untrusted input can influence the expression being parsed.
- WAF bypass: A WAF bypass is a request variation that slips past a web application firewall rule while still reaching the vulnerable application logic. It matters because fast defensive rules often target known proof-of-concept patterns, not every encoding, parameter, or legacy behaviour attackers can use.
What's in the full article
Escape's full analysis covers the exploit details this post intentionally leaves at a governance level:
- The exact request shapes and payload construction used to prove the unauthenticated SpEL injection path.
- The full obfuscation sequence that rebuilt dangerous Java identifiers at runtime to defeat keyword-based WAF rules.
- The agentic workflow used to trace source code, confirm exploitability, and reproduce the findings in the live application.
- The raw proof-of-concept outputs that show command execution returning in the rendered page.
👉 Escape's full post covers the source trace, exploit reconstruction, and command-execution proof.
Deepen your knowledge
The NHI Foundation Level course, the industry's only accredited NHI security programme, covers NHI governance, secrets management, and identity lifecycle fundamentals. It helps security and identity practitioners build governance skills that apply across modern access and control programmes.
Published by the NHIMG editorial team on August 18, 2026.
NHI Mgmt Group — the independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org