From f34a24c17b3252628056bfcbc991fd408fab5493 Mon Sep 17 00:00:00 2001 From: ai-anant Date: Thu, 3 Sep 2026 06:17:53 +0530 Subject: [PATCH 1/2] feat(java): detect process launch with a workspace-resolved executable path (CWE-427/94) --- .../rce/workspace-child-launch-direct.yaml | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 java/jenkins/rce/workspace-child-launch-direct.yaml diff --git a/java/jenkins/rce/workspace-child-launch-direct.yaml b/java/jenkins/rce/workspace-child-launch-direct.yaml new file mode 100644 index 0000000..89ac28d --- /dev/null +++ b/java/jenkins/rce/workspace-child-launch-direct.yaml @@ -0,0 +1,44 @@ +rules: + # ============================================================================ + # WORKSPACE-RESOLVED PATH FLOWING INTO A PROCESS-LAUNCH COMMAND VECTOR + # (CWE-427 Uncontrolled Search Path Element / CWE-94 Improper Control of + # Generation of Code) + # Generic shape: a Jenkins build step builds a process command vector whose + # executable path (and/or tokens) are resolved from a FilePath inside the + # build workspace (`workspace.child(...)` / `FilePath.child(...)`), and that + # vector is handed to `Launcher.launch().cmds(...)`. Workspace content is + # commonly attacker-influenceable (SCM checkout, shared agent workspaces, + # earlier build steps); if a step re-uses an existing file at such a path as + # the process binary without verifying it is genuine, this yields arbitrary + # code execution in the build and potential credential exposure. + # ============================================================================ + - id: codevigilant.java.jenkins.rce.workspace-child-launch-direct + mode: taint + message: >- + A process is launched with a command vector built from a workspace- + resolved path (a FilePath `child(...)`). Build workspace content can be + attacker-influenceable (SCM checkout, shared agent workspace, earlier + build steps). Executing a workspace-resolved file without verifying its + authenticity can allow arbitrary code execution in the build context and + expose any credentials in the process environment. Resolve the executable + from a trusted location and verify its integrity (checksum/PGP). + severity: WARNING + languages: [java] + pattern-sources: + - pattern: $WS.child($NAME).getRemote() + - pattern: $WS.child($NAME) + pattern-sinks: + - pattern: $X.add($T) + - pattern: new ArgumentListBuilder($T) + - pattern: $LAUNCHER.launch().cmds($ARGS) + metadata: + category: security + cwe: "CWE-427: Uncontrolled Search Path Element" + owasp: "A03:2021 - Injection" + technology: jenkins + confidence: MEDIUM + references: + - https://cwe.mitre.org/data/definitions/427.html + - www.jenkins.io/doc/developer/security/access-control/sandbox/ + source: semgrep-rule-gap + license: MIT \ No newline at end of file From 0ee2de9a5f849c4ea9a16bb857b9b6bd30b085b3 Mon Sep 17 00:00:00 2001 From: ai-anant Date: Fri, 4 Sep 2026 12:24:35 +0530 Subject: [PATCH 2/2] feat(java): extend workspace-child-launch-direct to string-concatenated workspace paths + multi-arg add sinks (CWE-427/94) --- .../rce/workspace-child-launch-direct.yaml | 39 +++++++++++++++---- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/java/jenkins/rce/workspace-child-launch-direct.yaml b/java/jenkins/rce/workspace-child-launch-direct.yaml index 89ac28d..f3e6aba 100644 --- a/java/jenkins/rce/workspace-child-launch-direct.yaml +++ b/java/jenkins/rce/workspace-child-launch-direct.yaml @@ -5,18 +5,24 @@ rules: # Generation of Code) # Generic shape: a Jenkins build step builds a process command vector whose # executable path (and/or tokens) are resolved from a FilePath inside the - # build workspace (`workspace.child(...)` / `FilePath.child(...)`), and that - # vector is handed to `Launcher.launch().cmds(...)`. Workspace content is - # commonly attacker-influenceable (SCM checkout, shared agent workspaces, - # earlier build steps); if a step re-uses an existing file at such a path as - # the process binary without verifying it is genuine, this yields arbitrary - # code execution in the build and potential credential exposure. + # build workspace — either via `workspace.child(...)` / `FilePath.child(...)` + # or by STRING-CONCATENATING the workspace path value (e.g. + # `$WS + "/binary"`, `$WS + "/" + $NAME`; FilePath.toString() yields the + # remote path string so the concat resolves to the workspace on the agent) — + # and that vector is handed to `Launcher.launch().cmds(...)` / + # `ArgumentListBuilder`. Workspace content is commonly attacker-influenceable + # (SCM checkout, shared agent workspaces, earlier build steps); if a step + # re-uses an existing file at such a path as the process binary without + # verifying it is genuine (e.g. the binary was supposed to be downloaded from + # a URL but the download failed silently), this yields arbitrary code + # execution in the build and potential credential exposure. # ============================================================================ - id: codevigilant.java.jenkins.rce.workspace-child-launch-direct mode: taint message: >- A process is launched with a command vector built from a workspace- - resolved path (a FilePath `child(...)`). Build workspace content can be + resolved path (a FilePath `child(...)` result or a path string built by + concatenating the workspace value). Build workspace content can be attacker-influenceable (SCM checkout, shared agent workspace, earlier build steps). Executing a workspace-resolved file without verifying its authenticity can allow arbitrary code execution in the build context and @@ -27,8 +33,25 @@ rules: pattern-sources: - pattern: $WS.child($NAME).getRemote() - pattern: $WS.child($NAME) + # string-concatenated workspace path (FilePath.toString() == getRemote()): + - patterns: + - pattern-either: + - pattern: $WS + "/" + $NAME + - patterns: + - pattern: $WS + $LIT + - metavariable-regex: + # metavariable-regex sees the quoted literal text + # (e.g. "/scannercli"), so anchor on the leading quote. + metavariable: $LIT + regex: '^"[/\\]' pattern-sinks: - - pattern: $X.add($T) + # scope the add-sink to command-vector-like receivers to avoid + # flagging ordinary collection adds (e.g. List.add) + - patterns: + - pattern: $X.add(..., $T, ...) + - metavariable-regex: + metavariable: $X + regex: (?i).*(arg|cmd|command|argv|launch|proc|builder|token).* - pattern: new ArgumentListBuilder($T) - pattern: $LAUNCHER.launch().cmds($ARGS) metadata: