use crate::evidence::Confidence;
use crate::patterns::{Pattern, PatternCategory, PatternTier, Severity};
pub const PATTERNS: &[Pattern] = &[
Pattern {
id: "php.code_exec.eval",
description: "eval() runs dynamic code",
query: r#"(function_call_expression
function: (name) @n (#eq? @n "eval"))
@vuln"#,
severity: Severity::High,
tier: PatternTier::A,
category: PatternCategory::CodeExec,
confidence: Confidence::High,
},
Pattern {
id: "php.code_exec.create_function",
description: "create_function() is a deprecated eval-like constructor",
query: r#"(function_call_expression
function: (name) @n (#eq? @n "create_function"))
@vuln"#,
severity: Severity::High,
tier: PatternTier::A,
category: PatternCategory::CodeExec,
confidence: Confidence::High,
},
Pattern {
id: "php.code_exec.preg_replace_e",
description: "preg_replace with /e modifier executes code via regex",
query: r#"(function_call_expression
function: (name) @n (#eq? @n "preg_replace")
arguments: (arguments
(argument
(string) @pat (#match? @pat "/[^/]*/[a-zA-Z]*e"))))
@vuln"#,
severity: Severity::High,
tier: PatternTier::A,
category: PatternCategory::CodeExec,
confidence: Confidence::High,
},
Pattern {
id: "php.code_exec.assert_string",
description: "assert() with a string argument evaluates PHP code",
query: r#"(function_call_expression
function: (name) @n (#eq? @n "assert")
arguments: (arguments
(argument (string) @code)))
@vuln"#,
severity: Severity::High,
tier: PatternTier::A,
category: PatternCategory::CodeExec,
confidence: Confidence::High,
},
Pattern {
id: "php.cmdi.system",
description: "system/shell_exec/exec/passthru runs a shell command",
query: r#"(function_call_expression
function: (name) @n (#match? @n "^(system|shell_exec|exec|passthru|proc_open|popen)$"))
@vuln"#,
severity: Severity::High,
tier: PatternTier::A,
category: PatternCategory::CommandExec,
confidence: Confidence::High,
},
Pattern {
id: "php.deser.unserialize",
description: "unserialize() enables PHP object injection",
query: r#"(function_call_expression
function: (name) @n (#eq? @n "unserialize"))
@vuln"#,
severity: Severity::High,
tier: PatternTier::A,
category: PatternCategory::Deserialization,
confidence: Confidence::High,
},
Pattern {
id: "php.sqli.query_concat",
description: "mysql_query/mysqli_query with concatenated SQL string",
query: r#"(function_call_expression
function: (name) @n (#match? @n "^(mysql_query|mysqli_query)$")
arguments: (arguments
(argument (binary_expression) @concat)))
@vuln"#,
severity: Severity::Medium,
tier: PatternTier::B,
category: PatternCategory::SqlInjection,
confidence: Confidence::Medium,
},
Pattern {
id: "php.path.include_variable",
description: "include/require with a variable path is a file-inclusion vulnerability",
query: r#"(include_expression (variable_name)) @vuln"#,
severity: Severity::High,
tier: PatternTier::B,
category: PatternCategory::PathTraversal,
confidence: Confidence::Medium,
},
Pattern {
id: "php.crypto.md5",
description: "md5() is a weak hash function",
query: r#"(function_call_expression
function: (name) @n (#eq? @n "md5"))
@vuln"#,
severity: Severity::Low,
tier: PatternTier::A,
category: PatternCategory::Crypto,
confidence: Confidence::Medium,
},
Pattern {
id: "php.crypto.sha1",
description: "sha1() is a weak hash function",
query: r#"(function_call_expression
function: (name) @n (#eq? @n "sha1"))
@vuln"#,
severity: Severity::Low,
tier: PatternTier::A,
category: PatternCategory::Crypto,
confidence: Confidence::Medium,
},
Pattern {
id: "php.crypto.rand",
description: "rand()/mt_rand() is not cryptographically secure",
query: r#"(function_call_expression
function: (name) @n (#match? @n "^(rand|mt_rand)$"))
@vuln"#,
severity: Severity::Low,
tier: PatternTier::A,
category: PatternCategory::Crypto,
confidence: Confidence::Medium,
},
];