diff --git a/java/jenkins/crypto/bcrypt-truncated-password.yaml b/java/jenkins/crypto/bcrypt-truncated-password.yaml new file mode 100644 index 0000000..520fce7 --- /dev/null +++ b/java/jenkins/crypto/bcrypt-truncated-password.yaml @@ -0,0 +1,31 @@ +rules: + - id: codevigilant.java.jenkins.crypto.bcrypt-truncated-password + message: >- + A password byte array is truncated to 72 bytes (Arrays.copyOfRange(..., 0, + 72) or a BCRYPT/MAX_LENGTH constant) before being hashed or compared with + BCrypt. BCrypt only uses the first 72 bytes of the input, so truncating + first makes every password that shares its first 72 bytes equivalent + (password-equivalence) and silently weakens long credentials. Hash or + compare the full password and let the library apply its own limit, or + pre-hash long passwords with a fast digest (e.g. SHA-256) before BCrypt. + severity: HIGH + languages: [java] + patterns: + - pattern: Arrays.copyOfRange($BYTES, 0, $LEN) + - metavariable-regex: + metavariable: $LEN + regex: '^(72|.*MAX_LENGTH.*|.*BCRYPT.*)$' + metadata: + category: security + cwe: "CWE-916: Use of Password Hash With Insufficient Computational Effort" + owasp: "A02:2021 - Cryptographic Failures" + technology: + - jenkins + - java + - crypto + confidence: MEDIUM + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html + - https://en.wikipedia.org/wiki/Bcrypt + source: ai-anant + license: MIT diff --git a/java/jenkins/file-operation/filepath-copyfrom-url.yaml b/java/jenkins/file-operation/filepath-copyfrom-url.yaml new file mode 100644 index 0000000..0f50708 --- /dev/null +++ b/java/jenkins/file-operation/filepath-copyfrom-url.yaml @@ -0,0 +1,39 @@ +rules: + - id: codevigilant.java.jenkins.file-operation.filepath.copyfrom-url + patterns: + - pattern: $FP.copyFrom($URL) + - metavariable-pattern: + metavariable: $URL + patterns: + - pattern-either: + - pattern: new URL(...) + - pattern: (URL $U) + - pattern-not: $FP.copyFrom(new URL("...")) + message: | + Detected hudson.FilePath.copyFrom called with a non-literal URL. + copyFrom(URL) opens an outbound connection to the given URL and writes + the response body into the FilePath on the local node. In Jenkins + plugins the URL frequently originates from a remote server response + (report/download links), job configuration or build parameters expanded + at runtime. An attacker who can influence the resolved value can make + the agent/controller fetch arbitrary internal or external URLs + (server-side request forgery) and can steer the fetched content into an + attacker-chosen destination path, enabling arbitrary file writes on the + node. When the URL is not fully trusted, validate its scheme and host + against an allow-list, add connect/read timeouts, and constrain the + destination with FilePath.child(...) plus an isDescendant containment + check before fetching. + metadata: + category: security + cwe: "CWE-918: Server-Side Request Forgery (SSRF)" + owasp: "A10:2021 - Server-Side Request Forgery" + technology: jenkins + confidence: MEDIUM + references: + - https://www.jenkins.io/doc/developer/security/#server-side-request-forgery-ssrf + - https://owasp.org/www-community/attacks/Server_Side_Request_Forgery + source: independent security review + license: MIT + languages: [java] + mode: search + severity: HIGH diff --git a/testcases/java/filepath-tainted-path-neg.java b/testcases/java/filepath-tainted-path-neg.java new file mode 100644 index 0000000..f8c70a9 --- /dev/null +++ b/testcases/java/filepath-tainted-path-neg.java @@ -0,0 +1,13 @@ +import hudson.FilePath; +import hudson.remoting.VirtualChannel; +import java.net.URL; + +// Negative: literal URLs, FilePath-to-FilePath copies and child()-derived paths -> must NOT fire +public class FilePathLiteralRepro { + public void safe(FilePath workspace, VirtualChannel channel, FilePath other) throws Exception { + FilePath literal = new FilePath(channel, "/var/lib/jenkins/workspace"); + FilePath child = workspace.child("report.html"); + literal.copyFrom(new URL("https://acunetix.example/reports/1.html")); + child.copyFrom(other); // FilePath-to-FilePath copy, not a URL fetch + } +} diff --git a/testcases/java/filepath-tainted-path-pos.java b/testcases/java/filepath-tainted-path-pos.java new file mode 100644 index 0000000..73ef919 --- /dev/null +++ b/testcases/java/filepath-tainted-path-pos.java @@ -0,0 +1,13 @@ +import hudson.FilePath; +import hudson.remoting.VirtualChannel; +import java.net.URL; + +// Positive: copyFrom fed a non-literal URL (remote-controlled download link), +// fetched into a path built by string concatenation. Must fire on the copyFrom sink. +public class FilePathTaintedRepro { + public void saveReport(FilePath workspace, VirtualChannel channel, String reportName, String urlSource) throws Exception { + URL url = new URL(urlSource); + FilePath reportFile = new FilePath(channel, workspace.getRemote() + "/" + reportName); + reportFile.copyFrom(url); + } +}