skilllite_core/skill/
skill_md_security.rs1#[derive(Debug, Clone, serde::Serialize)]
6pub struct SkillMdAlert {
7 pub pattern: String,
8 pub severity: String,
9 pub message: String,
10}
11
12pub fn scan_skill_md_suspicious_patterns(content: &str) -> Vec<SkillMdAlert> {
15 let mut alerts = Vec::new();
16 let lower = content.to_lowercase();
17
18 if lower.contains("| bash") || lower.contains("|bash") {
20 alerts.push(SkillMdAlert {
21 pattern: "| bash".to_string(),
22 severity: "high".to_string(),
23 message: "SKILL.md contains '| bash' - may instruct user to run remote script"
24 .to_string(),
25 });
26 }
27 if lower.contains("| sh") && !lower.contains("#!/bin/sh") {
28 alerts.push(SkillMdAlert {
29 pattern: "| sh".to_string(),
30 severity: "high".to_string(),
31 message: "SKILL.md contains '| sh' - may instruct user to run remote script"
32 .to_string(),
33 });
34 }
35 if lower.contains("base64 -d") || lower.contains("base64 -D") {
36 alerts.push(SkillMdAlert {
37 pattern: "base64 -d/-D".to_string(),
38 severity: "high".to_string(),
39 message: "SKILL.md contains base64 decode - common in obfuscated payload delivery"
40 .to_string(),
41 });
42 }
43
44 if lower.contains("rentry.co") || lower.contains("pastebin.com") {
46 alerts.push(SkillMdAlert {
47 pattern: "pastebin/rentry".to_string(),
48 severity: "high".to_string(),
49 message: "SKILL.md links to pastebin/rentry - often used to host second-stage payloads"
50 .to_string(),
51 });
52 }
53
54 for (pattern, msg) in [
56 (
57 "run in terminal",
58 "Instructions to run command in user terminal",
59 ),
60 (
61 "copy and paste",
62 "Instructions to copy-paste command (social engineering)",
63 ),
64 ("copy and run", "Instructions to copy and run command"),
65 ("run this command", "Direct instruction to run a command"),
66 (
67 "execute this command",
68 "Direct instruction to execute a command",
69 ),
70 ("在终端运行", "Instructions to run in terminal (Chinese)"),
71 ("复制并执行", "Instructions to copy and execute (Chinese)"),
72 ] {
73 if lower.contains(pattern) {
74 alerts.push(SkillMdAlert {
75 pattern: pattern.to_string(),
76 severity: "medium".to_string(),
77 message: format!("SKILL.md contains '{}' - {}", pattern, msg),
78 });
79 }
80 }
81
82 let in_prereq_or_setup =
84 lower.contains("prerequisite") || lower.contains("setup") || lower.contains("install");
85 if in_prereq_or_setup && (lower.contains("curl ") || lower.contains("wget ")) {
86 alerts.push(SkillMdAlert {
87 pattern: "curl/wget in prereq".to_string(),
88 severity: "medium".to_string(),
89 message: "SKILL.md mentions curl/wget in prerequisites/setup - verify before following"
90 .to_string(),
91 });
92 }
93
94 alerts
95}
96
97pub fn has_skill_md_high_risk_patterns(content: &str) -> bool {
99 scan_skill_md_suspicious_patterns(content)
100 .iter()
101 .any(|a| a.severity == "high")
102}