From 6f01d2acef6b2b772d6358c73caa990083473b12 Mon Sep 17 00:00:00 2001 From: ai-anant Date: Sat, 15 Aug 2026 05:22:28 +0000 Subject: [PATCH] feat(java): detect Jelly form-entry title/description expressions rendered unescaped (CWE-79) --- .../xss/jelly-entry-unescaped-expression.yaml | 37 +++++++++++++++++++ testcases/java/jelly-entry-unescaped-neg.xml | 17 +++++++++ testcases/java/jelly-entry-unescaped-pos.xml | 20 ++++++++++ 3 files changed, 74 insertions(+) create mode 100644 java/jenkins/xss/jelly-entry-unescaped-expression.yaml create mode 100644 testcases/java/jelly-entry-unescaped-neg.xml create mode 100644 testcases/java/jelly-entry-unescaped-pos.xml diff --git a/java/jenkins/xss/jelly-entry-unescaped-expression.yaml b/java/jenkins/xss/jelly-entry-unescaped-expression.yaml new file mode 100644 index 0000000..9220883 --- /dev/null +++ b/java/jenkins/xss/jelly-entry-unescaped-expression.yaml @@ -0,0 +1,37 @@ +rules: + - id: codevigilant.java.jenkins.xss.jelly-entry-unescaped-expression + message: >- + A Jelly form entry (f:entry/f:block) binds a ${...} expression to its + title/description while the view disables escaping via + `escapeEntryTitleAndDescription=false`. The expression is neither wrapped + in h.escape(...) nor the MarkupFormatter-sanitized + formattedDescription/getFormattedDescription getter, so any + configuration- or user-controlled content reaching the attribute is + emitted as raw HTML in the Jenkins UI (stored XSS, CWE-79). Escape the + value with h.escape(...) or render only the markup-formatter output. + severity: ERROR + languages: + - generic + paths: + include: + - "*.jelly" + - "*.xml" + patterns: + - pattern-inside: | + + ... + - pattern-regex: >- + (?is)]*\b(?:title|description)="\$\{(?!h\.escape\()(?![^"}]*getFormattedDescription\(\))(?![^"}]*\.formattedDescription\s*\})[^"]*" + metadata: + category: security + cwe: "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')" + owasp: "A03:2021 - Injection" + technology: + - jenkins + - jelly + confidence: MEDIUM + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html + - https://www.jenkins.io/doc/developer/security/ + source: ai-anant + license: MIT diff --git a/testcases/java/jelly-entry-unescaped-neg.xml b/testcases/java/jelly-entry-unescaped-neg.xml new file mode 100644 index 0000000..a8722f3 --- /dev/null +++ b/testcases/java/jelly-entry-unescaped-neg.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/testcases/java/jelly-entry-unescaped-pos.xml b/testcases/java/jelly-entry-unescaped-pos.xml new file mode 100644 index 0000000..fb60c4d --- /dev/null +++ b/testcases/java/jelly-entry-unescaped-pos.xml @@ -0,0 +1,20 @@ + + + + + + + +
+ + +
+
+
+ + + + + + +