Repository navigation
Expand file tree
/
Copy pathvalidate_security_skill.sh
More file actions
executable file
·142 lines (128 loc) · 4.39 KB
/
Copy pathvalidate_security_skill.sh
File metadata and controls
executable file
·142 lines (128 loc) · 4.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/usr/bin/env bash
set -euo pipefail
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
failures=0
fail() {
echo "FAIL: $*"
failures=$((failures + 1))
}
pass() {
echo "PASS: $*"
}
require_file() {
local path="$1"
if [[ -f "$root/$path" ]]; then
pass "$path exists"
else
fail "$path missing"
fi
}
required_files=(
"SKILL.md"
"README.md"
"README.en.md"
"LICENSE"
"USAGE.zh-en.md"
"agents/openai.yaml"
"references/severity-and-release-gates.md"
"references/web-api-security.md"
"references/auth-permissions.md"
"references/secrets-privacy.md"
"references/files-oss.md"
"references/payment-wechat.md"
"references/mobile-hardening.md"
"references/ai-prompt-injection.md"
"scripts/scan_secrets.sh"
"scripts/scan_dangerous_patterns.sh"
"scripts/security_report.sh"
"examples/security-review-sample.md"
"examples/vulnerable-snippets.md"
"examples/security-report-demo.md"
"assets/demo/security-report-demo.html"
"examples/test-prompts.json"
)
for file in "${required_files[@]}"; do
require_file "$file"
done
if ruby -ryaml -e '
path = ARGV.fetch(0)
text = File.read(path)
abort "missing frontmatter" unless text.start_with?("---")
match = text.match(/\A---\n(.*?)\n---/m) or abort "invalid frontmatter"
yaml = YAML.safe_load(match[1])
abort "frontmatter is not a map" unless yaml.is_a?(Hash)
abort "bad name" unless yaml["name"] == "security-skill"
desc = yaml["description"].to_s
abort "description too short" unless desc.length >= 120
abort "description too long" unless desc.length <= 1024
abort "angle brackets in description" if desc.include?("<") || desc.include?(">")
' "$root/SKILL.md"; then
pass "SKILL.md frontmatter is valid"
else
fail "SKILL.md frontmatter is invalid"
fi
if ! rg -n 'TODO|FIXME|\[TODO\]' "$root/SKILL.md" "$root/references" "$root/README.md" "$root/README.en.md" >/tmp/security-skill-todos.$$ 2>/dev/null; then
pass "no TODO markers in release-facing docs"
else
cat /tmp/security-skill-todos.$$
fail "TODO markers found"
fi
rm -f /tmp/security-skill-todos.$$
if "$root/scripts/scan_secrets.sh" "$root" >/tmp/security-skill-secrets.$$ 2>&1; then
fail "secret scanner found unexpected results"
cat /tmp/security-skill-secrets.$$
else
code=$?
if [[ "$code" -eq 1 ]]; then
pass "secret scanner found no obvious secrets"
else
fail "secret scanner failed with exit code $code"
cat /tmp/security-skill-secrets.$$
fi
fi
rm -f /tmp/security-skill-secrets.$$
if "$root/scripts/scan_dangerous_patterns.sh" "$root/examples/vulnerable-snippets.md" >/tmp/security-skill-patterns.$$ 2>&1; then
fail "dangerous pattern scanner did not flag vulnerable snippets"
else
code=$?
if [[ "$code" -eq 1 ]]; then
pass "dangerous pattern scanner flags vulnerable snippets"
else
fail "dangerous pattern scanner failed with exit code $code"
cat /tmp/security-skill-patterns.$$
fi
fi
rm -f /tmp/security-skill-patterns.$$
if "$root/scripts/security_report.sh" "$root/examples/vulnerable-snippets.md" /tmp/security-skill-report.$$.md >/tmp/security-skill-report.$$.out 2>&1; then
fail "security report did not flag vulnerable snippets"
else
code=$?
if [[ "$code" -eq 1 ]] && rg -q 'Conclusion: \*\*阻止上线\*\*|Possible SQL Injection|Possible XSS|JWT or Auth Risk|Upload Risk' /tmp/security-skill-report.$$.md; then
pass "security report flags vulnerable snippets and writes markdown"
else
fail "security report failed with exit code $code"
cat /tmp/security-skill-report.$$.out
[[ -f /tmp/security-skill-report.$$.md ]] && cat /tmp/security-skill-report.$$.md
fi
fi
rm -f /tmp/security-skill-report.$$.out /tmp/security-skill-report.$$.md
if ruby -rjson -e '
data = JSON.parse(File.read(ARGV.fetch(0)))
abort "expected array" unless data.is_a?(Array)
abort "need at least 4 prompts" unless data.length >= 4
data.each do |item|
abort "missing id" unless item["id"].is_a?(String) && item["id"].length > 0
abort "missing prompt" unless item["prompt"].is_a?(String) && item["prompt"].include?("$security-skill")
abort "missing expected" unless item["expected"].is_a?(Array) && item["expected"].length > 0
end
' "$root/examples/test-prompts.json"; then
pass "test prompts are valid"
else
fail "test prompts are invalid"
fi
if [[ "$failures" -eq 0 ]]; then
echo "Security skill validation passed."
exit 0
fi
echo "Security skill validation failed with $failures issue(s)."
exit 1