Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
87f9cc8
model: propagate untrusted host through HttpHost#<init> into the host…
misonijnik Jul 3, 2026
e9e6a6b
test(rules): Add positive XSS sample for HttpHeaders getFirst propaga…
misonijnik Jul 2, 2026
4424e1a
More Java/Kotlin rules
dvvrd Mar 24, 2026
7f1c4bf
Wire missing -in-servlet-app/-in-spring-app rules and add CodeQL sani…
misonijnik May 16, 2026
306774e
Add CodeQL-aligned LDAP/SSRF/XSS sanitizers and exercising negative t…
misonijnik May 16, 2026
7dac17d
Add minimal repros for analyzer FN gaps + the propagators that fix them
misonijnik May 17, 2026
379cb30
Add JVM-level regression tests for pattern-matcher behaviours touched…
misonijnik May 17, 2026
bf9a4d1
Add Servlet API propagators + widen servlet entry-point pattern
misonijnik May 17, 2026
b55135a
Drive rules/test FN from 281 to 7 with CI-style JVM flags
misonijnik May 17, 2026
54a5c42
Add CodeQL-aligned barriers with test bank for path, ssrf, ldap, log,…
misonijnik May 17, 2026
484d573
More CodeQL-aligned barriers: XPath, SSTI, deser, log line-breaks, re…
misonijnik May 17, 2026
ba4815b
Add SMTP CRLF, unvalidated-redirect, and Spring/XSS barrier sanitizers
misonijnik May 17, 2026
b87e7c6
Add ValidatingObjectInputStream deserialization barrier test
misonijnik May 17, 2026
5bf7cba
More XSS encoder barriers: Apache escapeEcmaScript, OWASP ESAPI suite
misonijnik May 17, 2026
77e9f9d
Extend response-injection barriers to match XSS encoder set
misonijnik May 17, 2026
4c376ce
Extend spring-response-injection barriers to match XSS encoder set
misonijnik May 17, 2026
f5b284b
Add CodeQL external barrierModel sanitizers: File.getName + ESAPI Val…
misonijnik May 17, 2026
211856d
Treat URL encoders as CRLF/http-response-splitting barriers
misonijnik May 17, 2026
885e615
Add Jenkins hudson.Util.escape as XSS / response-injection barrier
misonijnik May 17, 2026
876b6c0
Drop ESAPI Validator.getValidURI — not in current ESAPI surface
misonijnik May 17, 2026
6fee352
Add pixee java-security-toolkit barriers: HtmlEncoder, Newlines
misonijnik May 17, 2026
f22e95d
Add pixee Urls.create as SSRF barrier
misonijnik May 17, 2026
85fea58
Add pixee Urls.create as unvalidated-redirect barrier
misonijnik May 17, 2026
c8ae0df
Add pixee deser + reflection barriers
misonijnik May 17, 2026
8b68125
Drop runCommandAsString sanitizer (not in pixee 1.2.3 API)
misonijnik May 17, 2026
1e088fe
Add pixee jakarta.PathValidator.validateDispatcherPath as url-forward…
misonijnik May 17, 2026
8b7ca62
Eliminate remaining 7 FN by fixing sink + propagator gaps
misonijnik May 17, 2026
94ea2bf
Remove rule tests
misonijnik May 18, 2026
66768b9
Polish rules: dedupe, fix typos, consolidate provenance
misonijnik May 18, 2026
1fda35e
Activate rule-test suite end-to-end: rename test IDs, add propagators
misonijnik May 18, 2026
20f9692
ssrf-sinks: add inline URL/URI wrapper variants for 9 missing sinks
misonijnik May 18, 2026
3b50550
ssrf-sinks: refactor URL/URI wrappers into pattern-inside let-bindings
misonijnik May 18, 2026
272f61b
ssrf-sinks: chain pattern-inside let-bindings via shared metavars
misonijnik May 18, 2026
e1e227f
ssrf-sinks: collapse builder-chain steps into a single multi-line pat…
misonijnik May 18, 2026
f064c70
ssrf-sinks: document why `$_` is the .uri/.url receiver
misonijnik May 18, 2026
941d903
ssrf-sinks: use literal `new Request.Builder()` for OkHttp, keep `$_`…
misonijnik May 18, 2026
e40f464
ssrf-sinks: bind HttpRequest newBuilder() receiver via $NEW_BUILDER
misonijnik May 20, 2026
5383d1b
Remove new taint sources (revert to origin/main source rules)
misonijnik May 22, 2026
9307470
ci-rules: overlay source propagators into analyzer jar
misonijnik May 22, 2026
0911ef1
ci-rules: overlay config with zip to avoid jar uf duplicate-entry crash
misonijnik May 22, 2026
4bd1049
rules: detect taint entering wrappers carried on virtual fields
misonijnik May 26, 2026
7eae86e
rules: pin ognl-injection-sinks Map.of receiver via pattern-inside
misonijnik May 27, 2026
ff8292a
rules: leave $COND unconstrained in ldap-injection-sinks Spring block
misonijnik May 27, 2026
fff61d5
ci-rules: point config overlay at relocated java-config path
misonijnik May 29, 2026
22d29d4
rules/test: migrate sample suite to declarative rule-test.yaml harness
misonijnik Jul 3, 2026
1041204
rules: relax unsafe-jackson activateDefaultTyping sink to untyped val…
misonijnik Jul 3, 2026
0dd5c04
rules: add `new URL(spec)` pattern-propagators to ssrf + path-travers…
misonijnik Jul 3, 2026
be9e548
rules/test: fix + re-enable SSRF HttpAsyncRequester and Kotlin TextSt…
misonijnik Jul 3, 2026
762b63d
rules/test: drop vestigial commented-out @RuleSample annotations
misonijnik Jul 3, 2026
aa8d61a
rules/test: fix #7 in place, drop repro-related disabled samples
misonijnik Jul 3, 2026
02964d5
rules: match a HttpHost built from untrusted data reaching HttpAsyncR…
misonijnik Jul 3, 2026
e05b0c8
rules: drop unparseable URL[] array propagators from ssrf-sinks
misonijnik Jul 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
language: java
passThrough:
- function: org.apache.hc.core5.http.HttpHost#<init>
signature: (java.lang.String) *
copy:
- from: arg(0)
to:
- this
- .org.apache.hc.core5.http.HttpHost#hostName#java.lang.String
- function: org.apache.hc.core5.http.HttpHost#<init>
signature: (java.lang.String, int) *
copy:
- from: arg(0)
to:
- this
- .org.apache.hc.core5.http.HttpHost#hostName#java.lang.String
- function: org.apache.hc.core5.http.HttpHost#<init>
signature: (java.lang.String, java.lang.String, int) *
copy:
- from: arg(1)
to:
- this
- .org.apache.hc.core5.http.HttpHost#hostName#java.lang.String
- function: org.apache.hc.core5.http.io.entity.StringEntity#<init>
signature: (java.lang.String) *
copy:
Expand Down
161 changes: 160 additions & 1 deletion rules/ruleset/java/lib/generic/code-injection-sinks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,17 @@ rules:
- java
patterns:
- pattern-either:
# ── ognl.Ognl core ──
- pattern: ognl.Ognl.getValue($INPUT,...);
# ── Struts2 OgnlReflectionProvider ──
- pattern: (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).getGetMethod($T, $INPUT,...);
- pattern: (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).getSetMethod($T, $INPUT,...);
- pattern: (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).getField($T, $INPUT,...);
- pattern: (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).setProperties($INPUT,...);
- pattern: (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).setProperty($INPUT,...);
- pattern: (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).getValue($INPUT,...);
- pattern: (com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P).setValue($INPUT,...);
# ── Struts2 ReflectionProvider (interface) ──
- pattern: (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).getGetMethod($T, $INPUT,...);
- pattern: (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).getSetMethod($T, $INPUT,...);
- pattern: (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).getField($T, $INPUT,...);
Expand All @@ -26,18 +29,20 @@ rules:
- pattern: (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).getValue($INPUT,...);
- pattern: (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).setValue($INPUT,...);
- pattern: (com.opensymphony.xwork2.util.reflection.ReflectionProvider $P).translateVariables($INPUT,...);
# ── Struts2 TextParseUtil ──
- pattern: com.opensymphony.xwork2.util.TextParseUtil.translateVariables($INPUT, ...);
- pattern: com.opensymphony.xwork2.util.TextParseUtil.translateVariablesCollection($INPUT,...);
- pattern: com.opensymphony.xwork2.util.TextParseUtil.shallBeIncluded($INPUT,...);
# TODO: commaDelimitedStringToSet is propagator!
- pattern: com.opensymphony.xwork2.util.TextParseUtil.commaDelimitedStringToSet($INPUT,...);
# ── Struts2 OgnlTextParser / OgnlUtil ──
- pattern: (com.opensymphony.xwork2.util.OgnlTextParser $P).evaluate($INPUT,...);
- pattern: (com.opensymphony.xwork2.util.OgnlTextParser $P).setProperties($INPUT,...);
- pattern: (com.opensymphony.xwork2.ognl.OgnlUtil $P).setProperty($INPUT,...);
- pattern: (com.opensymphony.xwork2.ognl.OgnlUtil $P).getValue($INPUT,...);
- pattern: (com.opensymphony.xwork2.ognl.OgnlUtil $P).setValue($INPUT,...);
- pattern: (com.opensymphony.xwork2.ognl.OgnlUtil $P).callMethod($INPUT,...);
- pattern: (com.opensymphony.xwork2.ognl.OgnlUtil $P).compile($INPUT,...);
# ── Struts2 StrutsUtil / VelocityStrutsUtil / OgnlTool ──
- pattern: (org.apache.struts2.util.VelocityStrutsUtil $P).evaluate($INPUT,...);
- pattern: (org.apache.struts2.util.StrutsUtil $P).isTrue($INPUT,...);
- pattern: (org.apache.struts2.util.StrutsUtil $P).findString($INPUT,...);
Expand All @@ -46,10 +51,106 @@ rules:
- pattern: (org.apache.struts2.util.StrutsUtil $P).translateVariables($INPUT,...);
- pattern: (org.apache.struts2.util.StrutsUtil $P).makeSelectList($INPUT,...);
- pattern: (org.apache.struts2.views.jsp.ui.OgnlTool $P).findValue($INPUT,...);
# ── Struts2 ValueStack ──
- pattern: (com.opensymphony.xwork2.util.ValueStack $P).findString($INPUT,...);
- pattern: (com.opensymphony.xwork2.util.ValueStack $P).findValue($INPUT,...);
- pattern: (com.opensymphony.xwork2.util.ValueStack $P).setValue($INPUT,...);
- pattern: (com.opensymphony.xwork2.util.ValueStack $P).setParameter($INPUT,...);
# ognl.Node.getValue/setValue (Argument[this] - tainted compiled expression)
- patterns:
- pattern: (ognl.Node $INPUT).$METHOD(...);
- metavariable-regex:
metavariable: $METHOD
regex: (getValue|setValue)
# ognl.enhance.ExpressionAccessor.get/set (Argument[this])
- patterns:
- pattern: (ognl.enhance.ExpressionAccessor $INPUT).$METHOD(...);
- metavariable-regex:
metavariable: $METHOD
regex: (get|set)
# org.apache.commons.ognl.Ognl.getValue/setValue (Argument[0])
- pattern: org.apache.commons.ognl.Ognl.getValue($INPUT,...);
- pattern: org.apache.commons.ognl.Ognl.setValue($INPUT,...);
# org.apache.commons.ognl.Node.getValue/setValue (Argument[this])
- patterns:
- pattern: (org.apache.commons.ognl.Node $INPUT).$METHOD(...);
- metavariable-regex:
metavariable: $METHOD
regex: (getValue|setValue)
# org.apache.commons.ognl.enhance.ExpressionAccessor.get/set (Argument[this])
- patterns:
- pattern: (org.apache.commons.ognl.enhance.ExpressionAccessor $INPUT).$METHOD(...);
- metavariable-regex:
metavariable: $METHOD
regex: (get|set)
# OgnlValueStack methods (Argument[0])
- patterns:
- pattern: (com.opensymphony.xwork2.ognl.OgnlValueStack $P).$METHOD($INPUT,...);
- metavariable-regex:
metavariable: $METHOD
regex: (findString|findValue|getValue|getValueUsingOgnl|setParameter|setValue|tryFindValue|tryFindValueWhenExpressionIsNotNull|trySetValue)
# ActionSupport.getFormatted (Argument[0] and Argument[1])
- pattern: (com.opensymphony.xwork2.ActionSupport $P).getFormatted($INPUT,...);
- pattern: (com.opensymphony.xwork2.ActionSupport $P).getFormatted(...,$INPUT);
# TextProvider.getText (Argument[0])
- pattern: (com.opensymphony.xwork2.TextProvider $P).getText($INPUT,...);
# TextProvider.getText (Argument[1] - default value in some overloads)
- pattern: (com.opensymphony.xwork2.TextProvider $P).getText($A, $INPUT,...);
# TextProvider.hasKey (Argument[0])
- pattern: (com.opensymphony.xwork2.TextProvider $P).hasKey($INPUT);
# DEPENDENCY LIMITATION: LocalizedTextUtil removed in Struts 2.5.x (no test dependency available)
# LocalizedTextUtil.findText (Argument[1])
# - pattern: com.opensymphony.xwork2.util.LocalizedTextUtil.findText($A, $INPUT,...);
# LocalizedTextUtil.findText (Argument[3])
# - pattern: com.opensymphony.xwork2.util.LocalizedTextUtil.findText($A, $B, $C, $INPUT,...);
# ValidatorSupport.parse/getFieldValue (Argument[0])
- patterns:
- pattern: (com.opensymphony.xwork2.validator.validators.ValidatorSupport $P).$METHOD($INPUT,...);
- metavariable-regex:
metavariable: $METHOD
regex: (parse|getFieldValue)
# StrutsBodyTagSupport.findPattern/findString (Argument[1])
- patterns:
- pattern: (org.apache.struts2.views.jsp.StrutsBodyTagSupport $P).$METHOD($A, $INPUT,...);
- metavariable-regex:
metavariable: $METHOD
regex: (findPattern|findString)
# Inlined Map.of(...) flow into setProperties — OpenTaint's Map.of
# propagator stores taint on the MapValue accessor, not on the Map
# reference itself, so the bare $INPUT pattern misses the case where
# the caller wraps a tainted string in a Map first. Match the Map
# construction explicitly so $INPUT binds to the value, and pin the
# receiver type with a per-provider pattern-inside declaration (the
# dangerous-groovy-shell idiom below) instead of repeating each shape
# — OpenTaint does not support a typed `metavariable-pattern` on $P.
- patterns:
- pattern-either:
- pattern: |
$M = java.util.Map.of($K1, $INPUT);
...
$P.setProperties($M, ...);
- pattern: |
$M = java.util.Map.of($K1, $V1, $K2, $INPUT);
...
$P.setProperties($M, ...);
- pattern: |
$M = java.util.Map.of($K1, $INPUT, $K2, $V2);
...
$P.setProperties($M, ...);
- pattern: |
$P.setProperties(java.util.Map.of($K1, $INPUT), ...);
- pattern: |
$P.setProperties(java.util.Map.of($K1, $V1, $K2, $INPUT), ...);
- pattern: |
$P.setProperties(java.util.Map.of($K1, $INPUT, $K2, $V2), ...);
- pattern-either:
- pattern-inside: |
com.opensymphony.xwork2.ognl.OgnlReflectionProvider $P = ...;
...
- pattern-inside: |
com.opensymphony.xwork2.util.reflection.ReflectionProvider $P = ...;
...
- focus-metavariable: $INPUT

- id: dangerous-groovy-shell
options:
Expand Down Expand Up @@ -80,6 +181,22 @@ rules:
- pattern: groovy.util.Eval.x($X, $UNTRUSTED)
- pattern: groovy.util.Eval.xy($X, $Y, $UNTRUSTED)
- pattern: groovy.util.Eval.xyz($X, $Y, $Z, $UNTRUSTED)
# groovy.text.TemplateEngine.createTemplate (Argument[0])
- pattern: (groovy.text.TemplateEngine $T).createTemplate($UNTRUSTED)
# CompilationUnit.compile (Argument[this] - tainted compilation unit)
- pattern: |
(org.codehaus.groovy.control.CompilationUnit $UNTRUSTED).compile(...);
# Untrusted source added to a CompilationUnit then compiled. The unit stores
# the source in a virtual field, so the tainted-unit sink above can't observe
# it on the whole unit — match the source entering addSource and require a
# later compile() (cf. List.add(..) -> new ProcessBuilder($ARGS) in
# command-injection-sinks).
- patterns:
- pattern: |
(org.codehaus.groovy.control.CompilationUnit $CU).addSource(..., $UNTRUSTED, ...);
...
(org.codehaus.groovy.control.CompilationUnit $CU).compile(...);
- focus-metavariable: $UNTRUSTED

- id: dangerous-script-engine-eval
options:
Expand All @@ -94,3 +211,45 @@ rules:
- pattern: (javax.script.ScriptEngine $SE).eval($UNTRUSTED)
- pattern: (javax.script.Invocable $INVC).invokeFunction(..., $UNTRUSTED)
- pattern: (javax.script.Invocable $INVC).invokeMethod(..., $UNTRUSTED)

- id: mvel-injection-sinks
options:
lib: true
severity: NOTE
message: MVEL expression injection with user-controlled input
metadata:
provenance: https://github.com/github/codeql/tree/cdd8aa49e16650a96b8993e8745c7672600fe930/java/ql/lib/ext
languages:
- java
pattern-either:
# MVEL.eval/evalToBoolean/evalToString/executeAllExpression/executeExpression/executeSetExpression (Argument[0])
- patterns:
- pattern: org.mvel2.MVEL.$METHOD($EXPR, ...)
- metavariable-regex:
metavariable: $METHOD
regex: (eval|evalToBoolean|evalToString|executeAllExpression|executeExpression|executeSetExpression)
# MVELRuntime.execute (Argument[1])
- pattern: org.mvel2.MVELRuntime.execute($H, $EXPR, ...)
# MvelScriptEngine.eval/evaluate (Argument[0])
- patterns:
- pattern: (org.mvel2.jsr223.MvelScriptEngine $E).$METHOD($EXPR, ...)
- metavariable-regex:
metavariable: $METHOD
regex: (eval|evaluate)
# TemplateRuntime.eval/execute (Argument[0])
- patterns:
- pattern: org.mvel2.templates.TemplateRuntime.$METHOD($EXPR, ...)
- metavariable-regex:
metavariable: $METHOD
regex: (eval|execute)
# MvelCompiledScript.eval (Argument[this] - tainted compiled script)
- pattern: (org.mvel2.jsr223.MvelCompiledScript $EXPR).eval(...)
# Accessor/CompiledAccExpression/CompiledExpression/ExecutableStatement getValue/getDirectValue (Argument[this])
- patterns:
- pattern: (org.mvel2.compiler.$TYPE $EXPR).$METHOD(...)
- metavariable-regex:
metavariable: $TYPE
regex: (Accessor|CompiledAccExpression|CompiledExpression|ExecutableStatement)
- metavariable-regex:
metavariable: $METHOD
regex: (getValue|getDirectValue)
Loading
Loading