cisco-ai-skill-scanner 1.0.0__py3-none-any.whl → 1.0.2__py3-none-any.whl
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.
- {cisco_ai_skill_scanner-1.0.0.dist-info → cisco_ai_skill_scanner-1.0.2.dist-info}/METADATA +28 -13
- cisco_ai_skill_scanner-1.0.2.dist-info/RECORD +102 -0
- cisco_ai_skill_scanner-1.0.2.dist-info/entry_points.txt +4 -0
- {skillanalyzer → skill_scanner}/__init__.py +8 -4
- {skillanalyzer → skill_scanner}/_version.py +2 -2
- {skillanalyzer → skill_scanner}/api/__init__.py +1 -1
- {skillanalyzer → skill_scanner}/api/api.py +4 -4
- {skillanalyzer → skill_scanner}/api/api_cli.py +8 -8
- {skillanalyzer → skill_scanner}/api/api_server.py +7 -7
- {skillanalyzer → skill_scanner}/api/router.py +3 -3
- {skillanalyzer → skill_scanner}/cli/__init__.py +1 -1
- {skillanalyzer → skill_scanner}/cli/cli.py +71 -13
- {skillanalyzer → skill_scanner}/config/__init__.py +3 -3
- {skillanalyzer → skill_scanner}/config/config.py +2 -2
- {skillanalyzer → skill_scanner}/config/config_parser.py +9 -9
- {skillanalyzer → skill_scanner}/config/constants.py +2 -2
- skill_scanner/config/yara_modes.py +314 -0
- {skillanalyzer → skill_scanner}/core/__init__.py +1 -1
- {skillanalyzer → skill_scanner}/core/analyzers/__init__.py +3 -3
- {skillanalyzer → skill_scanner}/core/analyzers/aidefense_analyzer.py +3 -3
- {skillanalyzer → skill_scanner}/core/analyzers/behavioral/__init__.py +1 -1
- {skillanalyzer → skill_scanner}/core/analyzers/behavioral/alignment/alignment_llm_client.py +1 -1
- {skillanalyzer → skill_scanner}/core/analyzers/behavioral/alignment/alignment_prompt_builder.py +2 -2
- {skillanalyzer → skill_scanner}/core/analyzers/behavioral_analyzer.py +1 -1
- skillanalyzer/core/analyzers/cross_skill_analyzer.py → skill_scanner/core/analyzers/cross_skill_scanner.py +5 -5
- {skillanalyzer → skill_scanner}/core/analyzers/llm_analyzer.py +4 -4
- {skillanalyzer → skill_scanner}/core/analyzers/llm_prompt_builder.py +2 -2
- {skillanalyzer → skill_scanner}/core/analyzers/meta_analyzer.py +52 -20
- {skillanalyzer → skill_scanner}/core/analyzers/static.py +185 -35
- {skillanalyzer → skill_scanner}/core/analyzers/trigger_analyzer.py +2 -2
- {skillanalyzer → skill_scanner}/core/exceptions.py +10 -10
- {skillanalyzer → skill_scanner}/core/loader.py +4 -4
- {skillanalyzer → skill_scanner}/core/models.py +7 -6
- {skillanalyzer → skill_scanner}/core/reporters/markdown_reporter.py +11 -5
- {skillanalyzer → skill_scanner}/core/reporters/sarif_reporter.py +2 -2
- {skillanalyzer → skill_scanner}/core/reporters/table_reporter.py +2 -2
- {skillanalyzer → skill_scanner}/core/rules/yara_scanner.py +1 -1
- {skillanalyzer → skill_scanner}/core/scanner.py +2 -2
- {skillanalyzer → skill_scanner}/core/static_analysis/context_extractor.py +88 -14
- {skillanalyzer → skill_scanner}/core/static_analysis/dataflow/__init__.py +1 -1
- {skillanalyzer → skill_scanner}/core/static_analysis/interprocedural/call_graph_analyzer.py +2 -2
- {skillanalyzer → skill_scanner}/core/static_analysis/parser/python_parser.py +5 -5
- {skillanalyzer → skill_scanner}/data/__init__.py +1 -1
- {skillanalyzer → skill_scanner}/data/prompts/boilerplate_protection_rule_prompt.md +5 -5
- {skillanalyzer → skill_scanner}/data/prompts/code_alignment_threat_analysis_prompt.md +128 -53
- {skillanalyzer → skill_scanner}/data/prompts/llm_response_schema.json +3 -3
- {skillanalyzer → skill_scanner}/data/prompts/skill_meta_analysis_prompt.md +16 -15
- {skillanalyzer → skill_scanner}/data/prompts/skill_threat_analysis_prompt.md +53 -17
- {skillanalyzer → skill_scanner}/data/prompts/unified_response_schema.md +1 -1
- {skillanalyzer → skill_scanner}/data/rules/signatures.yaml +143 -37
- skill_scanner/data/yara_rules/autonomy_abuse_generic.yara +66 -0
- skillanalyzer/data/yara_rules/skill_discovery_abuse.yara → skill_scanner/data/yara_rules/capability_inflation_generic.yara +7 -4
- skill_scanner/data/yara_rules/code_execution_generic.yara +76 -0
- skillanalyzer/data/yara_rules/coercive_injection.yara → skill_scanner/data/yara_rules/coercive_injection_generic.yara +2 -2
- skill_scanner/data/yara_rules/command_injection_generic.yara +77 -0
- skillanalyzer/data/yara_rules/credential_harvesting.yara → skill_scanner/data/yara_rules/credential_harvesting_generic.yara +25 -4
- skillanalyzer/data/yara_rules/transitive_trust_abuse.yara → skill_scanner/data/yara_rules/indirect_prompt_injection_generic.yara +8 -5
- skillanalyzer/data/yara_rules/prompt_injection.yara → skill_scanner/data/yara_rules/prompt_injection_generic.yara +2 -2
- skillanalyzer/data/yara_rules/unicode_steganography.yara → skill_scanner/data/yara_rules/prompt_injection_unicode_steganography.yara +23 -17
- skill_scanner/data/yara_rules/script_injection_generic.yara +82 -0
- skillanalyzer/data/yara_rules/sql_injection.yara → skill_scanner/data/yara_rules/sql_injection_generic.yara +22 -8
- skill_scanner/data/yara_rules/system_manipulation_generic.yara +79 -0
- skill_scanner/data/yara_rules/tool_chaining_abuse_generic.yara +72 -0
- {skillanalyzer → skill_scanner}/hooks/__init__.py +1 -1
- {skillanalyzer → skill_scanner}/hooks/pre_commit.py +16 -16
- {skillanalyzer → skill_scanner}/threats/__init__.py +25 -3
- skill_scanner/threats/cisco_ai_taxonomy.py +274 -0
- {skillanalyzer → skill_scanner}/threats/threats.py +28 -99
- {skillanalyzer → skill_scanner}/utils/__init__.py +1 -1
- {skillanalyzer → skill_scanner}/utils/command_utils.py +1 -1
- {skillanalyzer → skill_scanner}/utils/di_container.py +1 -1
- {skillanalyzer → skill_scanner}/utils/logging_config.py +7 -7
- cisco_ai_skill_scanner-1.0.0.dist-info/RECORD +0 -100
- cisco_ai_skill_scanner-1.0.0.dist-info/entry_points.txt +0 -4
- skillanalyzer/data/yara_rules/autonomy_abuse.yara +0 -66
- skillanalyzer/data/yara_rules/code_execution.yara +0 -61
- skillanalyzer/data/yara_rules/command_injection.yara +0 -54
- skillanalyzer/data/yara_rules/script_injection.yara +0 -83
- skillanalyzer/data/yara_rules/system_manipulation.yara +0 -65
- skillanalyzer/data/yara_rules/tool_chaining_abuse.yara +0 -60
- {cisco_ai_skill_scanner-1.0.0.dist-info → cisco_ai_skill_scanner-1.0.2.dist-info}/WHEEL +0 -0
- {cisco_ai_skill_scanner-1.0.0.dist-info → cisco_ai_skill_scanner-1.0.2.dist-info}/licenses/LICENSE +0 -0
- {skillanalyzer → skill_scanner}/core/analyzers/base.py +0 -0
- {skillanalyzer → skill_scanner}/core/analyzers/behavioral/alignment/__init__.py +0 -0
- {skillanalyzer → skill_scanner}/core/analyzers/behavioral/alignment/alignment_orchestrator.py +0 -0
- {skillanalyzer → skill_scanner}/core/analyzers/behavioral/alignment/alignment_response_validator.py +0 -0
- {skillanalyzer → skill_scanner}/core/analyzers/behavioral/alignment/threat_vulnerability_classifier.py +0 -0
- {skillanalyzer → skill_scanner}/core/analyzers/llm_provider_config.py +0 -0
- {skillanalyzer → skill_scanner}/core/analyzers/llm_request_handler.py +0 -0
- {skillanalyzer → skill_scanner}/core/analyzers/llm_response_parser.py +0 -0
- {skillanalyzer → skill_scanner}/core/analyzers/virustotal_analyzer.py +0 -0
- {skillanalyzer → skill_scanner}/core/reporters/__init__.py +0 -0
- {skillanalyzer → skill_scanner}/core/reporters/json_reporter.py +0 -0
- {skillanalyzer → skill_scanner}/core/rules/__init__.py +0 -0
- {skillanalyzer → skill_scanner}/core/rules/patterns.py +0 -0
- {skillanalyzer → skill_scanner}/core/static_analysis/__init__.py +0 -0
- {skillanalyzer → skill_scanner}/core/static_analysis/cfg/__init__.py +0 -0
- {skillanalyzer → skill_scanner}/core/static_analysis/cfg/builder.py +0 -0
- {skillanalyzer → skill_scanner}/core/static_analysis/dataflow/forward_analysis.py +0 -0
- {skillanalyzer → skill_scanner}/core/static_analysis/interprocedural/__init__.py +0 -0
- {skillanalyzer → skill_scanner}/core/static_analysis/interprocedural/cross_file_analyzer.py +0 -0
- {skillanalyzer → skill_scanner}/core/static_analysis/parser/__init__.py +0 -0
- {skillanalyzer → skill_scanner}/core/static_analysis/semantic/__init__.py +0 -0
- {skillanalyzer → skill_scanner}/core/static_analysis/semantic/name_resolver.py +0 -0
- {skillanalyzer → skill_scanner}/core/static_analysis/semantic/type_analyzer.py +0 -0
- {skillanalyzer → skill_scanner}/core/static_analysis/taint/__init__.py +0 -0
- {skillanalyzer → skill_scanner}/core/static_analysis/taint/tracker.py +0 -0
- {skillanalyzer → skill_scanner}/core/static_analysis/types/__init__.py +0 -0
- {skillanalyzer → skill_scanner}/utils/file_utils.py +0 -0
- {skillanalyzer → skill_scanner}/utils/logging_utils.py +0 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
//////////////////////////////////////////
|
|
2
|
+
// System Manipulation and Privilege Escalation Detection
|
|
3
|
+
// Target: File destruction and manipulation operations
|
|
4
|
+
// (Process control and termination)
|
|
5
|
+
//////////////////////////////////////////
|
|
6
|
+
|
|
7
|
+
rule system_manipulation_generic{
|
|
8
|
+
|
|
9
|
+
meta:
|
|
10
|
+
author = "Cisco"
|
|
11
|
+
description = "Detects system manipulation, privilege escalation, and destructive file operations"
|
|
12
|
+
classification = "harmful"
|
|
13
|
+
threat_type = "SYSTEM MANIPULATION"
|
|
14
|
+
|
|
15
|
+
strings:
|
|
16
|
+
// Suspicious environment variable manipulation (not just reading)
|
|
17
|
+
$env_var_manipulation = /\b(os\.environ\s*\[[^\]]*\]\s*=|export\s+PATH=|unset\s+(PATH|HOME|USER))\b/i
|
|
18
|
+
|
|
19
|
+
// File destruction and manipulation
|
|
20
|
+
$file_destruction = /\b(rm\s+-rf|dd\s+if=\/dev\/zero|wipefs|shred\s+-|find\s+[^\n]+-delete)\b/i
|
|
21
|
+
|
|
22
|
+
// Dangerous file permission changes
|
|
23
|
+
$permission_manipulation = /\b(chmod\s+(777|4755|6755|[ug]?\+s)|(chown|chgrp)\s+(root|0)|setuid|setgid)\b/i
|
|
24
|
+
|
|
25
|
+
// Critical system file access
|
|
26
|
+
$critical_system_access = /\b(\/etc\/(passwd|shadow|sudoers)|\/root\/\.ssh|~\/\.aws\/credentials|~\/\.ssh\/id_rsa)\b/i
|
|
27
|
+
|
|
28
|
+
// Privilege escalation patterns
|
|
29
|
+
$privilege_escalation = /\b(sudo\s+-[si]|su\s+-c?|runuser|doas)\b/i
|
|
30
|
+
|
|
31
|
+
// Dangerous process operations
|
|
32
|
+
$process_manipulation = /\b(kill\s+-9\s+[0-9]+|killall\s+-9|pkill\s+-9)\b/i
|
|
33
|
+
|
|
34
|
+
// Dangerous recursive operations with wildcards (exclude common cleanup dirs)
|
|
35
|
+
$recursive_operations = /\b(rm\s+-rf\s+(\/\s|\/root|\/home|\$HOME|~\/|\/etc|\/usr)|\bfind\s+\/\s+-delete)\b/i
|
|
36
|
+
|
|
37
|
+
// Safe cleanup patterns to exclude (Docker, npm, apt cache cleanup, backup retention)
|
|
38
|
+
$safe_cleanup = /(rm\s+-rf\s+(\/var\/lib\/apt\/lists|\/tmp\/|node_modules|__pycache__|\.cache|\.npm|\/var\/cache|dist|build|target)|find\s+[^\n]*-mtime\s+\+[0-9]+[^\n]*-delete|find\s+[^\n]*backup[^\n]*-delete)/i
|
|
39
|
+
|
|
40
|
+
// Testing and build commands (not manipulation)
|
|
41
|
+
$testing_commands = /\b(pytest|tox|make\s+test|npm\s+test|cargo\s+test|go\s+test|mvn\s+test|gradle\s+test|jest|mocha)\b/i
|
|
42
|
+
|
|
43
|
+
// Safe directory creation
|
|
44
|
+
$safe_mkdir = /\bmkdir\s+-p\b/
|
|
45
|
+
|
|
46
|
+
// System path manipulation
|
|
47
|
+
$path_manipulation = /\b(PATH=\/tmp|PATH=\.:|export\s+PATH=[\$\{])/i
|
|
48
|
+
|
|
49
|
+
condition:
|
|
50
|
+
// Exclude safe patterns
|
|
51
|
+
not $safe_cleanup and
|
|
52
|
+
not $testing_commands and
|
|
53
|
+
not $safe_mkdir and
|
|
54
|
+
(
|
|
55
|
+
// Environment variable manipulation (not just reading)
|
|
56
|
+
$env_var_manipulation or
|
|
57
|
+
|
|
58
|
+
// File destruction (not safe cleanup)
|
|
59
|
+
($file_destruction and not $safe_cleanup) or
|
|
60
|
+
|
|
61
|
+
// Permission manipulation
|
|
62
|
+
$permission_manipulation or
|
|
63
|
+
|
|
64
|
+
// Critical system access
|
|
65
|
+
$critical_system_access or
|
|
66
|
+
|
|
67
|
+
// Privilege escalation
|
|
68
|
+
$privilege_escalation or
|
|
69
|
+
|
|
70
|
+
// Process manipulation
|
|
71
|
+
$process_manipulation or
|
|
72
|
+
|
|
73
|
+
// Recursive operations
|
|
74
|
+
$recursive_operations or
|
|
75
|
+
|
|
76
|
+
// PATH manipulation
|
|
77
|
+
$path_manipulation
|
|
78
|
+
)
|
|
79
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
//////////////////////////////////////////
|
|
2
|
+
// Tool Chaining Abuse Detection
|
|
3
|
+
// Target: Data exfiltration through tool chains
|
|
4
|
+
// Very specific patterns to minimize FPs
|
|
5
|
+
//////////////////////////////////////////
|
|
6
|
+
|
|
7
|
+
rule tool_chaining_abuse_generic{
|
|
8
|
+
|
|
9
|
+
meta:
|
|
10
|
+
author = "Cisco"
|
|
11
|
+
description = "Detects suspicious tool chaining patterns that could lead to data exfiltration"
|
|
12
|
+
classification = "harmful"
|
|
13
|
+
threat_type = "TOOL CHAINING ABUSE"
|
|
14
|
+
|
|
15
|
+
strings:
|
|
16
|
+
|
|
17
|
+
// === High confidence: explicit exfil to known bad destinations ===
|
|
18
|
+
|
|
19
|
+
// Send to known exfil destinations
|
|
20
|
+
$exfil_discord = /\b(send|post|upload)[^.]{0,60}discord\.com\/api\/webhooks/i
|
|
21
|
+
$exfil_telegram = /\b(send|post|upload)[^.]{0,60}telegram\.org\/bot/i
|
|
22
|
+
$exfil_pastebin = /\b(send|post|upload)[^.]{0,60}pastebin\.com/i
|
|
23
|
+
$exfil_requestbin = /\b(send|post|upload)[^.]{0,60}(webhook\.site|requestbin|ngrok\.io)/i
|
|
24
|
+
|
|
25
|
+
// === High confidence: credential file access + network ===
|
|
26
|
+
|
|
27
|
+
// SSH key file + network send (on same line)
|
|
28
|
+
$ssh_key_exfil = /\.ssh\/(id_rsa|id_ed25519|id_dsa)[^.]{0,80}\b(send|post|upload|requests|fetch|curl|wget)\b/i
|
|
29
|
+
|
|
30
|
+
// AWS credentials file + network
|
|
31
|
+
$aws_cred_exfil = /\.aws\/credentials[^.]{0,80}\b(send|post|upload|requests|fetch)\b/i
|
|
32
|
+
|
|
33
|
+
// .env file + network
|
|
34
|
+
$env_file_exfil = /\b(read|open|load)[^.]{0,30}\.env[^.]{0,80}\b(send|post|upload|requests)\b/i
|
|
35
|
+
|
|
36
|
+
// === High confidence: explicit exfil language ===
|
|
37
|
+
|
|
38
|
+
// Explicit exfiltration keywords
|
|
39
|
+
$explicit_exfil = /\b(exfiltrate|steal|harvest|siphon)\s+(the\s+)?(data|files?|credentials?|secrets?|keys?)/i
|
|
40
|
+
|
|
41
|
+
// Send to attacker-controlled destination
|
|
42
|
+
$attacker_dest = /\b(send|forward|upload)\s+(to|data\s+to)\s+(attacker|malicious|c2|command[_-]?and[_-]?control)/i
|
|
43
|
+
|
|
44
|
+
// === High confidence: env var exfil ===
|
|
45
|
+
|
|
46
|
+
// Read secret env var then send to network
|
|
47
|
+
$env_var_exfil = /\b(os\.environ|getenv|process\.env)[^.]{0,30}(SECRET|PRIVATE|KEY|TOKEN|PASSWORD|CREDENTIAL)[^.]{0,100}\b(requests\.(post|get)|urllib|fetch|curl|wget)\b/i
|
|
48
|
+
|
|
49
|
+
// === Exclusions ===
|
|
50
|
+
$security_docs = /\b(MITRE|ATT&CK|threat\s+(model|hunt)|detection\s+rule)/i
|
|
51
|
+
$auth_code = /\b(login|authenticate|signIn|logIn)\s*\(/i
|
|
52
|
+
|
|
53
|
+
condition:
|
|
54
|
+
not $security_docs and
|
|
55
|
+
not $auth_code and
|
|
56
|
+
(
|
|
57
|
+
// Exfil to known bad destinations
|
|
58
|
+
$exfil_discord or
|
|
59
|
+
$exfil_telegram or
|
|
60
|
+
$exfil_pastebin or
|
|
61
|
+
$exfil_requestbin or
|
|
62
|
+
// Credential file exfil
|
|
63
|
+
$ssh_key_exfil or
|
|
64
|
+
$aws_cred_exfil or
|
|
65
|
+
$env_file_exfil or
|
|
66
|
+
// Explicit exfil language
|
|
67
|
+
$explicit_exfil or
|
|
68
|
+
$attacker_dest or
|
|
69
|
+
// Env var exfil
|
|
70
|
+
$env_var_exfil
|
|
71
|
+
)
|
|
72
|
+
}
|
|
@@ -16,27 +16,27 @@
|
|
|
16
16
|
# SPDX-License-Identifier: Apache-2.0
|
|
17
17
|
|
|
18
18
|
"""
|
|
19
|
-
Pre-commit hook for scanning
|
|
19
|
+
Pre-commit hook for scanning agent skills for security issues.
|
|
20
20
|
|
|
21
21
|
This hook scans staged skill directories for security vulnerabilities
|
|
22
22
|
and blocks commits that contain HIGH or CRITICAL severity findings.
|
|
23
23
|
|
|
24
24
|
Usage:
|
|
25
25
|
1. Install as a pre-commit hook:
|
|
26
|
-
skill-
|
|
26
|
+
skill-scanner-pre-commit install
|
|
27
27
|
|
|
28
28
|
2. Or add to .pre-commit-config.yaml:
|
|
29
29
|
- repo: local
|
|
30
30
|
hooks:
|
|
31
|
-
- id: skill-
|
|
32
|
-
name: Skill
|
|
33
|
-
entry: skill-
|
|
31
|
+
- id: skill-scanner
|
|
32
|
+
name: Skill Scanner
|
|
33
|
+
entry: skill-scanner-pre-commit
|
|
34
34
|
language: python
|
|
35
35
|
types: [file]
|
|
36
36
|
pass_filenames: false
|
|
37
37
|
|
|
38
38
|
Configuration:
|
|
39
|
-
Create a .
|
|
39
|
+
Create a .skill_scannerrc file in your repo root:
|
|
40
40
|
|
|
41
41
|
{
|
|
42
42
|
"severity_threshold": "high", # block on: critical, high, medium, low
|
|
@@ -54,7 +54,7 @@ from pathlib import Path
|
|
|
54
54
|
# Default configuration
|
|
55
55
|
DEFAULT_CONFIG = {
|
|
56
56
|
"severity_threshold": "high", # Block commits on HIGH or CRITICAL
|
|
57
|
-
"skills_path": ".claude/skills", # Default
|
|
57
|
+
"skills_path": ".claude/skills", # Default skills location
|
|
58
58
|
"fail_fast": True,
|
|
59
59
|
"use_behavioral": False,
|
|
60
60
|
"use_trigger": True,
|
|
@@ -73,7 +73,7 @@ SEVERITY_LEVELS = {
|
|
|
73
73
|
|
|
74
74
|
def load_config(repo_root: Path) -> dict:
|
|
75
75
|
"""
|
|
76
|
-
Load configuration from .
|
|
76
|
+
Load configuration from .skill_scannerrc file.
|
|
77
77
|
|
|
78
78
|
Args:
|
|
79
79
|
repo_root: Repository root directory
|
|
@@ -84,9 +84,9 @@ def load_config(repo_root: Path) -> dict:
|
|
|
84
84
|
config = DEFAULT_CONFIG.copy()
|
|
85
85
|
|
|
86
86
|
config_paths = [
|
|
87
|
-
repo_root / ".
|
|
88
|
-
repo_root / ".
|
|
89
|
-
repo_root / "
|
|
87
|
+
repo_root / ".skill_scannerrc",
|
|
88
|
+
repo_root / ".skill_scannerrc.json",
|
|
89
|
+
repo_root / "skill_scanner.json",
|
|
90
90
|
]
|
|
91
91
|
|
|
92
92
|
for config_path in config_paths:
|
|
@@ -273,7 +273,7 @@ def main(args: list[str] | None = None) -> int:
|
|
|
273
273
|
Returns:
|
|
274
274
|
Exit code (0 = success, 1 = blocked)
|
|
275
275
|
"""
|
|
276
|
-
parser = argparse.ArgumentParser(description="Pre-commit hook for scanning
|
|
276
|
+
parser = argparse.ArgumentParser(description="Pre-commit hook for scanning agent skills")
|
|
277
277
|
parser.add_argument(
|
|
278
278
|
"--severity",
|
|
279
279
|
choices=["critical", "high", "medium", "low"],
|
|
@@ -413,10 +413,10 @@ def install_hook() -> int:
|
|
|
413
413
|
hook_path = hooks_dir / "pre-commit"
|
|
414
414
|
|
|
415
415
|
hook_script = """#!/bin/sh
|
|
416
|
-
# Skill
|
|
417
|
-
# Automatically scans
|
|
416
|
+
# Skill Scanner Pre-commit Hook
|
|
417
|
+
# Automatically scans agent skills for security issues
|
|
418
418
|
|
|
419
|
-
skill-
|
|
419
|
+
skill-scanner-pre-commit "$@"
|
|
420
420
|
exit_code=$?
|
|
421
421
|
|
|
422
422
|
if [ $exit_code -ne 0 ]; then
|
|
@@ -440,7 +440,7 @@ exit $exit_code
|
|
|
440
440
|
|
|
441
441
|
print(f"✅ Pre-commit hook installed at {hook_path}")
|
|
442
442
|
print("\nConfiguration:")
|
|
443
|
-
print(" Create .
|
|
443
|
+
print(" Create .skill_scannerrc in your repo root to customize behavior:")
|
|
444
444
|
print(' { "severity_threshold": "high", "skills_path": ".claude/skills" }')
|
|
445
445
|
|
|
446
446
|
return 0
|
|
@@ -15,11 +15,33 @@
|
|
|
15
15
|
# SPDX-License-Identifier: Apache-2.0
|
|
16
16
|
|
|
17
17
|
"""
|
|
18
|
-
Threat mapping and taxonomy for
|
|
18
|
+
Threat mapping and taxonomy for Skill Scanner.
|
|
19
19
|
|
|
20
|
-
Aligned with
|
|
20
|
+
Aligned with Cisco AI Security Framework taxonomy.
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
|
+
from .cisco_ai_taxonomy import (
|
|
24
|
+
AISUBTECH_TAXONOMY,
|
|
25
|
+
AITECH_TAXONOMY,
|
|
26
|
+
VALID_AISUBTECH_CODES,
|
|
27
|
+
VALID_AITECH_CODES,
|
|
28
|
+
get_aisubtech_name,
|
|
29
|
+
get_aitech_name,
|
|
30
|
+
is_valid_aisubtech,
|
|
31
|
+
is_valid_aitech,
|
|
32
|
+
)
|
|
23
33
|
from .threats import LLM_THREAT_MAPPING, YARA_THREAT_MAPPING, ThreatMapping
|
|
24
34
|
|
|
25
|
-
__all__ = [
|
|
35
|
+
__all__ = [
|
|
36
|
+
"ThreatMapping",
|
|
37
|
+
"LLM_THREAT_MAPPING",
|
|
38
|
+
"YARA_THREAT_MAPPING",
|
|
39
|
+
"AITECH_TAXONOMY",
|
|
40
|
+
"AISUBTECH_TAXONOMY",
|
|
41
|
+
"VALID_AITECH_CODES",
|
|
42
|
+
"VALID_AISUBTECH_CODES",
|
|
43
|
+
"is_valid_aitech",
|
|
44
|
+
"is_valid_aisubtech",
|
|
45
|
+
"get_aitech_name",
|
|
46
|
+
"get_aisubtech_name",
|
|
47
|
+
]
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
# Copyright 2026 Cisco Systems, Inc.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
#
|
|
15
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
16
|
+
|
|
17
|
+
"""
|
|
18
|
+
Cisco AI Security Framework - Ground Truth Taxonomy.
|
|
19
|
+
|
|
20
|
+
Source: https://learn-cloudsecurity.cisco.com/ai-security-framework
|
|
21
|
+
Owner: Ankit Garg
|
|
22
|
+
Last Updated: 2026-02-02
|
|
23
|
+
|
|
24
|
+
This file contains the authoritative AITech and AISubtech codes from the
|
|
25
|
+
Cisco Integrated AI Security and Safety Framework. All threat mappings in
|
|
26
|
+
threats.py must use codes that exist in this taxonomy.
|
|
27
|
+
|
|
28
|
+
To update this file when the framework changes:
|
|
29
|
+
1. Export data from https://learn-cloudsecurity.cisco.com/ai-security-framework
|
|
30
|
+
2. Update the dictionaries below
|
|
31
|
+
3. Run tests to validate threats.py alignment
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
# Valid AITech codes and their official names
|
|
35
|
+
AITECH_TAXONOMY: dict[str, str] = {
|
|
36
|
+
# OB-001: Goal Hijacking
|
|
37
|
+
"AITech-1.1": "Direct Prompt Injection",
|
|
38
|
+
"AITech-1.2": "Indirect Prompt Injection",
|
|
39
|
+
"AITech-1.3": "Goal Manipulation",
|
|
40
|
+
"AITech-1.4": "Multi-Modal Injection and Manipulation",
|
|
41
|
+
# OB-002: Jailbreak
|
|
42
|
+
"AITech-2.1": "Jailbreak",
|
|
43
|
+
# OB-003: Masquerading / Obfuscation / Impersonation
|
|
44
|
+
"AITech-3.1": "Masquerading / Obfuscation / Impersonation",
|
|
45
|
+
# OB-004: Communication Compromise
|
|
46
|
+
"AITech-4.1": "Agent Injection",
|
|
47
|
+
"AITech-4.2": "Context Boundary Attacks",
|
|
48
|
+
"AITech-4.3": "Protocol Manipulation",
|
|
49
|
+
# OB-005: Persistence
|
|
50
|
+
"AITech-5.1": "Memory System Persistence",
|
|
51
|
+
"AITech-5.2": "Configuration Persistence",
|
|
52
|
+
# OB-006: Feedback Loop Manipulation
|
|
53
|
+
"AITech-6.1": "Training Data Poisoning",
|
|
54
|
+
# OB-007: Sabotage / Integrity Degradation
|
|
55
|
+
"AITech-7.1": "Reasoning Corruption",
|
|
56
|
+
"AITech-7.2": "Memory System Corruption",
|
|
57
|
+
"AITech-7.3": "Data Source Abuse and Manipulation",
|
|
58
|
+
"AITech-7.4": "Token Manipulation",
|
|
59
|
+
# OB-008: Data Privacy Violations
|
|
60
|
+
"AITech-8.1": "Membership Inference",
|
|
61
|
+
"AITech-8.2": "Data Exfiltration / Exposure",
|
|
62
|
+
"AITech-8.3": "Information Disclosure",
|
|
63
|
+
"AITech-8.4": "Prompt/Meta Extraction",
|
|
64
|
+
# OB-009: Supply Chain Compromise
|
|
65
|
+
"AITech-9.1": "Model or Agentic System Manipulation",
|
|
66
|
+
"AITech-9.2": "Detection Evasion",
|
|
67
|
+
"AITech-9.3": "Dependency / Plugin Compromise",
|
|
68
|
+
# OB-010: Model Theft / Extraction
|
|
69
|
+
"AITech-10.1": "Model Extraction",
|
|
70
|
+
"AITech-10.2": "Model Inversion",
|
|
71
|
+
# OB-011: Adversarial Evasion
|
|
72
|
+
"AITech-11.1": "Environment-Aware Evasion",
|
|
73
|
+
"AITech-11.2": "Model-Selective Evasion",
|
|
74
|
+
# OB-012: Action-Space and Integration Abuse
|
|
75
|
+
"AITech-12.1": "Tool Exploitation",
|
|
76
|
+
"AITech-12.2": "Insecure Output Handling",
|
|
77
|
+
# OB-013: Availability Abuse
|
|
78
|
+
"AITech-13.1": "Disruption of Availability",
|
|
79
|
+
"AITech-13.2": "Cost Harvesting / Repurposing",
|
|
80
|
+
# OB-014: Privilege Compromise
|
|
81
|
+
"AITech-14.1": "Unauthorized Access",
|
|
82
|
+
"AITech-14.2": "Abuse of Delegated Authority",
|
|
83
|
+
# OB-015: Harmful / Misleading / Inaccurate Content
|
|
84
|
+
"AITech-15.1": "Harmful Content",
|
|
85
|
+
# OB-016: Surveillance
|
|
86
|
+
"AITech-16.1": "Eavesdropping",
|
|
87
|
+
# OB-017: Cyber-Physical / Sensor Attacks
|
|
88
|
+
"AITech-17.1": "Sensor Spoofing",
|
|
89
|
+
# OB-018: System Misuse / Malicious Application
|
|
90
|
+
"AITech-18.1": "Fraudulent Use",
|
|
91
|
+
"AITech-18.2": "Malicious Workflows",
|
|
92
|
+
# OB-019: Multi-Modal / Cross-Modal Risks
|
|
93
|
+
"AITech-19.1": "Cross-Modal Inconsistency Exploits",
|
|
94
|
+
"AITech-19.2": "Fusion Payload Split",
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
# Valid AISubtech codes and their official names
|
|
98
|
+
AISUBTECH_TAXONOMY: dict[str, str] = {
|
|
99
|
+
# AITech-1.1: Direct Prompt Injection
|
|
100
|
+
"AISubtech-1.1.1": "Instruction Manipulation (Direct Prompt Injection)",
|
|
101
|
+
"AISubtech-1.1.2": "Obfuscation (Direct Prompt Injection)",
|
|
102
|
+
"AISubtech-1.1.3": "Multi-Agent Prompt Injection",
|
|
103
|
+
# AITech-1.2: Indirect Prompt Injection
|
|
104
|
+
"AISubtech-1.2.1": "Instruction Manipulation (Indirect Prompt Injection)",
|
|
105
|
+
"AISubtech-1.2.2": "Obfuscation (Indirect Prompt Injection)",
|
|
106
|
+
"AISubtech-1.2.3": "Multi-Agent (Indirect Prompt Injection)",
|
|
107
|
+
# AITech-1.3: Goal Manipulation
|
|
108
|
+
"AISubtech-1.3.1": "Goal Manipulation (Models, Agents)",
|
|
109
|
+
"AISubtech-1.3.2": "Goal Manipulation (Tools, Prompts, Resources)",
|
|
110
|
+
# AITech-1.4: Multi-Modal Injection
|
|
111
|
+
"AISubtech-1.4.1": "Image-Text Injection",
|
|
112
|
+
"AISubtech-1.4.2": "Image Manipulation",
|
|
113
|
+
"AISubtech-1.4.3": "Audio Command Injection",
|
|
114
|
+
"AISubtech-1.4.4": "Video Overlay Manipulation",
|
|
115
|
+
# AITech-2.1: Jailbreak
|
|
116
|
+
"AISubtech-2.1.1": "Context Manipulation (Jailbreak)",
|
|
117
|
+
"AISubtech-2.1.2": "Obfuscation (Jailbreak)",
|
|
118
|
+
"AISubtech-2.1.3": "Semantic Manipulation (Jailbreak)",
|
|
119
|
+
"AISubtech-2.1.4": "Token Exploitation (Jailbreak)",
|
|
120
|
+
"AISubtech-2.1.5": "Multi-Agent Jailbreak Collaboration",
|
|
121
|
+
# AITech-3.1: Masquerading
|
|
122
|
+
"AISubtech-3.1.1": "Identity Obfuscation",
|
|
123
|
+
"AISubtech-3.1.2": "Trusted Agent Spoofing",
|
|
124
|
+
# AITech-4.1: Agent Injection
|
|
125
|
+
"AISubtech-4.1.1": "Rogue Agent Introduction",
|
|
126
|
+
# AITech-4.2: Context Boundary Attacks
|
|
127
|
+
"AISubtech-4.2.1": "Context Window Exploitation",
|
|
128
|
+
"AISubtech-4.2.2": "Session Boundary Violation",
|
|
129
|
+
# AITech-4.3: Protocol Manipulation
|
|
130
|
+
"AISubtech-4.3.1": "Schema Inconsistencies",
|
|
131
|
+
"AISubtech-4.3.2": "Namespace Collision",
|
|
132
|
+
"AISubtech-4.3.3": "Server Rebinding Attack",
|
|
133
|
+
"AISubtech-4.3.4": "Replay Exploitation",
|
|
134
|
+
"AISubtech-4.3.5": "Capability Inflation",
|
|
135
|
+
"AISubtech-4.3.6": "Cross-Origin Exploitation",
|
|
136
|
+
# AITech-5.1: Memory System Persistence
|
|
137
|
+
"AISubtech-5.1.1": "Long-term / Short-term Memory Injection",
|
|
138
|
+
# AITech-5.2: Configuration Persistence
|
|
139
|
+
"AISubtech-5.2.1": "Agent Profile Tampering",
|
|
140
|
+
# AITech-6.1: Training Data Poisoning
|
|
141
|
+
"AISubtech-6.1.1": "Knowledge Base Poisoning",
|
|
142
|
+
"AISubtech-6.1.2": "Reinforcement Biasing",
|
|
143
|
+
"AISubtech-6.1.3": "Reinforcement Signal Corruption",
|
|
144
|
+
# AITech-7.2: Memory System Corruption
|
|
145
|
+
"AISubtech-7.2.1": "Memory Anchor Attacks",
|
|
146
|
+
"AISubtech-7.2.2": "Memory Index Manipulation",
|
|
147
|
+
# AITech-7.3: Data Source Abuse
|
|
148
|
+
"AISubtech-7.3.1": "Corrupted Third-Party Data",
|
|
149
|
+
# AITech-7.4: Token Manipulation
|
|
150
|
+
"AISubtech-7.4.1": "Token Theft",
|
|
151
|
+
# AITech-8.1: Membership Inference
|
|
152
|
+
"AISubtech-8.1.1": "Presence Detection",
|
|
153
|
+
# AITech-8.2: Data Exfiltration / Exposure
|
|
154
|
+
"AISubtech-8.2.1": "Training Data Exposure",
|
|
155
|
+
"AISubtech-8.2.2": "LLM Data Leakage",
|
|
156
|
+
"AISubtech-8.2.3": "Data Exfiltration via Agent Tooling",
|
|
157
|
+
# AITech-8.3: Information Disclosure
|
|
158
|
+
"AISubtech-8.3.1": "Tool Metadata Exposure",
|
|
159
|
+
"AISubtech-8.3.2": "System Information Leakage",
|
|
160
|
+
# AITech-8.4: Prompt/Meta Extraction
|
|
161
|
+
"AISubtech-8.4.1": "System LLM Prompt Leakage",
|
|
162
|
+
# AITech-9.1: Model or Agentic System Manipulation
|
|
163
|
+
"AISubtech-9.1.1": "Code Execution",
|
|
164
|
+
"AISubtech-9.1.2": "Unauthorized or Unsolicited System Access",
|
|
165
|
+
"AISubtech-9.1.3": "Unauthorized or Unsolicited Network Access",
|
|
166
|
+
"AISubtech-9.1.4": "Injection Attacks (SQL, Command Execution, XSS)",
|
|
167
|
+
"AISubtech-9.1.5": "Template Injection (SSTI)",
|
|
168
|
+
# AITech-9.2: Detection Evasion
|
|
169
|
+
"AISubtech-9.2.1": "Obfuscation Vulnerabilities",
|
|
170
|
+
"AISubtech-9.2.2": "Backdoors and Trojans",
|
|
171
|
+
# AITech-9.3: Dependency / Plugin Compromise
|
|
172
|
+
"AISubtech-9.3.1": "Malicious Package / Tool Injection",
|
|
173
|
+
"AISubtech-9.3.2": "Dependency Name Squatting (Tools / Servers)",
|
|
174
|
+
"AISubtech-9.3.3": "Dependency Replacement / Rug Pull",
|
|
175
|
+
# AITech-10.1: Model Extraction
|
|
176
|
+
"AISubtech-10.1.1": "API Query Stealing",
|
|
177
|
+
"AISubtech-10.1.2": "Weight Reconstruction",
|
|
178
|
+
"AISubtech-10.1.3": "Sensitive Data Reconstruction",
|
|
179
|
+
# AITech-10.2: Model Inversion
|
|
180
|
+
"AISubtech-10.2.1": "Model Inversion",
|
|
181
|
+
# AITech-11.1: Environment-Aware Evasion
|
|
182
|
+
"AISubtech-11.1.1": "Agent-Specific Evasion",
|
|
183
|
+
"AISubtech-11.1.2": "Tool-Scoped Evasion",
|
|
184
|
+
"AISubtech-11.1.3": "Environment-Scoped Payloads",
|
|
185
|
+
"AISubtech-11.1.4": "Defense-Aware Payloads",
|
|
186
|
+
# AITech-11.2: Model-Selective Evasion
|
|
187
|
+
"AISubtech-11.2.1": "Targeted Model Fingerprinting",
|
|
188
|
+
"AISubtech-11.2.2": "Conditional Attack Execution",
|
|
189
|
+
# AITech-12.1: Tool Exploitation
|
|
190
|
+
"AISubtech-12.1.1": "Parameter Manipulation",
|
|
191
|
+
"AISubtech-12.1.2": "Tool Poisoning",
|
|
192
|
+
"AISubtech-12.1.3": "Unsafe System / Browser / File Execution",
|
|
193
|
+
"AISubtech-12.1.4": "Tool Shadowing",
|
|
194
|
+
# AITech-12.2: Insecure Output Handling
|
|
195
|
+
"AISubtech-12.2.1": "Code Detection / Malicious Code Output",
|
|
196
|
+
# AITech-13.1: Disruption of Availability
|
|
197
|
+
"AISubtech-13.1.1": "Compute Exhaustion",
|
|
198
|
+
"AISubtech-13.1.2": "Memory Flooding",
|
|
199
|
+
"AISubtech-13.1.3": "Model Denial of Service",
|
|
200
|
+
"AISubtech-13.1.4": "Application Denial of Service",
|
|
201
|
+
"AISubtech-13.1.5": "Decision Paralysis Attacks",
|
|
202
|
+
# AITech-13.2: Cost Harvesting
|
|
203
|
+
"AISubtech-13.2.1": "Service Misuse for Cost Inflation",
|
|
204
|
+
# AITech-14.1: Unauthorized Access
|
|
205
|
+
"AISubtech-14.1.1": "Credential Theft",
|
|
206
|
+
"AISubtech-14.1.2": "Insufficient Access Controls",
|
|
207
|
+
# AITech-14.2: Abuse of Delegated Authority
|
|
208
|
+
"AISubtech-14.2.1": "Permission Escalation via Delegation",
|
|
209
|
+
# AITech-15.1: Harmful Content (extensive sub-techniques)
|
|
210
|
+
"AISubtech-15.1.1": "Cybersecurity and Hacking: Malware / Exploits",
|
|
211
|
+
"AISubtech-15.1.2": "Cybersecurity and Hacking: Cyber Abuse",
|
|
212
|
+
"AISubtech-15.1.3": "Safety Harms and Toxicity: Animal Abuse",
|
|
213
|
+
"AISubtech-15.1.4": "Safety Harms and Toxicity: Child Abuse / Exploitation",
|
|
214
|
+
"AISubtech-15.1.5": "Safety Harms and Toxicity: Disinformation",
|
|
215
|
+
"AISubtech-15.1.6": "Safety Harms and Toxicity: Environmental Harm",
|
|
216
|
+
"AISubtech-15.1.7": "Safety Harms and Toxicity: Financial Harm",
|
|
217
|
+
"AISubtech-15.1.8": "Safety Harms and Toxicity: Harassment",
|
|
218
|
+
"AISubtech-15.1.9": "Safety Harms and Toxicity: Hate Speech",
|
|
219
|
+
"AISubtech-15.1.10": "Safety Harms and Toxicity: Non-Violent Crime",
|
|
220
|
+
"AISubtech-15.1.11": "Safety Harms and Toxicity: Profanity",
|
|
221
|
+
"AISubtech-15.1.12": "Safety Harms and Toxicity: Scams and Deception",
|
|
222
|
+
"AISubtech-15.1.13": "Safety Harms and Toxicity: Self Harm",
|
|
223
|
+
"AISubtech-15.1.14": "Safety Harms and Toxicity: Sexual Content and Exploitation",
|
|
224
|
+
"AISubtech-15.1.15": "Safety Harms and Toxicity: Social Division and Polarization",
|
|
225
|
+
"AISubtech-15.1.16": "Safety Harms and Toxicity: Terrorism / Extremism",
|
|
226
|
+
"AISubtech-15.1.17": "Safety Harms and Toxicity: Violence and Public Safety Threat",
|
|
227
|
+
"AISubtech-15.1.18": "Safety Harms and Toxicity: Weapons / CBRN Risks",
|
|
228
|
+
"AISubtech-15.1.19": "Integrity: Hallucinations / Misinformation",
|
|
229
|
+
"AISubtech-15.1.20": "Integrity: Unauthorized Financial Advice",
|
|
230
|
+
"AISubtech-15.1.21": "Integrity: Unauthorized Legal Advice",
|
|
231
|
+
"AISubtech-15.1.22": "Integrity: Unauthorized Medical Advice",
|
|
232
|
+
"AISubtech-15.1.23": "Intellectual Property Compromise: Intellectual Property Infringement",
|
|
233
|
+
"AISubtech-15.1.24": "Intellectual Property Compromise: Confidential Data",
|
|
234
|
+
"AISubtech-15.1.25": "Privacy Attacks: PII / PHI / PCI",
|
|
235
|
+
# AITech-16.1: Eavesdropping
|
|
236
|
+
"AISubtech-16.1.1": "Logging Sensitive Conversations",
|
|
237
|
+
# AITech-17.1: Sensor Spoofing
|
|
238
|
+
"AISubtech-17.1.1": "Sensor Spoofing: Action Signals (audio, visual)",
|
|
239
|
+
# AITech-18.1: Fraudulent Use
|
|
240
|
+
"AISubtech-18.1.1": "Spam / Scam / Social Engineering Generation",
|
|
241
|
+
# AITech-18.2: Malicious Workflows
|
|
242
|
+
"AISubtech-18.2.1": "Abuse of APIs for Mass Automation",
|
|
243
|
+
"AISubtech-18.2.2": "Dedicated Malicious Server or Infrastructure",
|
|
244
|
+
# AITech-19.1: Cross-Modal Inconsistency
|
|
245
|
+
"AISubtech-19.1.1": "Contradictory Inputs Attack",
|
|
246
|
+
"AISubtech-19.1.2": "Modality Skewing",
|
|
247
|
+
# AITech-19.2: Fusion Payload Split
|
|
248
|
+
"AISubtech-19.2.1": "Convergence Payload Injection",
|
|
249
|
+
"AISubtech-19.2.2": "Chained Payload Execution",
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
# Convenience sets for quick membership testing
|
|
253
|
+
VALID_AITECH_CODES: set[str] = set(AITECH_TAXONOMY.keys())
|
|
254
|
+
VALID_AISUBTECH_CODES: set[str] = set(AISUBTECH_TAXONOMY.keys())
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
def is_valid_aitech(code: str) -> bool:
|
|
258
|
+
"""Check if an AITech code exists in the official taxonomy."""
|
|
259
|
+
return code in VALID_AITECH_CODES
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
def is_valid_aisubtech(code: str) -> bool:
|
|
263
|
+
"""Check if an AISubtech code exists in the official taxonomy."""
|
|
264
|
+
return code in VALID_AISUBTECH_CODES
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def get_aitech_name(code: str) -> str | None:
|
|
268
|
+
"""Get the official name for an AITech code."""
|
|
269
|
+
return AITECH_TAXONOMY.get(code)
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def get_aisubtech_name(code: str) -> str | None:
|
|
273
|
+
"""Get the official name for an AISubtech code."""
|
|
274
|
+
return AISUBTECH_TAXONOMY.get(code)
|