feat(ssa): optimize branch condition handling via constant folding, enhance precision for taint analysis, and expand OWASP Benchmark support

This commit is contained in:
elipeter 2026-06-02 13:41:45 -05:00
parent ec76c9e08f
commit 9c99f6c6a9
22 changed files with 1020 additions and 17 deletions

View file

@ -124,6 +124,23 @@ pub static RULES: &[LabelRule] = &[
label: DataLabel::Sink(Cap::SHELL_ESCAPE),
case_sensitive: false,
},
// `ProcessBuilder.command(argList)` — the dominant OWASP Benchmark
// command-injection shape builds an argument `List<String>`, attaches it
// via `pb.command(argList)`, then runs `pb.start()`. The argument list is
// a separate channel from the constructor, so the flat `ProcessBuilder`
// constructor sink above never sees the tainted args. This rule fires
// only via type-qualified resolution: the receiver `pb` must carry a
// `TypeKind::ProcessBuilder` fact (set by `constructor_type` for
// `new ProcessBuilder(...)`), so the resolver rewrites `pb.command(...)` →
// `ProcessBuilder.command`. Case-sensitive and receiver-typed to avoid
// colliding with the many unrelated `.command(...)` methods (CLI builders,
// JCommander, picocli, Swing actions). The payload is restricted to arg 0
// (the command list) via `type_qualified_sink_payload_args`.
LabelRule {
matchers: &["ProcessBuilder.command"],
label: DataLabel::Sink(Cap::SHELL_ESCAPE),
case_sensitive: true,
},
LabelRule {
matchers: &["executeQuery", "executeUpdate"],
label: DataLabel::Sink(Cap::SQL_QUERY),

View file

@ -1496,7 +1496,11 @@ pub fn type_qualified_sink_payload_args(qualified_callee: &str) -> Option<&'stat
| "TypeOrmRepo.createQueryBuilder"
| "TypeOrmManager.query"
| "TypeOrmManager.createQueryBuilder"
| "MikroOrmEm.execute" => Some(&[0]),
| "MikroOrmEm.execute"
// `ProcessBuilder.command(argList)` — arg 0 is the command list;
// any later positional args are not part of the v1 shape. Restrict
// sink-taint scanning to arg 0 so receiver / unrelated args don't fire.
| "ProcessBuilder.command" => Some(&[0]),
_ => None,
}
}