feat(rules): Update rules to use star operator - #314
Open
misonijnik wants to merge 12 commits into
Open
Conversation
misonijnik
force-pushed
the
misonijnik/3-rules
branch
3 times, most recently
from
July 30, 2026 08:10
f5be3ef to
97adcc7
Compare
misonijnik
force-pushed
the
misonijnik/3-rules
branch
2 times, most recently
from
August 12, 2026 09:24
9508d6a to
c3403d7
Compare
misonijnik
force-pushed
the
misonijnik/3-rules
branch
from
August 14, 2026 10:12
c3403d7 to
11ca418
Compare
misonijnik
marked this pull request as ready for review
August 14, 2026 10:15
Saloed
force-pushed
the
misonijnik/3-rules
branch
from
August 17, 2026 19:25
11ca418 to
bc5cc77
Compare
misonijnik
force-pushed
the
misonijnik/3-rules
branch
2 times, most recently
from
August 18, 2026 15:45
41185cc to
56224bf
Compare
…e star Replaces the two hard-coded Spring hacks with rule-level star operators: the controller parameter source is now `$*UNTRUSTED`, and the controller-return any-field sinks are expressed with a starred metavar. Both the source hack and the sink hack are deleted. Also restores the Z2F-gate bypass for controller-return sinks and tightens the source `$TYPE` regex, which the hack had been masking.
Keeps array and primitive parameters as plain value sources, stars the untrusted-path-source pattern-not with a fresh metavar, drops the List adapter overloads from the command-injection sink, and collapses the servlet upload source read-back -- all expressible directly now that a starred metavar means whole-object taint. Documents the pattern-not star limitation, the sink focus requirement and the Go parity story in the rules README.
resolveArrayPosition was the last implicit type-triggered array mechanism: it silently gave every array- or Object-typed source ASSIGN position an element twin. The star operator expresses the same thing from the rules, and does it better -- the any-field star is recursive, so it also catches the deep Map<String,String[]> flows the element-only twin missed. Array and vararg sink args are now starred explicitly, the implicit sink any-field emission is gone, and the Go side drops its blanket any-accessor emission in favour of explicit variadic taint in the Go model config.
Makes the servlet source whole-object and adds the channel-model getter passthroughs it reads back, and stars the xss and response-injection value sanitizers so a sanitized wrapper is recognised as clean at every depth.
Collapses the source down to a single focused form, focuses and stars the session-store sink, and flags a tainted attribute NAME as well as a tainted value -- previously only the value was considered.
Makes the java.io.File model field-sensitive with starred path sinks, and migrates every starred metavar in the ruleset, the Spring rule provider and the rules README to the $*VAR spelling the parser accepts.
The one false positive the rule-tests have been carrying since before this batch: InsecureDesignSamples#validateBeforeCrossingTrustBoundarySecure reads a value back out of the session and stores it again, which is the textbook safe shape, and it reported. The source pattern was `$*RESULT = $REQ.$FUNC(...)` with $REQ bound by the sibling pattern-inside and getSession excluded by a $FUNC regex. Probing the analyzer with three rewritten regexes shows what actually happens: ^zzzNoSuchMethodzzz$ -> 0 findings (the regex constraint is applied) ^getSession$ -> 2 findings (getSession calls do reach the sink) ^getAttribute$ -> 2 findings, including the FP The last one is the answer: `session.getAttribute(..)` matches `$REQ.$FUNC(..)` because the $REQ binding from pattern-inside is not enforced in the sibling pattern, so any receiver matches. Reading back out of the session became a source, and the getSession exclusion never saw the call it was meant to stop. Typing the receiver in the pattern itself - `(HttpServletRequest $REQ).$FUNC(...)`, which is what the sink patterns already do - keeps the three true positives and drops the false one. The rule-tests are now 0 FP / 0 FN for the first time.
Saloed
force-pushed
the
misonijnik/3-rules
branch
from
August 19, 2026 22:10
56224bf to
44877fb
Compare
`StringUtils.arrayToCommaDelimitedString(dir.listFiles())` joins `String.valueOf(element)`
for every element, so a mark on an element *object* -- or on any field of it, e.g.
`java.io.File#path` -- belongs on the returned String as a plain value.
The library model instead copies `arg(0)[*]` verbatim, which carries the element's own
accessors over into a String result; `result.java.io.File#path` is correctly rejected by
the type checker and the flow dies there. WebGoat's
ResponseEntity.status(..).body(
StringUtils.arrayToCommaDelimitedString(catPicture.getParentFile().listFiles())
.getBytes())
lost its `xss-in-spring-app` finding at ProfileUploadRetrieval.java:114 that way.
A propagator with a **starred** `from` reads through the element's fields and assigns a
plain value, which is exactly the join's semantics. The star has to sit on the pattern
occurrence -- the `from:`/`to:` YAML fields stay starless, like `focus-metavariable`.
Verified: dropping the star loses the shape again; on WebGoat the propagator adds exactly
one finding, the lost one (65 vs 64 results).
Propagators are per-rule, and only `mode: taint` lib rules -- the sink libs -- have the
slot, so this repeats in each sink lib where the helper can appear on a flow.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Saloed
force-pushed
the
misonijnik/3-rules
branch
from
August 19, 2026 22:19
fd0a4b7 to
e9f5c2b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.