2025-06-24 18:53:31 +02:00
|
|
|
use crate::patterns::{Pattern, Severity};
|
|
|
|
|
pub const PATTERNS: &[Pattern] = &[
|
2025-06-24 20:27:06 +02:00
|
|
|
// ---------- Runtime code-execution primitives ----------
|
|
|
|
|
Pattern {
|
|
|
|
|
id: "eval_call",
|
|
|
|
|
description: "Kernel#eval usage",
|
|
|
|
|
query: r#"
|
2025-06-24 18:53:31 +02:00
|
|
|
(call
|
|
|
|
|
(identifier) @id
|
|
|
|
|
(#eq? @id "eval")
|
|
|
|
|
) @vuln
|
|
|
|
|
"#,
|
2025-06-24 20:27:06 +02:00
|
|
|
severity: Severity::High,
|
|
|
|
|
},
|
|
|
|
|
Pattern {
|
|
|
|
|
id: "instance_eval_call",
|
|
|
|
|
description: "Object#instance_eval usage",
|
|
|
|
|
query: r#"
|
2025-06-24 18:53:31 +02:00
|
|
|
(call
|
|
|
|
|
(identifier) @id
|
|
|
|
|
(#eq? @id "instance_eval")
|
|
|
|
|
) @vuln
|
|
|
|
|
"#,
|
2025-06-24 20:27:06 +02:00
|
|
|
severity: Severity::High,
|
|
|
|
|
},
|
|
|
|
|
Pattern {
|
|
|
|
|
id: "class_eval_call",
|
|
|
|
|
description: "Module#class_eval / module_eval usage",
|
|
|
|
|
query: r#"
|
2025-06-24 18:53:31 +02:00
|
|
|
(call
|
|
|
|
|
(identifier) @id
|
|
|
|
|
(#match? @id "^(class_eval|module_eval)$")
|
|
|
|
|
) @vuln
|
|
|
|
|
"#,
|
2025-06-24 20:27:06 +02:00
|
|
|
severity: Severity::High,
|
|
|
|
|
},
|
|
|
|
|
// ---------- Shell execution ----------
|
|
|
|
|
Pattern {
|
|
|
|
|
id: "system_exec_interp",
|
|
|
|
|
description: "system/exec with string interpolation",
|
|
|
|
|
query: r#"
|
2025-06-24 18:53:31 +02:00
|
|
|
(call
|
|
|
|
|
method: (identifier) @m
|
|
|
|
|
(#match? @m "^(system|exec)$")
|
|
|
|
|
arguments: (argument_list
|
|
|
|
|
(string
|
|
|
|
|
(interpolation)+ @vuln
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
"#,
|
2025-06-24 20:27:06 +02:00
|
|
|
severity: Severity::High,
|
|
|
|
|
},
|
|
|
|
|
Pattern {
|
|
|
|
|
id: "backtick_command",
|
|
|
|
|
description: "Back-tick shell execution",
|
|
|
|
|
// `uname -a`
|
|
|
|
|
query: r#"(shell_command) @vuln"#,
|
|
|
|
|
severity: Severity::High,
|
|
|
|
|
},
|
|
|
|
|
// ---------- Dangerous deserialisation ----------
|
|
|
|
|
Pattern {
|
|
|
|
|
id: "yaml_load",
|
|
|
|
|
description: "YAML.load / Psych.load (arbitrary object deserialisation)",
|
|
|
|
|
query: r#"
|
2025-06-24 18:53:31 +02:00
|
|
|
(call
|
|
|
|
|
receiver: (constant) @recv
|
|
|
|
|
(#match? @recv "^(YAML|Psych)$")
|
|
|
|
|
method: (identifier) @m
|
|
|
|
|
(#eq? @m "load")
|
|
|
|
|
) @vuln
|
|
|
|
|
"#,
|
2025-06-24 20:27:06 +02:00
|
|
|
severity: Severity::High,
|
|
|
|
|
},
|
|
|
|
|
Pattern {
|
|
|
|
|
id: "marshal_load",
|
|
|
|
|
description: "Marshal.load usage",
|
|
|
|
|
query: r#"
|
2025-06-24 18:53:31 +02:00
|
|
|
(call
|
|
|
|
|
receiver: (constant) @recv
|
|
|
|
|
(#eq? @recv "Marshal")
|
|
|
|
|
method: (identifier) @m
|
|
|
|
|
(#eq? @m "load")
|
|
|
|
|
) @vuln
|
|
|
|
|
"#,
|
2025-06-24 20:27:06 +02:00
|
|
|
severity: Severity::High,
|
|
|
|
|
},
|
|
|
|
|
// ---------- Reflection / meta-programming ----------
|
|
|
|
|
Pattern {
|
|
|
|
|
id: "send_dynamic",
|
|
|
|
|
description: "send() with dynamic first argument (not a literal symbol)",
|
|
|
|
|
query: r#"
|
2025-06-24 18:53:31 +02:00
|
|
|
(call
|
|
|
|
|
method: (identifier) @m
|
|
|
|
|
(#eq? @m "send")
|
|
|
|
|
arguments: (argument_list
|
|
|
|
|
[
|
|
|
|
|
(identifier) ; send(method_name_var, …)
|
|
|
|
|
(string (interpolation)+) ; send("user_#{role}", …)
|
|
|
|
|
] @vuln
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
"#,
|
2025-06-24 20:27:06 +02:00
|
|
|
severity: Severity::Medium,
|
|
|
|
|
},
|
|
|
|
|
Pattern {
|
|
|
|
|
id: "constantize_call",
|
|
|
|
|
description: "ActiveSupport constantize / safe_constantize on tainted data",
|
|
|
|
|
query: r#"
|
2025-06-24 18:53:31 +02:00
|
|
|
(call
|
|
|
|
|
method: (identifier) @m
|
|
|
|
|
(#match? @m "^(constantize|safe_constantize)$")
|
|
|
|
|
) @vuln
|
|
|
|
|
"#,
|
2025-06-24 20:27:06 +02:00
|
|
|
severity: Severity::Medium,
|
|
|
|
|
},
|
|
|
|
|
// ---------- Insecure resource access ----------
|
|
|
|
|
Pattern {
|
|
|
|
|
id: "open_uri_http",
|
|
|
|
|
description: "Kernel#open with HTTP(S) URL (open-uri auto-follow)",
|
|
|
|
|
query: r#"
|
2025-06-24 18:53:31 +02:00
|
|
|
(call
|
|
|
|
|
method: (identifier) @m
|
|
|
|
|
(#eq? @m "open")
|
|
|
|
|
arguments: (argument_list
|
|
|
|
|
(string) @url
|
|
|
|
|
(#match? @url "^\"https?://")
|
|
|
|
|
)
|
|
|
|
|
) @vuln
|
|
|
|
|
"#,
|
2025-06-24 20:27:06 +02:00
|
|
|
severity: Severity::Medium,
|
|
|
|
|
},
|
2025-06-24 18:53:31 +02:00
|
|
|
];
|