mirror of
https://github.com/aaif-goose/goose.git
synced 2026-06-01 22:09:18 +02:00
Prompt injection mitigation: update pattern-based detection (#9198)
This commit is contained in:
committed by
GitHub
parent
c89bf0c30c
commit
826cce0257
@@ -54,9 +54,9 @@ pub const THREAT_PATTERNS: &[ThreatPattern] = &[
|
||||
category: ThreatCategory::FileSystemDestruction,
|
||||
},
|
||||
ThreatPattern {
|
||||
name: "rm_rf_system",
|
||||
pattern: r"rm\s+(-[rf]*[rf][rf]*|--recursive|--force)\s+[^\s;|&]*/?(bin|etc|usr|var|sys|proc|dev|boot|lib|opt|srv)(?:/|\s|[;&|]|$)",
|
||||
description: "Recursive deletion of system directories",
|
||||
name: "rm_rf_home_or_root",
|
||||
pattern: r"rm\s+((--[a-zA-Z][a-zA-Z\-]*|--|-[a-zA-Z]+)\s+)*(-[a-zA-Z]*[rR][a-zA-Z]*|--recursive|--dir|-d)(\s+(--[a-zA-Z][a-zA-Z\-]*|--|-[a-zA-Z]+))*\s+['\x22]?(~|\$HOME|\$\{HOME\}|/home|/root)/?(\*)?['\x22]?(\s|[;&|]|$)",
|
||||
description: "Recursive deletion of home or root directory",
|
||||
risk_level: RiskLevel::Critical,
|
||||
category: ThreatCategory::FileSystemDestruction,
|
||||
},
|
||||
@@ -242,14 +242,6 @@ pub const THREAT_PATTERNS: &[ThreatPattern] = &[
|
||||
risk_level: RiskLevel::Medium,
|
||||
category: ThreatCategory::CommandInjection,
|
||||
},
|
||||
ThreatPattern {
|
||||
name: "alternative_shell_invocation",
|
||||
pattern: r"(/bin/|/usr/bin/|\./)?(bash|sh|zsh|fish|csh|tcsh|dash)\s+-c\s+.*[;&|]",
|
||||
description: "Alternative shell invocation patterns",
|
||||
risk_level: RiskLevel::Medium,
|
||||
category: ThreatCategory::CommandInjection,
|
||||
},
|
||||
// Additional dangerous commands that might be missing
|
||||
ThreatPattern {
|
||||
name: "docker_privileged_exec",
|
||||
pattern: r"docker\s+(run|exec).*--privileged",
|
||||
@@ -280,7 +272,7 @@ pub const THREAT_PATTERNS: &[ThreatPattern] = &[
|
||||
},
|
||||
ThreatPattern {
|
||||
name: "log_manipulation",
|
||||
pattern: r"(>\s*/dev/null|truncate.*log|rm.*\.log|echo\s*>\s*/var/log)",
|
||||
pattern: r"(truncate.*log|rm\s+((--[a-zA-Z][a-zA-Z\-]*|--|-[a-zA-Z]+)\s+)*/var/log(/|\s|[;&|]|$)|echo\s*>\s*/var/log)",
|
||||
description: "Log file manipulation or deletion",
|
||||
risk_level: RiskLevel::Medium,
|
||||
category: ThreatCategory::SystemModification,
|
||||
@@ -418,18 +410,80 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rm_rf_system_matches_absolute_and_relative() {
|
||||
let pat = "rm_rf_system";
|
||||
assert!(matches(pat, "rm -rf /etc"));
|
||||
assert!(matches(pat, "rm -rf /usr/bin"));
|
||||
assert!(matches(pat, "rm -rf etc"));
|
||||
assert!(matches(pat, "rm -rf var"));
|
||||
fn rm_rf_home_or_root_matches_bare_targets() {
|
||||
let pat = "rm_rf_home_or_root";
|
||||
assert!(matches(pat, "rm -rf ~"));
|
||||
assert!(matches(pat, "rm -rf ~/"));
|
||||
assert!(matches(pat, "rm -rf $HOME"));
|
||||
assert!(matches(pat, "rm -rf $HOME/"));
|
||||
assert!(matches(pat, "rm -rf ${HOME}"));
|
||||
assert!(matches(pat, r#"rm -rf "${HOME}""#));
|
||||
assert!(matches(pat, "rm -rf /home"));
|
||||
assert!(matches(pat, "rm -rf /home/"));
|
||||
assert!(matches(pat, "rm -rf /root"));
|
||||
assert!(matches(pat, "rm -rf /root/"));
|
||||
assert!(matches(pat, "rm -fr ~"));
|
||||
assert!(matches(pat, "rm --recursive --force ~"));
|
||||
assert!(matches(pat, r#"rm -rf "$HOME""#));
|
||||
assert!(matches(pat, "rm -rf ~; echo done"));
|
||||
// Wildcard wipes of contents
|
||||
assert!(matches(pat, "rm -rf /home/*"));
|
||||
assert!(matches(pat, "rm -rf /root/*"));
|
||||
assert!(matches(pat, "rm -rf ~/*"));
|
||||
assert!(matches(pat, "rm -rf ${HOME}/*"));
|
||||
assert!(matches(pat, r#"rm -rf "/home/*""#));
|
||||
// Extra flags and option separator
|
||||
assert!(matches(pat, "rm -rfv ~"));
|
||||
assert!(matches(pat, "rm -rf -- ~"));
|
||||
assert!(matches(pat, "rm --recursive --force -- /home/*"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rm_rf_system_no_false_positives() {
|
||||
let pat = "rm_rf_system";
|
||||
assert!(!matches(pat, "rm -rf ./etc-backup"));
|
||||
fn rm_rf_home_or_root_no_false_positives_on_subdirs() {
|
||||
let pat = "rm_rf_home_or_root";
|
||||
assert!(!matches(pat, "rm -rf ~/Documents/my-gh-repo"));
|
||||
assert!(!matches(pat, "rm -rf ~/.cache"));
|
||||
assert!(!matches(pat, "rm -rf $HOME/build"));
|
||||
assert!(!matches(pat, "rm -rf ${HOME}/build"));
|
||||
assert!(!matches(pat, "rm -rf ${HOMEDIR}"));
|
||||
assert!(!matches(pat, "rm -rf /home/user"));
|
||||
assert!(!matches(pat, "rm -rf /home/user/project"));
|
||||
assert!(!matches(pat, "rm -rf /root/tmp"));
|
||||
assert!(!matches(pat, "rm -rf ./home"));
|
||||
assert!(!matches(pat, "rm -rf $HOMEDIR"));
|
||||
// Wildcards inside subdirs should not match
|
||||
assert!(!matches(pat, "rm -rf /home/user/*"));
|
||||
assert!(!matches(pat, "rm -rf ~/Documents/*"));
|
||||
// Flags that cannot recursively remove directories should not fire
|
||||
assert!(!matches(pat, "rm -i /root"));
|
||||
assert!(!matches(pat, "rm -f ~"));
|
||||
assert!(!matches(pat, "rm --force ~"));
|
||||
assert!(!matches(pat, "rm --help ~"));
|
||||
assert!(!matches(pat, "rm -v ~"));
|
||||
assert!(!matches(pat, "rm -- ~"));
|
||||
assert!(!matches(pat, "rm ~"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn log_manipulation_no_dev_null_false_positives() {
|
||||
let pat = "log_manipulation";
|
||||
// Standard stderr suppression should NOT match
|
||||
assert!(!matches(pat, "ls 2>/dev/null"));
|
||||
assert!(!matches(pat, "rm -f /tmp/file 2>/dev/null"));
|
||||
assert!(!matches(pat, "command > /dev/null 2>&1"));
|
||||
// Actual log tampering should still match
|
||||
assert!(matches(pat, "truncate -s 0 /var/log/auth.log"));
|
||||
assert!(matches(pat, "echo > /var/log/syslog"));
|
||||
assert!(matches(pat, "rm -f /var/log/auth.log"));
|
||||
assert!(matches(pat, "rm -rf /var/log/syslog"));
|
||||
assert!(matches(pat, "rm -fr /var/log/auth.log"));
|
||||
assert!(matches(pat, "rm -rf /var/log"));
|
||||
assert!(matches(pat, "rm --recursive --force /var/log/auth.log"));
|
||||
assert!(matches(pat, "rm --recursive /var/log"));
|
||||
assert!(matches(pat, "rm -rf -- /var/log/auth.log"));
|
||||
assert!(matches(pat, "rm -rfv /var/log/auth.log"));
|
||||
// Similar-looking paths outside /var/log should NOT match
|
||||
assert!(!matches(pat, "rm -rf /var/log-backup"));
|
||||
assert!(!matches(pat, "rm -rf /var/logs"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user