Summary
Rule authors who compose join-mode rules must enumerate every referenced library rule individually, by exact file path and rule id. There is no way to group related library rules (for example, "all untrusted-data sources") and pull them into a join by a single logical name. This request adds an optional set of tags to rule definitions and lets a join ref target a tag (- tag: <name>) as an alternative to - rule: <path>#<id>. A tag ref expands to every rule that carries that tag, so adding a new source or sink becomes a one-line change on that rule instead of an edit to every join rule that should include it.
Problem
A mode: join rule today references each component rule explicitly. When a vulnerability draws from more than one source (or sink) family, the author repeats the same shape for every component: one ref with its own as: alias, plus one line in the on: section per alias.
Concrete example — ruleset/java/security/ssrf.yaml already pulls untrusted data from both a servlet source and a Spring source:
mode: join
join:
refs:
- rule: java/lib/generic/servlet-untrusted-data-source.yaml#java-servlet-untrusted-data-source
as: servlet-untrusted-data
- rule: java/lib/spring/untrusted-data-source.yaml#spring-untrusted-data-source
as: spring-untrusted-data
- rule: java/lib/generic/ssrf-sinks.yaml#java-ssrf-sink
as: sink
on:
- 'servlet-untrusted-data.$UNTRUSTED -> sink.$UNTRUSTED'
- 'spring-untrusted-data.$UNTRUSTED -> sink.$UNTRUSTED'
## Notes
### Desired outcome
1. **Tags on rules.** A rule definition may declare one or more tags, e.g.:
```yaml
rules:
- id: java-servlet-untrusted-data-source
options:
lib: true
tags:
- untrusted-data-source
...
Tags are author-defined logical groupings (e.g. untrusted-data-source, ssrf-sink). A rule may carry several tags; a tag may be shared by many rules across files.
-
Tag refs in join mode. Inside join.refs, an entry may use - tag: <name> in place of - rule: <path>#<id>. A tag ref expands to all rules carrying that tag, bound to a single alias:
mode: join
join:
refs:
- tag: untrusted-data-source
as: untrusted-data
- rule: java/lib/generic/ssrf-sinks.yaml#java-ssrf-sink
as: sink
on:
- 'untrusted-data.$UNTRUSTED -> sink.$UNTRUSTED'
The alias untrusted-data now stands for the union of every tagged source, so the single on: line covers all of them. Adding a new source later only requires tagging that source rule with untrusted-data-source; every join that references the tag picks it up automatically, with no edits to the join rules.
-
- rule and - tag coexist. A single join may mix explicit - rule refs and - tag refs. Existing rules using only - rule continue to work unchanged (fully backward compatible).
Summary
Rule authors who compose join-mode rules must enumerate every referenced library rule individually, by exact file path and rule id. There is no way to group related library rules (for example, "all untrusted-data sources") and pull them into a join by a single logical name. This request adds an optional set of tags to rule definitions and lets a join
reftarget a tag (- tag: <name>) as an alternative to- rule: <path>#<id>. A tag ref expands to every rule that carries that tag, so adding a new source or sink becomes a one-line change on that rule instead of an edit to every join rule that should include it.Problem
A
mode: joinrule today references each component rule explicitly. When a vulnerability draws from more than one source (or sink) family, the author repeats the same shape for every component: onerefwith its ownas:alias, plus one line in theon:section per alias.Concrete example —
ruleset/java/security/ssrf.yamlalready pulls untrusted data from both a servlet source and a Spring source:Tags are author-defined logical groupings (e.g.
untrusted-data-source,ssrf-sink). A rule may carry several tags; a tag may be shared by many rules across files.Tag refs in join mode. Inside
join.refs, an entry may use- tag: <name>in place of- rule: <path>#<id>. A tag ref expands to all rules carrying that tag, bound to a single alias:The alias
untrusted-datanow stands for the union of every tagged source, so the singleon:line covers all of them. Adding a new source later only requires tagging that source rule withuntrusted-data-source; every join that references the tag picks it up automatically, with no edits to the join rules.- ruleand- tagcoexist. A single join may mix explicit- rulerefs and- tagrefs. Existing rules using only- rulecontinue to work unchanged (fully backward compatible).