Why Groovy Compile-Time Annotations Break the Jenkins Script Security Sandbox
The Jenkins advisory published on September 16, 2026 lists seven Script Security sandbox bypasses among its 20 plugin vulnerabilities. Most of them follow patterns that security engineers expect: a coercion here, a null receiver there, a race condition in a check. One cluster does not. It abuses Groovy annotations that execute during compilation, and it exposes a limitation that no amount of runtime interception can fix.
Understanding that cluster matters beyond this advisory. It explains why sandboxing a dynamic JVM language is structurally harder than it looks, and why the same technique is likely to reappear.
How the sandbox normally works
The Script Security Plugin guards Pipeline execution by intercepting Groovy operations at runtime. When a sandboxed script calls a method, reads a field, or invokes a constructor, the interceptor examines the operation and compares it against an allowlist. Anything not approved by an administrator, or not covered by the classpath approval mechanism, is rejected before it runs.
This design is fundamentally reactive. It waits for an operation to occur and then decides whether to permit it. That works as long as the interceptor sees the operation in the form the developer wrote it.
Where the model breaks
Groovy supports local AST transformations through annotations. When the compiler encounters an annotation such as @GroovyASTTransformationClass or @Builder, it invokes an associated transformation during the compilation phase. That transformation receives the abstract syntax tree and can rewrite it: adding methods, changing class structure, generating new code.
The sandbox intercepts runtime execution. It does not sit between the compiler and the AST. By the time the sandbox sees the code, the transformation has already run and the script's actual behaviour may differ from the source that was reviewed.
A user who can place one of these annotations inside a Pipeline definition therefore has a route around the runtime check. The compiler becomes the instrument of the escape, and the sandbox's allowlist is evaluated against a program that has already been reshaped.
The other six bypasses in the same batch
The advisory groups the remaining sandbox escapes by technique, and they are more conventional:
- Interface coercion. Groovy's automatic type coercion between interfaces can produce a call path that the interceptor does not model as a method invocation.
- Null receivers. Invoking a method on a null receiver follows a distinct resolution path that the sandbox does not inspect.
- Collection casting. Casting collections between types can reach methods the sandbox believed it had blocked.
- Classpath approval bypass. Classpath approval is how administrators extend the allowlist to additional code. If that approval can be circumvented, the allowlist loses its meaning.
- Time-of-check-to-time-of-use race. The sandbox's decision and the eventual execution can be separated in time, allowing state to change in between.
Each of these is a defect that a patch can close. The compile-time annotation case is different in kind: it exploits the boundary between two execution phases rather than a flaw within one.
Impact of a successful bypass
All seven flaws end in the same outcome: arbitrary code execution inside the Jenkins controller JVM.
The controller is the most privileged component in a Jenkins installation. It stores the credentials used to reach source control, cloud providers, container registries, and deployment targets. It defines and orchestrates every job. An attacker with code execution there can read those credentials, alter job definitions, and inject steps into future builds.
For build pipelines that produce software artifacts, controller compromise is a supply chain event. Anything built after the compromise requires independent verification before it can be trusted.
Affected versions and fixed releases
The flaws affect the Script Security Plugin up to and including 1415.v9a_f9b_3a_c253d. The fixed release is 1422.v06869826dd9b_ or later.
The broader advisory also covers the Robot Framework Plugin up to 6.2.2, fixed in 6.3.0, along with stored XSS issues in Warnings, Coverage, and Dependency-Check, and SSRF issues in the Gradle and Bitbucket plugins. None of the affected components is Jenkins core.
Exploitation status
The Jenkins project reports no known active exploitation and no public proof-of-concept at the time of publication. Many of the issues were submitted through the Jenkins Bug Bounty Program.
Remediation
Upgrade Script Security to 1422.v06869826dd9b_ or later. This is the direct fix for all seven sandbox bypasses.
Restrict Pipeline authoring rights. Every one of these bypasses requires the attacker to be able to define and run a sandboxed Pipeline. Limiting job configuration and Pipeline definition to a small, audited group removes the precondition. This control remains effective after the current advisory is closed.
Treat the controller as a high-value asset. Apply the same segmentation, credential hygiene, and monitoring you would apply to any system that holds deployment secrets. Review which credentials a controller-level job can reach and rotate those that matter.
Track plugin versions continuously. The compile-time annotation technique is not specific to one plugin. Keeping an accurate inventory of installed plugins and their versions is what makes the next advisory actionable.
Sources
- Jenkins Security Advisory, September 16, 2026: https://www.jenkins.io/security/advisories/
- SecurityOnline.info, "Jenkins Patches 20 Plugin Flaws, Sandbox Bypasses Lead RCE": https://securityonline.info/jenkins-plugin-vulnerabilities-september-2026/
- Jenkins Script Security Plugin documentation: https://plugins.jenkins.io/script-security/
Top comments (0)