mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-16 19:59:26 +00:00
Quick mode had no PHP rules, so a PHP quick scan read the files and reported a plausible zero. ruleset/php/rules.toml adds 13 line/statement rules built on semantic/php.toml's sinks, sources and sanitizers (sql/wpdb, command, code_eval, unserialize, echo, file_inclusion, filesystem, outbound_request, redirect). 9 are enabled and 4 are shadow (sql-call-composition, code-eval, unserialize, xss-echo-input). A rule is shadow when it fired on the corpus but never at a known site. precision_estimate is the measured lower bound. Measured in-sample on the development corpus only (pmpro introduce/repair/benign, population-v1 PHP cases; population-v2 was not read). Known site hit on the vulnerable pin in 4 of 5 cases (LearnPress missed). The hit disappears on the fixed pin for pmpro and YesWiki. Numbers, per-pin files/bytes read and the engine comparison are in benchmarks/measurements/2026-09-30-php-quick-rules/. - fixtures php-vulnerable / php-benign plus manifests: ousast benchmark covers PHP (9/14 reported, 13/14 including shadow; the benign twin records 2 known false alerts) - PHP `#` comments are comments; `#[...]` attributes are not - the alerts task now reports PHP as quick coverage; alerts-engine keeps running the engine for PHP next to the quick rules (ENGINE_ALONGSIDE_QUICK) - other languages' benchmark findings and metrics are unchanged Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
137 lines
2.8 KiB
TOML
137 lines
2.8 KiB
TOML
name = "php-vulnerable"
|
|
language = "php_web"
|
|
frameworks = ["wordpress"]
|
|
setup = []
|
|
modes = ["quick", "standard"]
|
|
known_noise = []
|
|
baselines = []
|
|
|
|
[source]
|
|
type = "local"
|
|
path = "../fixtures/php-vulnerable"
|
|
|
|
[[expected]]
|
|
cwe = "CWE-89"
|
|
class = "sql injection"
|
|
path = "app.php"
|
|
line = 11
|
|
rule_id = "php-wpdb-sql-composition"
|
|
sink = "get_var"
|
|
evidence = "wpdb get_var query concatenates the order code without prepare"
|
|
|
|
[[expected]]
|
|
cwe = "CWE-89"
|
|
class = "sql injection"
|
|
path = "app.php"
|
|
line = 16
|
|
rule_id = "php-sql-call-composition"
|
|
sink = "mysqli_query"
|
|
evidence = "mysqli_query composes the query from request input"
|
|
|
|
[[expected]]
|
|
cwe = "CWE-89"
|
|
class = "sql injection"
|
|
path = "app.php"
|
|
line = 22
|
|
rule_id = "php-sql-unquoted-interpolation"
|
|
sink = "ORDER"
|
|
evidence = "esc_sql value interpolated into an unquoted ORDER BY"
|
|
|
|
[[expected]]
|
|
cwe = "CWE-89"
|
|
class = "sql injection"
|
|
path = "app.php"
|
|
line = 27
|
|
rule_id = "php-sql-unquoted-concat"
|
|
sink = "VALUES"
|
|
evidence = "form id concatenated unquoted into VALUES"
|
|
|
|
[[expected]]
|
|
cwe = "CWE-89"
|
|
class = "sql injection"
|
|
path = "app.php"
|
|
line = 32
|
|
rule_id = "php-sql-sprintf-unescaped"
|
|
sink = "sprintf"
|
|
evidence = "sprintf SQL with an unescaped quoted %s user agent"
|
|
|
|
[[expected]]
|
|
cwe = "CWE-78"
|
|
class = "command injection"
|
|
path = "app.php"
|
|
line = 41
|
|
rule_id = "php-command-injection"
|
|
sink = "system"
|
|
evidence = "system runs a command built from request input"
|
|
|
|
[[expected]]
|
|
cwe = "CWE-95"
|
|
class = "code injection"
|
|
path = "app.php"
|
|
line = 46
|
|
rule_id = "php-code-eval"
|
|
sink = "eval"
|
|
evidence = "eval executes a formula string"
|
|
|
|
[[expected]]
|
|
cwe = "CWE-502"
|
|
class = "insecure deserialization"
|
|
path = "app.php"
|
|
line = 52
|
|
rule_id = "php-unserialize"
|
|
sink = "unserialize"
|
|
evidence = "unserialize of a cookie"
|
|
|
|
[[expected]]
|
|
cwe = "CWE-79"
|
|
class = "cross-site scripting"
|
|
path = "app.php"
|
|
line = 57
|
|
rule_id = "php-xss-echo-input"
|
|
sink = "echo"
|
|
evidence = "request input echoed without escaping"
|
|
|
|
[[expected]]
|
|
cwe = "CWE-98"
|
|
class = "file inclusion"
|
|
path = "app.php"
|
|
line = 62
|
|
rule_id = "php-file-inclusion-input"
|
|
sink = "include"
|
|
evidence = "include of a request-chosen path"
|
|
|
|
[[expected]]
|
|
cwe = "CWE-22"
|
|
class = "path traversal"
|
|
path = "app.php"
|
|
line = 67
|
|
rule_id = "php-path-input"
|
|
sink = "readfile"
|
|
evidence = "readfile of a request-chosen path"
|
|
|
|
[[expected]]
|
|
cwe = "CWE-918"
|
|
class = "server-side request forgery"
|
|
path = "app.php"
|
|
line = 72
|
|
rule_id = "php-ssrf-input"
|
|
sink = "curl_init"
|
|
evidence = "curl request to a request-chosen URL"
|
|
|
|
[[expected]]
|
|
cwe = "CWE-601"
|
|
class = "open redirect"
|
|
path = "app.php"
|
|
line = 78
|
|
rule_id = "php-open-redirect"
|
|
sink = "header"
|
|
evidence = "Location header from request input"
|
|
|
|
[[expected]]
|
|
cwe = "CWE-89"
|
|
class = "sql injection"
|
|
path = "app.php"
|
|
line = 86
|
|
sink = "mysqli_query"
|
|
evidence = "query built from a request value on an earlier line (not visible to a line rule)"
|