use crate::evidence::Confidence;
use crate::patterns::{Pattern, PatternCategory, PatternTier, Severity};
pub const PATTERNS: &[Pattern] = &[
Pattern {
id: "c.memory.gets",
description: "gets() has no bounds checking and is always exploitable",
query: r#"(call_expression function: (identifier) @id (#eq? @id "gets")) @vuln"#,
severity: Severity::High,
tier: PatternTier::A,
category: PatternCategory::MemorySafety,
confidence: Confidence::High,
},
Pattern {
id: "c.memory.strcpy",
description: "strcpy() does not bounds-check the destination buffer",
query: r#"(call_expression function: (identifier) @id (#eq? @id "strcpy")) @vuln"#,
severity: Severity::High,
tier: PatternTier::A,
category: PatternCategory::MemorySafety,
confidence: Confidence::High,
},
Pattern {
id: "c.memory.strcat",
description: "strcat() does not bounds-check the destination buffer",
query: r#"(call_expression function: (identifier) @id (#eq? @id "strcat")) @vuln"#,
severity: Severity::High,
tier: PatternTier::A,
category: PatternCategory::MemorySafety,
confidence: Confidence::High,
},
Pattern {
id: "c.memory.sprintf",
description: "sprintf() does not limit the output buffer length",
query: r#"(call_expression function: (identifier) @id (#eq? @id "sprintf")) @vuln"#,
severity: Severity::High,
tier: PatternTier::A,
category: PatternCategory::MemorySafety,
confidence: Confidence::High,
},
Pattern {
id: "c.memory.scanf_percent_s",
description: "scanf(\"%s\") performs an unbounded string read",
query: r#"(call_expression
function: (identifier) @id (#eq? @id "scanf")
arguments: (argument_list
(string_literal) @fmt (#match? @fmt "%s")))
@vuln"#,
severity: Severity::High,
tier: PatternTier::A,
category: PatternCategory::MemorySafety,
confidence: Confidence::High,
},
Pattern {
id: "c.cmdi.system",
description: "system() runs a shell command",
query: r#"(call_expression function: (identifier) @id (#eq? @id "system")) @vuln"#,
severity: Severity::High,
tier: PatternTier::A,
category: PatternCategory::CommandExec,
confidence: Confidence::High,
},
Pattern {
id: "c.cmdi.popen",
description: "popen() runs a shell command and returns a pipe",
query: r#"(call_expression function: (identifier) @id (#eq? @id "popen")) @vuln"#,
severity: Severity::Medium,
tier: PatternTier::A,
category: PatternCategory::CommandExec,
confidence: Confidence::High,
},
Pattern {
id: "c.memory.printf_no_fmt",
description: "printf(var) is a format-string vulnerability when the first arg is not a literal",
query: r#"(call_expression
function: (identifier) @id (#eq? @id "printf")
arguments: (argument_list
. (identifier) @arg))
@vuln"#,
severity: Severity::High,
tier: PatternTier::B,
category: PatternCategory::MemorySafety,
confidence: Confidence::Medium,
},
];