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.
Files changed (110) hide show
  1. {cisco_ai_skill_scanner-1.0.0.dist-info → cisco_ai_skill_scanner-1.0.2.dist-info}/METADATA +28 -13
  2. cisco_ai_skill_scanner-1.0.2.dist-info/RECORD +102 -0
  3. cisco_ai_skill_scanner-1.0.2.dist-info/entry_points.txt +4 -0
  4. {skillanalyzer → skill_scanner}/__init__.py +8 -4
  5. {skillanalyzer → skill_scanner}/_version.py +2 -2
  6. {skillanalyzer → skill_scanner}/api/__init__.py +1 -1
  7. {skillanalyzer → skill_scanner}/api/api.py +4 -4
  8. {skillanalyzer → skill_scanner}/api/api_cli.py +8 -8
  9. {skillanalyzer → skill_scanner}/api/api_server.py +7 -7
  10. {skillanalyzer → skill_scanner}/api/router.py +3 -3
  11. {skillanalyzer → skill_scanner}/cli/__init__.py +1 -1
  12. {skillanalyzer → skill_scanner}/cli/cli.py +71 -13
  13. {skillanalyzer → skill_scanner}/config/__init__.py +3 -3
  14. {skillanalyzer → skill_scanner}/config/config.py +2 -2
  15. {skillanalyzer → skill_scanner}/config/config_parser.py +9 -9
  16. {skillanalyzer → skill_scanner}/config/constants.py +2 -2
  17. skill_scanner/config/yara_modes.py +314 -0
  18. {skillanalyzer → skill_scanner}/core/__init__.py +1 -1
  19. {skillanalyzer → skill_scanner}/core/analyzers/__init__.py +3 -3
  20. {skillanalyzer → skill_scanner}/core/analyzers/aidefense_analyzer.py +3 -3
  21. {skillanalyzer → skill_scanner}/core/analyzers/behavioral/__init__.py +1 -1
  22. {skillanalyzer → skill_scanner}/core/analyzers/behavioral/alignment/alignment_llm_client.py +1 -1
  23. {skillanalyzer → skill_scanner}/core/analyzers/behavioral/alignment/alignment_prompt_builder.py +2 -2
  24. {skillanalyzer → skill_scanner}/core/analyzers/behavioral_analyzer.py +1 -1
  25. skillanalyzer/core/analyzers/cross_skill_analyzer.py → skill_scanner/core/analyzers/cross_skill_scanner.py +5 -5
  26. {skillanalyzer → skill_scanner}/core/analyzers/llm_analyzer.py +4 -4
  27. {skillanalyzer → skill_scanner}/core/analyzers/llm_prompt_builder.py +2 -2
  28. {skillanalyzer → skill_scanner}/core/analyzers/meta_analyzer.py +52 -20
  29. {skillanalyzer → skill_scanner}/core/analyzers/static.py +185 -35
  30. {skillanalyzer → skill_scanner}/core/analyzers/trigger_analyzer.py +2 -2
  31. {skillanalyzer → skill_scanner}/core/exceptions.py +10 -10
  32. {skillanalyzer → skill_scanner}/core/loader.py +4 -4
  33. {skillanalyzer → skill_scanner}/core/models.py +7 -6
  34. {skillanalyzer → skill_scanner}/core/reporters/markdown_reporter.py +11 -5
  35. {skillanalyzer → skill_scanner}/core/reporters/sarif_reporter.py +2 -2
  36. {skillanalyzer → skill_scanner}/core/reporters/table_reporter.py +2 -2
  37. {skillanalyzer → skill_scanner}/core/rules/yara_scanner.py +1 -1
  38. {skillanalyzer → skill_scanner}/core/scanner.py +2 -2
  39. {skillanalyzer → skill_scanner}/core/static_analysis/context_extractor.py +88 -14
  40. {skillanalyzer → skill_scanner}/core/static_analysis/dataflow/__init__.py +1 -1
  41. {skillanalyzer → skill_scanner}/core/static_analysis/interprocedural/call_graph_analyzer.py +2 -2
  42. {skillanalyzer → skill_scanner}/core/static_analysis/parser/python_parser.py +5 -5
  43. {skillanalyzer → skill_scanner}/data/__init__.py +1 -1
  44. {skillanalyzer → skill_scanner}/data/prompts/boilerplate_protection_rule_prompt.md +5 -5
  45. {skillanalyzer → skill_scanner}/data/prompts/code_alignment_threat_analysis_prompt.md +128 -53
  46. {skillanalyzer → skill_scanner}/data/prompts/llm_response_schema.json +3 -3
  47. {skillanalyzer → skill_scanner}/data/prompts/skill_meta_analysis_prompt.md +16 -15
  48. {skillanalyzer → skill_scanner}/data/prompts/skill_threat_analysis_prompt.md +53 -17
  49. {skillanalyzer → skill_scanner}/data/prompts/unified_response_schema.md +1 -1
  50. {skillanalyzer → skill_scanner}/data/rules/signatures.yaml +143 -37
  51. skill_scanner/data/yara_rules/autonomy_abuse_generic.yara +66 -0
  52. skillanalyzer/data/yara_rules/skill_discovery_abuse.yara → skill_scanner/data/yara_rules/capability_inflation_generic.yara +7 -4
  53. skill_scanner/data/yara_rules/code_execution_generic.yara +76 -0
  54. skillanalyzer/data/yara_rules/coercive_injection.yara → skill_scanner/data/yara_rules/coercive_injection_generic.yara +2 -2
  55. skill_scanner/data/yara_rules/command_injection_generic.yara +77 -0
  56. skillanalyzer/data/yara_rules/credential_harvesting.yara → skill_scanner/data/yara_rules/credential_harvesting_generic.yara +25 -4
  57. skillanalyzer/data/yara_rules/transitive_trust_abuse.yara → skill_scanner/data/yara_rules/indirect_prompt_injection_generic.yara +8 -5
  58. skillanalyzer/data/yara_rules/prompt_injection.yara → skill_scanner/data/yara_rules/prompt_injection_generic.yara +2 -2
  59. skillanalyzer/data/yara_rules/unicode_steganography.yara → skill_scanner/data/yara_rules/prompt_injection_unicode_steganography.yara +23 -17
  60. skill_scanner/data/yara_rules/script_injection_generic.yara +82 -0
  61. skillanalyzer/data/yara_rules/sql_injection.yara → skill_scanner/data/yara_rules/sql_injection_generic.yara +22 -8
  62. skill_scanner/data/yara_rules/system_manipulation_generic.yara +79 -0
  63. skill_scanner/data/yara_rules/tool_chaining_abuse_generic.yara +72 -0
  64. {skillanalyzer → skill_scanner}/hooks/__init__.py +1 -1
  65. {skillanalyzer → skill_scanner}/hooks/pre_commit.py +16 -16
  66. {skillanalyzer → skill_scanner}/threats/__init__.py +25 -3
  67. skill_scanner/threats/cisco_ai_taxonomy.py +274 -0
  68. {skillanalyzer → skill_scanner}/threats/threats.py +28 -99
  69. {skillanalyzer → skill_scanner}/utils/__init__.py +1 -1
  70. {skillanalyzer → skill_scanner}/utils/command_utils.py +1 -1
  71. {skillanalyzer → skill_scanner}/utils/di_container.py +1 -1
  72. {skillanalyzer → skill_scanner}/utils/logging_config.py +7 -7
  73. cisco_ai_skill_scanner-1.0.0.dist-info/RECORD +0 -100
  74. cisco_ai_skill_scanner-1.0.0.dist-info/entry_points.txt +0 -4
  75. skillanalyzer/data/yara_rules/autonomy_abuse.yara +0 -66
  76. skillanalyzer/data/yara_rules/code_execution.yara +0 -61
  77. skillanalyzer/data/yara_rules/command_injection.yara +0 -54
  78. skillanalyzer/data/yara_rules/script_injection.yara +0 -83
  79. skillanalyzer/data/yara_rules/system_manipulation.yara +0 -65
  80. skillanalyzer/data/yara_rules/tool_chaining_abuse.yara +0 -60
  81. {cisco_ai_skill_scanner-1.0.0.dist-info → cisco_ai_skill_scanner-1.0.2.dist-info}/WHEEL +0 -0
  82. {cisco_ai_skill_scanner-1.0.0.dist-info → cisco_ai_skill_scanner-1.0.2.dist-info}/licenses/LICENSE +0 -0
  83. {skillanalyzer → skill_scanner}/core/analyzers/base.py +0 -0
  84. {skillanalyzer → skill_scanner}/core/analyzers/behavioral/alignment/__init__.py +0 -0
  85. {skillanalyzer → skill_scanner}/core/analyzers/behavioral/alignment/alignment_orchestrator.py +0 -0
  86. {skillanalyzer → skill_scanner}/core/analyzers/behavioral/alignment/alignment_response_validator.py +0 -0
  87. {skillanalyzer → skill_scanner}/core/analyzers/behavioral/alignment/threat_vulnerability_classifier.py +0 -0
  88. {skillanalyzer → skill_scanner}/core/analyzers/llm_provider_config.py +0 -0
  89. {skillanalyzer → skill_scanner}/core/analyzers/llm_request_handler.py +0 -0
  90. {skillanalyzer → skill_scanner}/core/analyzers/llm_response_parser.py +0 -0
  91. {skillanalyzer → skill_scanner}/core/analyzers/virustotal_analyzer.py +0 -0
  92. {skillanalyzer → skill_scanner}/core/reporters/__init__.py +0 -0
  93. {skillanalyzer → skill_scanner}/core/reporters/json_reporter.py +0 -0
  94. {skillanalyzer → skill_scanner}/core/rules/__init__.py +0 -0
  95. {skillanalyzer → skill_scanner}/core/rules/patterns.py +0 -0
  96. {skillanalyzer → skill_scanner}/core/static_analysis/__init__.py +0 -0
  97. {skillanalyzer → skill_scanner}/core/static_analysis/cfg/__init__.py +0 -0
  98. {skillanalyzer → skill_scanner}/core/static_analysis/cfg/builder.py +0 -0
  99. {skillanalyzer → skill_scanner}/core/static_analysis/dataflow/forward_analysis.py +0 -0
  100. {skillanalyzer → skill_scanner}/core/static_analysis/interprocedural/__init__.py +0 -0
  101. {skillanalyzer → skill_scanner}/core/static_analysis/interprocedural/cross_file_analyzer.py +0 -0
  102. {skillanalyzer → skill_scanner}/core/static_analysis/parser/__init__.py +0 -0
  103. {skillanalyzer → skill_scanner}/core/static_analysis/semantic/__init__.py +0 -0
  104. {skillanalyzer → skill_scanner}/core/static_analysis/semantic/name_resolver.py +0 -0
  105. {skillanalyzer → skill_scanner}/core/static_analysis/semantic/type_analyzer.py +0 -0
  106. {skillanalyzer → skill_scanner}/core/static_analysis/taint/__init__.py +0 -0
  107. {skillanalyzer → skill_scanner}/core/static_analysis/taint/tracker.py +0 -0
  108. {skillanalyzer → skill_scanner}/core/static_analysis/types/__init__.py +0 -0
  109. {skillanalyzer → skill_scanner}/utils/file_utils.py +0 -0
  110. {skillanalyzer → skill_scanner}/utils/logging_utils.py +0 -0
@@ -14,10 +14,10 @@
14
14
  #
15
15
  # SPDX-License-Identifier: Apache-2.0
16
16
 
17
- """Configuration parser for Skill Analyzer.
17
+ """Configuration parser for Skill Scanner.
18
18
 
19
19
  This module provides functionality to parse configuration files
20
- and environment variables for Skill Analyzer.
20
+ and environment variables for Skill Scanner.
21
21
  """
22
22
 
23
23
  import os
@@ -25,7 +25,7 @@ from pathlib import Path
25
25
 
26
26
  from ..utils.logging_config import get_logger
27
27
  from .config import Config
28
- from .constants import SkillAnalyzerConstants
28
+ from .constants import SkillScannerConstants
29
29
 
30
30
  logger = get_logger(__name__)
31
31
 
@@ -74,10 +74,10 @@ def parse_config_file(config_path: str | None = None) -> Config:
74
74
  if not config_path:
75
75
  # Try to find default config file
76
76
  default_paths = [
77
- Path.home() / ".skillanalyzer" / "config.yaml",
78
- Path.home() / ".skillanalyzer" / "config.json",
79
- Path.cwd() / ".skillanalyzer.yaml",
80
- Path.cwd() / ".skillanalyzer.json",
77
+ Path.home() / ".skill_scanner" / "config.yaml",
78
+ Path.home() / ".skill_scanner" / "config.json",
79
+ Path.cwd() / ".skill_scanner.yaml",
80
+ Path.cwd() / ".skill_scanner.json",
81
81
  ]
82
82
 
83
83
  for path in default_paths:
@@ -96,11 +96,11 @@ def parse_config_file(config_path: str | None = None) -> Config:
96
96
 
97
97
 
98
98
  class ConfigParser:
99
- """Parser for Skill Analyzer configuration files."""
99
+ """Parser for Skill Scanner configuration files."""
100
100
 
101
101
  def __init__(self):
102
102
  """Initialize the config parser."""
103
- self.constants = SkillAnalyzerConstants
103
+ self.constants = SkillScannerConstants
104
104
 
105
105
  def parse(self, config_path: str | None = None) -> Config:
106
106
  """Parse configuration from file and environment.
@@ -15,7 +15,7 @@
15
15
  # SPDX-License-Identifier: Apache-2.0
16
16
 
17
17
  """
18
- Constants for Claude Skill Analyzer.
18
+ Constants for Skill Scanner.
19
19
 
20
20
  Mirrors MCP Scanner's constants structure.
21
21
  """
@@ -23,7 +23,7 @@ Mirrors MCP Scanner's constants structure.
23
23
  from pathlib import Path
24
24
 
25
25
 
26
- class SkillAnalyzerConstants:
26
+ class SkillScannerConstants:
27
27
  """Constants used throughout the analyzer."""
28
28
 
29
29
  # Version
@@ -0,0 +1,314 @@
1
+ # Copyright 2026 Cisco Systems, Inc. and its affiliates
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
+ YARA Mode Configuration System
19
+
20
+ Provides configurable detection modes to balance false positives vs true positives:
21
+ - STRICT: Maximum security, higher false positives acceptable
22
+ - BALANCED: Default mode, good tradeoff between FP and TP
23
+ - PERMISSIVE: Minimize false positives, may miss some threats
24
+ - CUSTOM: User-defined thresholds
25
+
26
+ Each mode configures:
27
+ - Rule-specific thresholds
28
+ - Post-processing filters
29
+ - Enabled/disabled rule sets
30
+ """
31
+
32
+ from dataclasses import dataclass, field
33
+ from enum import Enum
34
+ from typing import Optional
35
+
36
+
37
+ class YaraMode(Enum):
38
+ """YARA detection mode presets."""
39
+
40
+ STRICT = "strict"
41
+ BALANCED = "balanced"
42
+ PERMISSIVE = "permissive"
43
+ CUSTOM = "custom"
44
+
45
+
46
+ @dataclass
47
+ class UnicodeStegConfig:
48
+ """Configuration for unicode steganography detection."""
49
+
50
+ # Zero-width character thresholds
51
+ zerowidth_threshold_with_decode: int = 50 # When dangerous code is present
52
+ zerowidth_threshold_alone: int = 200 # Without dangerous code context
53
+
54
+ # Enable/disable specific patterns
55
+ detect_rtl_override: bool = True
56
+ detect_ltl_override: bool = True
57
+ detect_line_separators: bool = True
58
+ detect_unicode_tags: bool = True
59
+ detect_variation_selectors: bool = True
60
+
61
+
62
+ @dataclass
63
+ class CredentialHarvestingConfig:
64
+ """Configuration for credential harvesting detection."""
65
+
66
+ # Placeholder filtering
67
+ filter_placeholder_patterns: bool = True
68
+
69
+ # Specific API key patterns
70
+ detect_ai_api_keys: bool = True
71
+ detect_aws_keys: bool = True
72
+ detect_ssh_keys: bool = True
73
+ detect_env_exfiltration: bool = True
74
+
75
+
76
+ @dataclass
77
+ class ToolChainingConfig:
78
+ """Configuration for tool chaining abuse detection."""
79
+
80
+ # Post-filter settings
81
+ filter_api_documentation: bool = True
82
+ filter_generic_http_verbs: bool = True
83
+ filter_email_field_mentions: bool = True
84
+
85
+ # Pattern detection
86
+ detect_read_send: bool = True
87
+ detect_collect_exfil: bool = True
88
+ detect_env_network: bool = True
89
+
90
+
91
+ @dataclass
92
+ class YaraModeConfig:
93
+ """Complete YARA mode configuration."""
94
+
95
+ mode: YaraMode = YaraMode.BALANCED
96
+ description: str = ""
97
+
98
+ # Rule-specific configs
99
+ unicode_steg: UnicodeStegConfig = field(default_factory=UnicodeStegConfig)
100
+ credential_harvesting: CredentialHarvestingConfig = field(default_factory=CredentialHarvestingConfig)
101
+ tool_chaining: ToolChainingConfig = field(default_factory=ToolChainingConfig)
102
+
103
+ # Global settings
104
+ enabled_rules: set[str] = field(default_factory=set) # Empty = all enabled
105
+ disabled_rules: set[str] = field(default_factory=set)
106
+
107
+ @classmethod
108
+ def strict(cls) -> "YaraModeConfig":
109
+ """
110
+ STRICT mode: Maximum security, accept higher FP rate.
111
+
112
+ Use when:
113
+ - Scanning untrusted/external skills
114
+ - Security audit requirements
115
+ - Compliance scanning
116
+ """
117
+ return cls(
118
+ mode=YaraMode.STRICT,
119
+ description="Maximum security - flags more potential threats",
120
+ unicode_steg=UnicodeStegConfig(
121
+ zerowidth_threshold_with_decode=20, # Lower threshold
122
+ zerowidth_threshold_alone=100,
123
+ ),
124
+ credential_harvesting=CredentialHarvestingConfig(
125
+ filter_placeholder_patterns=False, # Don't filter - flag for review
126
+ ),
127
+ tool_chaining=ToolChainingConfig(
128
+ filter_api_documentation=False,
129
+ filter_generic_http_verbs=False,
130
+ ),
131
+ )
132
+
133
+ @classmethod
134
+ def balanced(cls) -> "YaraModeConfig":
135
+ """
136
+ BALANCED mode: Default - good tradeoff between FP and TP.
137
+
138
+ Use when:
139
+ - Regular skill scanning
140
+ - CI/CD pipeline integration
141
+ - Development workflow
142
+ """
143
+ return cls(
144
+ mode=YaraMode.BALANCED,
145
+ description="Balanced detection - default mode",
146
+ unicode_steg=UnicodeStegConfig(
147
+ zerowidth_threshold_with_decode=50,
148
+ zerowidth_threshold_alone=200,
149
+ ),
150
+ credential_harvesting=CredentialHarvestingConfig(
151
+ filter_placeholder_patterns=True,
152
+ ),
153
+ tool_chaining=ToolChainingConfig(
154
+ filter_api_documentation=True,
155
+ filter_generic_http_verbs=True,
156
+ filter_email_field_mentions=True,
157
+ ),
158
+ )
159
+
160
+ @classmethod
161
+ def permissive(cls) -> "YaraModeConfig":
162
+ """
163
+ PERMISSIVE mode: Minimize false positives.
164
+
165
+ Use when:
166
+ - Scanning trusted/internal skills
167
+ - High FP rate is disrupting workflow
168
+ - Focus on critical threats only
169
+ """
170
+ return cls(
171
+ mode=YaraMode.PERMISSIVE,
172
+ description="Minimal false positives - may miss some threats",
173
+ unicode_steg=UnicodeStegConfig(
174
+ zerowidth_threshold_with_decode=100, # Higher threshold
175
+ zerowidth_threshold_alone=500,
176
+ detect_line_separators=False, # Common in some content
177
+ ),
178
+ credential_harvesting=CredentialHarvestingConfig(
179
+ filter_placeholder_patterns=True,
180
+ ),
181
+ tool_chaining=ToolChainingConfig(
182
+ filter_api_documentation=True,
183
+ filter_generic_http_verbs=True,
184
+ filter_email_field_mentions=True,
185
+ ),
186
+ # Disable noisier rules
187
+ disabled_rules={
188
+ "capability_inflation_generic",
189
+ "indirect_prompt_injection_generic",
190
+ },
191
+ )
192
+
193
+ @classmethod
194
+ def custom(
195
+ cls,
196
+ unicode_steg: UnicodeStegConfig | None = None,
197
+ credential_harvesting: CredentialHarvestingConfig | None = None,
198
+ tool_chaining: ToolChainingConfig | None = None,
199
+ enabled_rules: set[str] | None = None,
200
+ disabled_rules: set[str] | None = None,
201
+ ) -> "YaraModeConfig":
202
+ """
203
+ CUSTOM mode: User-defined configuration.
204
+
205
+ Args:
206
+ unicode_steg: Unicode steganography config
207
+ credential_harvesting: Credential harvesting config
208
+ tool_chaining: Tool chaining config
209
+ enabled_rules: Set of rule names to enable (empty = all)
210
+ disabled_rules: Set of rule names to disable
211
+ """
212
+ return cls(
213
+ mode=YaraMode.CUSTOM,
214
+ description="Custom user-defined configuration",
215
+ unicode_steg=unicode_steg or UnicodeStegConfig(),
216
+ credential_harvesting=credential_harvesting or CredentialHarvestingConfig(),
217
+ tool_chaining=tool_chaining or ToolChainingConfig(),
218
+ enabled_rules=enabled_rules or set(),
219
+ disabled_rules=disabled_rules or set(),
220
+ )
221
+
222
+ @classmethod
223
+ def from_mode_name(cls, mode_name: str) -> "YaraModeConfig":
224
+ """Create config from mode name string."""
225
+ mode_map = {
226
+ "strict": cls.strict,
227
+ "balanced": cls.balanced,
228
+ "permissive": cls.permissive,
229
+ }
230
+ if mode_name.lower() in mode_map:
231
+ return mode_map[mode_name.lower()]()
232
+ raise ValueError(f"Unknown mode: {mode_name}. Use: strict, balanced, permissive, or custom")
233
+
234
+ def is_rule_enabled(self, rule_name: str) -> bool:
235
+ """Check if a specific rule is enabled in this mode."""
236
+ # If enabled_rules is specified, only those are allowed
237
+ if self.enabled_rules and rule_name not in self.enabled_rules:
238
+ return False
239
+ # Check if explicitly disabled
240
+ if rule_name in self.disabled_rules:
241
+ return False
242
+ return True
243
+
244
+ def to_dict(self) -> dict:
245
+ """Convert config to dictionary for serialization."""
246
+ return {
247
+ "mode": self.mode.value,
248
+ "description": self.description,
249
+ "unicode_steg": {
250
+ "zerowidth_threshold_with_decode": self.unicode_steg.zerowidth_threshold_with_decode,
251
+ "zerowidth_threshold_alone": self.unicode_steg.zerowidth_threshold_alone,
252
+ "detect_rtl_override": self.unicode_steg.detect_rtl_override,
253
+ "detect_ltl_override": self.unicode_steg.detect_ltl_override,
254
+ "detect_line_separators": self.unicode_steg.detect_line_separators,
255
+ "detect_unicode_tags": self.unicode_steg.detect_unicode_tags,
256
+ "detect_variation_selectors": self.unicode_steg.detect_variation_selectors,
257
+ },
258
+ "credential_harvesting": {
259
+ "filter_placeholder_patterns": self.credential_harvesting.filter_placeholder_patterns,
260
+ "detect_ai_api_keys": self.credential_harvesting.detect_ai_api_keys,
261
+ "detect_aws_keys": self.credential_harvesting.detect_aws_keys,
262
+ "detect_ssh_keys": self.credential_harvesting.detect_ssh_keys,
263
+ "detect_env_exfiltration": self.credential_harvesting.detect_env_exfiltration,
264
+ },
265
+ "tool_chaining": {
266
+ "filter_api_documentation": self.tool_chaining.filter_api_documentation,
267
+ "filter_generic_http_verbs": self.tool_chaining.filter_generic_http_verbs,
268
+ "filter_email_field_mentions": self.tool_chaining.filter_email_field_mentions,
269
+ "detect_read_send": self.tool_chaining.detect_read_send,
270
+ "detect_collect_exfil": self.tool_chaining.detect_collect_exfil,
271
+ "detect_env_network": self.tool_chaining.detect_env_network,
272
+ },
273
+ "enabled_rules": list(self.enabled_rules),
274
+ "disabled_rules": list(self.disabled_rules),
275
+ }
276
+
277
+
278
+ # Default mode
279
+ DEFAULT_YARA_MODE = YaraModeConfig.balanced()
280
+
281
+
282
+ # Mode descriptions for CLI/API documentation
283
+ MODE_DESCRIPTIONS = {
284
+ "strict": """
285
+ STRICT Mode - Maximum Security
286
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
287
+ • Lower detection thresholds
288
+ • Minimal post-processing filters
289
+ • Flags more potential threats
290
+ • Higher false positive rate acceptable
291
+
292
+ Use for: Untrusted skills, security audits, compliance
293
+ """,
294
+ "balanced": """
295
+ BALANCED Mode - Default
296
+ ━━━━━━━━━━━━━━━━━━━━━━━
297
+ • Moderate detection thresholds
298
+ • Context-aware post-processing
299
+ • Good tradeoff between FP and TP
300
+ • Suitable for most use cases
301
+
302
+ Use for: Regular scanning, CI/CD, development
303
+ """,
304
+ "permissive": """
305
+ PERMISSIVE Mode - Minimal False Positives
306
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
307
+ • Higher detection thresholds
308
+ • Aggressive filtering
309
+ • Focus on critical threats only
310
+ • May miss some edge-case threats
311
+
312
+ Use for: Trusted skills, high FP disruption
313
+ """,
314
+ }
@@ -15,7 +15,7 @@
15
15
  # SPDX-License-Identifier: Apache-2.0
16
16
 
17
17
  """
18
- Core functionality for Claude Skill Analyzer.
18
+ Core functionality for Skill Scanner.
19
19
 
20
20
  This module contains the core components including analyzers, scanner engine,
21
21
  and data models.
@@ -15,7 +15,7 @@
15
15
  # SPDX-License-Identifier: Apache-2.0
16
16
 
17
17
  """
18
- Analyzer modules for detecting security vulnerabilities in Claude Skills.
18
+ Analyzer modules for detecting security vulnerabilities in agent skills.
19
19
 
20
20
  Structure mirrors MCP Scanner's analyzer organization.
21
21
  """
@@ -61,9 +61,9 @@ except (ImportError, ModuleNotFoundError):
61
61
  pass
62
62
 
63
63
  try:
64
- from .cross_skill_analyzer import CrossSkillAnalyzer # noqa: F401
64
+ from .cross_skill_scanner import CrossSkillScanner # noqa: F401
65
65
 
66
- __all__.append("CrossSkillAnalyzer")
66
+ __all__.append("CrossSkillScanner")
67
67
  except (ImportError, ModuleNotFoundError):
68
68
  pass
69
69
 
@@ -15,7 +15,7 @@
15
15
  # SPDX-License-Identifier: Apache-2.0
16
16
 
17
17
  """
18
- AI Defense API analyzer for Claude Skills security scanning.
18
+ AI Defense API analyzer for agent skills security scanning.
19
19
 
20
20
  Integrates with Cisco AI Defense API (https://api.aidefense.cisco.com) for:
21
21
  - Prompt injection detection
@@ -325,7 +325,7 @@ class AIDefenseAnalyzer(BaseAnalyzer):
325
325
  }
326
326
  ]
327
327
  metadata = {
328
- "source": "skill_analyzer",
328
+ "source": "skill_scanner",
329
329
  "skill_name": skill_name,
330
330
  "file_path": file_path,
331
331
  "content_type": content_type,
@@ -465,7 +465,7 @@ class AIDefenseAnalyzer(BaseAnalyzer):
465
465
  {"role": "user", "content": f"# Code Analysis for {file_path}\n```{language}\n{content[:15000]}\n```"}
466
466
  ]
467
467
  metadata = {
468
- "source": "skill_analyzer",
468
+ "source": "skill_scanner",
469
469
  "skill_name": skill_name,
470
470
  "file_path": file_path,
471
471
  "language": language,
@@ -14,7 +14,7 @@
14
14
  #
15
15
  # SPDX-License-Identifier: Apache-2.0
16
16
 
17
- """Behavioral Analysis Package for Claude Skills.
17
+ """Behavioral Analysis Package for Agent Skills.
18
18
 
19
19
  This package provides enhanced behavioral analysis capabilities including:
20
20
  - Alignment verification between skill description and code behavior
@@ -192,7 +192,7 @@ class AlignmentLLMClient:
192
192
  {
193
193
  "role": "system",
194
194
  "content": (
195
- "You are a security expert analyzing Claude Skills. "
195
+ "You are a security expert analyzing agent skills. "
196
196
  "You receive complete dataflow analysis and code context. "
197
197
  "Analyze if the skill description accurately describes what the code actually does. "
198
198
  "Respond ONLY with valid JSON. Do not include any markdown formatting or code blocks."
@@ -378,9 +378,9 @@ Parameter Flow Tracking:
378
378
  Returns:
379
379
  Embedded prompt template
380
380
  """
381
- return """# Claude Skill Alignment Analysis
381
+ return """# Agent Skill Alignment Analysis
382
382
 
383
- You are a security expert analyzing Claude Skills for alignment mismatches between their
383
+ You are a security expert analyzing agent skills for alignment mismatches between their
384
384
  described behavior and actual implementation.
385
385
 
386
386
  ## Your Task
@@ -15,7 +15,7 @@
15
15
  # SPDX-License-Identifier: Apache-2.0
16
16
 
17
17
  """
18
- Behavioral analyzer for Claude Skills using static dataflow analysis.
18
+ Behavioral analyzer for agent skills using static dataflow analysis.
19
19
 
20
20
  Analyzes skill scripts using AST parsing, dataflow tracking, and description-behavior
21
21
  alignment checking. Detects threats through code analysis without execution.
@@ -15,7 +15,7 @@
15
15
  # SPDX-License-Identifier: Apache-2.0
16
16
 
17
17
  """
18
- Cross-skill analyzer for detecting coordinated attacks across multiple skills.
18
+ Cross-skill scanner for detecting coordinated attacks across multiple skills.
19
19
 
20
20
  This analyzer looks for patterns that suggest multiple skills are working together
21
21
  to perform malicious activities, such as:
@@ -30,7 +30,7 @@ from ..models import Finding, Severity, Skill, ThreatCategory
30
30
  from .base import BaseAnalyzer
31
31
 
32
32
 
33
- class CrossSkillAnalyzer(BaseAnalyzer):
33
+ class CrossSkillScanner(BaseAnalyzer):
34
34
  """
35
35
  Analyzes multiple skills together to detect coordinated attack patterns.
36
36
 
@@ -40,13 +40,13 @@ class CrossSkillAnalyzer(BaseAnalyzer):
40
40
  """
41
41
 
42
42
  def __init__(self):
43
- """Initialize cross-skill analyzer."""
44
- super().__init__("cross_skill_analyzer")
43
+ """Initialize cross-skill scanner."""
44
+ super().__init__("cross_skill_scanner")
45
45
  self._skills: list[Skill] = []
46
46
 
47
47
  def analyze(self, skill: Skill) -> list[Finding]:
48
48
  """
49
- Analyze a single skill (no-op for cross-skill analyzer).
49
+ Analyze a single skill (no-op for cross-skill scanner).
50
50
 
51
51
  This analyzer only produces findings when analyzing skill sets.
52
52
  Call analyze_skill_set() instead.
@@ -273,16 +273,16 @@ class LLMAnalyzer(BaseAnalyzer):
273
273
  messages = [
274
274
  {
275
275
  "role": "system",
276
- "content": """You are a security expert analyzing Claude Skills. Follow the analysis framework provided.
276
+ "content": """You are a security expert analyzing agent skills. Follow the analysis framework provided.
277
277
 
278
278
  When selecting AITech codes for findings, use these mappings:
279
279
  - AITech-1.1: Direct prompt injection in SKILL.md (jailbreak, instruction override)
280
- - AITech-1.2: Indirect prompt injection (transitive trust, following untrusted content)
281
- - AITech-2.1: Social engineering (deceptive descriptions/metadata)
280
+ - AITech-1.2: Indirect prompt injection - instruction manipulation (embedding malicious instructions in external sources)
281
+ - AITech-4.3: Protocol manipulation - capability inflation (skill discovery abuse, keyword baiting, over-broad claims)
282
282
  - AITech-8.2: Data exfiltration/exposure (unauthorized access, credential theft, hardcoded secrets)
283
283
  - AITech-9.1: Model/agentic manipulation (command injection, code injection, SQL injection, obfuscation)
284
284
  - AITech-12.1: Tool exploitation (tool poisoning, shadowing, unauthorized use)
285
- - AITech-13.3: Availability disruption (resource abuse, DoS, infinite loops)
285
+ - AITech-13.1: Disruption of Availability (resource abuse, DoS, infinite loops) - AISubtech-13.1.1: Compute Exhaustion
286
286
  - AITech-15.1: Harmful/misleading content (deceptive content, misinformation)
287
287
 
288
288
  The structured output schema will enforce these exact codes.""",
@@ -47,7 +47,7 @@ class PromptBuilder:
47
47
  self.protection_rules = protection_file.read_text(encoding="utf-8")
48
48
  else:
49
49
  print(f"Warning: Protection rules file not found at {protection_file}")
50
- self.protection_rules = "You are a security analyst analyzing Claude Skills."
50
+ self.protection_rules = "You are a security analyst analyzing agent skills."
51
51
 
52
52
  if threat_file.exists():
53
53
  self.threat_analysis_prompt = threat_file.read_text(encoding="utf-8")
@@ -57,7 +57,7 @@ class PromptBuilder:
57
57
 
58
58
  except Exception as e:
59
59
  print(f"Warning: Failed to load prompts: {e}")
60
- self.protection_rules = "You are a security analyst analyzing Claude Skills."
60
+ self.protection_rules = "You are a security analyst analyzing agent skills."
61
61
  self.threat_analysis_prompt = "Analyze for security threats."
62
62
 
63
63
  def build_threat_analysis_prompt(