mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-16 03:49:26 +00:00
fix(taint): a value stored while its guard held stays guarded
Ultimate Member's fixed pin kept one alert. The fix writes
`$this->sql_order = " ORDER BY u.{$sortby} "` inside
`elseif (in_array($sortby, $allowed, true))`, and after the if/elseif chain it
passes the field through `apply_filters(...)` into a second assignment. The guard
was judged only at the flow's final node, which is outside the branch.
A guard is now also judged at every point where the path stores the value (an
assignment target). A value stored while the check held carries the check forward,
because the rest of the path derives from that store. A mere read inside a branch
is not a candidate: the engine lists uses in branches the flow does not depend on.
The Joern-gated test gains the shape and its control: the same store in the
unguarded else branch, through the same filter, is still reported. The test fails
when only the end is judged.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
03f2ce7162
commit
69d4a8626f
@@ -1391,15 +1391,26 @@ def test_an_allowlist_check_guards_its_branch_and_its_ternary_arm(tmp_path: Path
|
||||
"function else_branch() { global $wpdb; $s = $_POST['s']; $core = array( 'login' );\n"
|
||||
" if ( in_array( $s, $core, true ) ) { return null; }\n"
|
||||
' else { return $wpdb->query( "SELECT 1 FROM t ORDER BY u.{$s}" ); } }\n'
|
||||
"function stored_in_branch() { global $wpdb; $s = $_POST['s']; $core = array( 'login' ); $o = '';\n"
|
||||
' if ( in_array( $s, $core, true ) ) { $o = " ORDER BY u.{$s} "; }\n'
|
||||
" $o = apply_filters( 'sort', $o, $s );\n"
|
||||
' return $wpdb->query( "SELECT 1 FROM t {$o}" ); }\n'
|
||||
"function stored_in_else() { global $wpdb; $s = $_POST['s']; $core = array( 'login' ); $o = '';\n"
|
||||
" if ( in_array( $s, $core, true ) ) { $o = ' ORDER BY u.login '; }\n"
|
||||
' else { $o = " ORDER BY u.{$s} "; }\n'
|
||||
" $o = apply_filters( 'sort', $o, $s );\n"
|
||||
' return $wpdb->query( "SELECT 1 FROM t {$o}" ); }\n'
|
||||
)
|
||||
names = ("ternary", "wrong_arm", "branch", "else_branch")
|
||||
names = ("ternary", "wrong_arm", "branch", "else_branch", "stored_in_branch", "stored_in_else")
|
||||
common = {
|
||||
"sources": ",".join(spec.sources),
|
||||
"sinks": ",".join(spec.sinks),
|
||||
"sanitizers": ",".join(spec.sanitizers),
|
||||
"guards": ",".join(spec.guards),
|
||||
"dispatchApply": ",".join(spec.dispatch_apply),
|
||||
"dispatchValue": ",".join(spec.dispatch_value),
|
||||
"file": "app.php",
|
||||
}
|
||||
payload = _taint_rows(tmp_path, "php2cpg", {"app.php": app}, {n: {**common, "function": n} for n in names})
|
||||
reported = {n for n in names if _unsanitized(payload, n)}
|
||||
assert reported == {"wrong_arm", "else_branch"}, {n: payload[n] for n in names}
|
||||
assert reported == {"wrong_arm", "else_branch", "stored_in_else"}, {n: payload[n] for n in names}
|
||||
|
||||
Reference in New Issue
Block a user