@elizaos/skills 2.0.0-alpha.3
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.
- package/README.md +126 -0
- package/package.json +53 -0
- package/skills/1password/SKILL.md +70 -0
- package/skills/1password/references/cli-examples.md +29 -0
- package/skills/1password/references/get-started.md +17 -0
- package/skills/apple-notes/SKILL.md +77 -0
- package/skills/apple-reminders/SKILL.md +96 -0
- package/skills/bear-notes/SKILL.md +107 -0
- package/skills/bird/SKILL.md +224 -0
- package/skills/blogwatcher/SKILL.md +69 -0
- package/skills/blucli/SKILL.md +47 -0
- package/skills/bluebubbles/SKILL.md +131 -0
- package/skills/camsnap/SKILL.md +45 -0
- package/skills/canvas/SKILL.md +203 -0
- package/skills/clawhub/SKILL.md +77 -0
- package/skills/coding-agent/SKILL.md +284 -0
- package/skills/discord/SKILL.md +578 -0
- package/skills/eightctl/SKILL.md +50 -0
- package/skills/food-order/SKILL.md +48 -0
- package/skills/gemini/SKILL.md +43 -0
- package/skills/gifgrep/SKILL.md +79 -0
- package/skills/github/SKILL.md +77 -0
- package/skills/gog/SKILL.md +116 -0
- package/skills/goplaces/SKILL.md +52 -0
- package/skills/healthcheck/SKILL.md +245 -0
- package/skills/himalaya/SKILL.md +257 -0
- package/skills/himalaya/references/configuration.md +184 -0
- package/skills/himalaya/references/message-composition.md +199 -0
- package/skills/imsg/SKILL.md +74 -0
- package/skills/local-places/SERVER_README.md +101 -0
- package/skills/local-places/SKILL.md +102 -0
- package/skills/local-places/pyproject.toml +21 -0
- package/skills/local-places/src/local_places/__init__.py +2 -0
- package/skills/local-places/src/local_places/google_places.py +314 -0
- package/skills/local-places/src/local_places/main.py +65 -0
- package/skills/local-places/src/local_places/schemas.py +107 -0
- package/skills/mcporter/SKILL.md +61 -0
- package/skills/model-usage/SKILL.md +69 -0
- package/skills/model-usage/references/codexbar-cli.md +33 -0
- package/skills/model-usage/scripts/model_usage.py +310 -0
- package/skills/nano-banana-pro/SKILL.md +58 -0
- package/skills/nano-banana-pro/scripts/generate_image.py +184 -0
- package/skills/nano-pdf/SKILL.md +38 -0
- package/skills/notion/SKILL.md +172 -0
- package/skills/obsidian/SKILL.md +81 -0
- package/skills/openai-image-gen/SKILL.md +89 -0
- package/skills/openai-image-gen/scripts/gen.py +240 -0
- package/skills/openai-whisper/SKILL.md +38 -0
- package/skills/openai-whisper-api/SKILL.md +52 -0
- package/skills/openai-whisper-api/scripts/transcribe.sh +85 -0
- package/skills/openhue/SKILL.md +51 -0
- package/skills/oracle/SKILL.md +125 -0
- package/skills/ordercli/SKILL.md +78 -0
- package/skills/peekaboo/SKILL.md +190 -0
- package/skills/sag/SKILL.md +87 -0
- package/skills/security-ask-questions-if-underspecified/.claude-plugin/plugin.json +10 -0
- package/skills/security-ask-questions-if-underspecified/README.md +24 -0
- package/skills/security-ask-questions-if-underspecified/skills/ask-questions-if-underspecified/SKILL.md +85 -0
- package/skills/security-audit-context-building/.claude-plugin/plugin.json +10 -0
- package/skills/security-audit-context-building/README.md +58 -0
- package/skills/security-audit-context-building/commands/audit-context.md +21 -0
- package/skills/security-audit-context-building/skills/audit-context-building/SKILL.md +297 -0
- package/skills/security-audit-context-building/skills/audit-context-building/resources/COMPLETENESS_CHECKLIST.md +47 -0
- package/skills/security-audit-context-building/skills/audit-context-building/resources/FUNCTION_MICRO_ANALYSIS_EXAMPLE.md +355 -0
- package/skills/security-audit-context-building/skills/audit-context-building/resources/OUTPUT_REQUIREMENTS.md +71 -0
- package/skills/security-building-secure-contracts/.claude-plugin/plugin.json +10 -0
- package/skills/security-building-secure-contracts/README.md +241 -0
- package/skills/security-building-secure-contracts/skills/algorand-vulnerability-scanner/SKILL.md +284 -0
- package/skills/security-building-secure-contracts/skills/algorand-vulnerability-scanner/resources/VULNERABILITY_PATTERNS.md +405 -0
- package/skills/security-building-secure-contracts/skills/audit-prep-assistant/SKILL.md +409 -0
- package/skills/security-building-secure-contracts/skills/cairo-vulnerability-scanner/SKILL.md +329 -0
- package/skills/security-building-secure-contracts/skills/cairo-vulnerability-scanner/resources/VULNERABILITY_PATTERNS.md +722 -0
- package/skills/security-building-secure-contracts/skills/code-maturity-assessor/SKILL.md +218 -0
- package/skills/security-building-secure-contracts/skills/code-maturity-assessor/resources/ASSESSMENT_CRITERIA.md +355 -0
- package/skills/security-building-secure-contracts/skills/code-maturity-assessor/resources/EXAMPLE_REPORT.md +248 -0
- package/skills/security-building-secure-contracts/skills/code-maturity-assessor/resources/REPORT_FORMAT.md +33 -0
- package/skills/security-building-secure-contracts/skills/cosmos-vulnerability-scanner/SKILL.md +334 -0
- package/skills/security-building-secure-contracts/skills/cosmos-vulnerability-scanner/resources/VULNERABILITY_PATTERNS.md +740 -0
- package/skills/security-building-secure-contracts/skills/guidelines-advisor/SKILL.md +252 -0
- package/skills/security-building-secure-contracts/skills/guidelines-advisor/resources/ASSESSMENT_AREAS.md +329 -0
- package/skills/security-building-secure-contracts/skills/guidelines-advisor/resources/DELIVERABLES.md +118 -0
- package/skills/security-building-secure-contracts/skills/guidelines-advisor/resources/EXAMPLE_REPORT.md +298 -0
- package/skills/security-building-secure-contracts/skills/secure-workflow-guide/SKILL.md +161 -0
- package/skills/security-building-secure-contracts/skills/secure-workflow-guide/resources/EXAMPLE_REPORT.md +279 -0
- package/skills/security-building-secure-contracts/skills/secure-workflow-guide/resources/WORKFLOW_STEPS.md +132 -0
- package/skills/security-building-secure-contracts/skills/solana-vulnerability-scanner/SKILL.md +389 -0
- package/skills/security-building-secure-contracts/skills/solana-vulnerability-scanner/resources/VULNERABILITY_PATTERNS.md +669 -0
- package/skills/security-building-secure-contracts/skills/substrate-vulnerability-scanner/SKILL.md +298 -0
- package/skills/security-building-secure-contracts/skills/substrate-vulnerability-scanner/resources/VULNERABILITY_PATTERNS.md +791 -0
- package/skills/security-building-secure-contracts/skills/token-integration-analyzer/SKILL.md +362 -0
- package/skills/security-building-secure-contracts/skills/token-integration-analyzer/resources/ASSESSMENT_CATEGORIES.md +571 -0
- package/skills/security-building-secure-contracts/skills/token-integration-analyzer/resources/REPORT_TEMPLATES.md +141 -0
- package/skills/security-building-secure-contracts/skills/ton-vulnerability-scanner/SKILL.md +388 -0
- package/skills/security-building-secure-contracts/skills/ton-vulnerability-scanner/resources/VULNERABILITY_PATTERNS.md +595 -0
- package/skills/security-burpsuite-project-parser/.claude-plugin/plugin.json +10 -0
- package/skills/security-burpsuite-project-parser/README.md +103 -0
- package/skills/security-burpsuite-project-parser/commands/burp-search.md +18 -0
- package/skills/security-burpsuite-project-parser/skills/SKILL.md +358 -0
- package/skills/security-burpsuite-project-parser/skills/scripts/burp-search.sh +99 -0
- package/skills/security-claude-in-chrome-troubleshooting/.claude-plugin/plugin.json +8 -0
- package/skills/security-claude-in-chrome-troubleshooting/README.md +31 -0
- package/skills/security-claude-in-chrome-troubleshooting/skills/claude-in-chrome-troubleshooting/SKILL.md +251 -0
- package/skills/security-constant-time-analysis/.claude-plugin/plugin.json +9 -0
- package/skills/security-constant-time-analysis/README.md +381 -0
- package/skills/security-constant-time-analysis/commands/ct-check.md +20 -0
- package/skills/security-constant-time-analysis/ct_analyzer/__init__.py +49 -0
- package/skills/security-constant-time-analysis/ct_analyzer/analyzer.py +1284 -0
- package/skills/security-constant-time-analysis/ct_analyzer/script_analyzers.py +3081 -0
- package/skills/security-constant-time-analysis/ct_analyzer/tests/__init__.py +1 -0
- package/skills/security-constant-time-analysis/ct_analyzer/tests/test_analyzer.py +1397 -0
- package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/bn_excerpt.js +205 -0
- package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/decompose_constant_time.c +181 -0
- package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/decompose_vulnerable.c +74 -0
- package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/decompose_vulnerable.go +78 -0
- package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/decompose_vulnerable.rs +92 -0
- package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/vulnerable.cs +174 -0
- package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/vulnerable.java +161 -0
- package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/vulnerable.kt +181 -0
- package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/vulnerable.php +140 -0
- package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/vulnerable.py +252 -0
- package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/vulnerable.rb +188 -0
- package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/vulnerable.swift +199 -0
- package/skills/security-constant-time-analysis/ct_analyzer/tests/test_samples/vulnerable.ts +154 -0
- package/skills/security-constant-time-analysis/pyproject.toml +52 -0
- package/skills/security-constant-time-analysis/skills/constant-time-analysis/README.md +90 -0
- package/skills/security-constant-time-analysis/skills/constant-time-analysis/SKILL.md +219 -0
- package/skills/security-constant-time-analysis/skills/constant-time-analysis/references/compiled.md +129 -0
- package/skills/security-constant-time-analysis/skills/constant-time-analysis/references/javascript.md +136 -0
- package/skills/security-constant-time-analysis/skills/constant-time-analysis/references/kotlin.md +252 -0
- package/skills/security-constant-time-analysis/skills/constant-time-analysis/references/php.md +172 -0
- package/skills/security-constant-time-analysis/skills/constant-time-analysis/references/python.md +179 -0
- package/skills/security-constant-time-analysis/skills/constant-time-analysis/references/ruby.md +198 -0
- package/skills/security-constant-time-analysis/skills/constant-time-analysis/references/swift.md +288 -0
- package/skills/security-constant-time-analysis/skills/constant-time-analysis/references/vm-compiled.md +354 -0
- package/skills/security-constant-time-analysis/uv.lock +8 -0
- package/skills/security-culture-index/.claude-plugin/plugin.json +8 -0
- package/skills/security-culture-index/README.md +79 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/SKILL.md +293 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/references/anti-patterns.md +255 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/references/conversation-starters.md +408 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/references/interview-trait-signals.md +253 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/references/motivators.md +158 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/references/patterns-archetypes.md +147 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/references/primary-traits.md +307 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/references/secondary-traits.md +228 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/references/team-composition.md +148 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/scripts/check_deps.py +108 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/scripts/culture_index/__init__.py +20 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/scripts/culture_index/constants.py +122 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/scripts/culture_index/extract.py +187 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/scripts/culture_index/models.py +16 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/scripts/culture_index/opencv_extractor.py +520 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/scripts/extract_pdf.py +237 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/scripts/pyproject.toml +18 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/templates/burnout-report.md +113 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/templates/comparison-report.md +103 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/templates/hiring-profile.md +127 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/templates/individual-report.md +85 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/templates/predicted-profile.md +165 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/templates/team-report.md +109 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/workflows/analyze-team.md +188 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/workflows/coach-manager.md +267 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/workflows/compare-profiles.md +188 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/workflows/define-hiring-profile.md +220 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/workflows/detect-burnout.md +206 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/workflows/extract-from-pdf.md +121 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/workflows/interpret-individual.md +183 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/workflows/interview-debrief.md +234 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/workflows/mediate-conflict.md +306 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/workflows/plan-onboarding.md +322 -0
- package/skills/security-culture-index/skills/interpreting-culture-index/workflows/predict-from-interview.md +250 -0
- package/skills/security-differential-review/.claude-plugin/plugin.json +10 -0
- package/skills/security-differential-review/README.md +109 -0
- package/skills/security-differential-review/commands/diff-review.md +21 -0
- package/skills/security-differential-review/skills/differential-review/SKILL.md +220 -0
- package/skills/security-differential-review/skills/differential-review/adversarial.md +203 -0
- package/skills/security-differential-review/skills/differential-review/methodology.md +234 -0
- package/skills/security-differential-review/skills/differential-review/patterns.md +300 -0
- package/skills/security-differential-review/skills/differential-review/reporting.md +369 -0
- package/skills/security-dwarf-expert/.claude-plugin/plugin.json +10 -0
- package/skills/security-dwarf-expert/README.md +38 -0
- package/skills/security-dwarf-expert/skills/dwarf-expert/SKILL.md +93 -0
- package/skills/security-dwarf-expert/skills/dwarf-expert/reference/coding.md +31 -0
- package/skills/security-dwarf-expert/skills/dwarf-expert/reference/dwarfdump.md +50 -0
- package/skills/security-dwarf-expert/skills/dwarf-expert/reference/readelf.md +8 -0
- package/skills/security-entry-point-analyzer/.claude-plugin/plugin.json +10 -0
- package/skills/security-entry-point-analyzer/README.md +74 -0
- package/skills/security-entry-point-analyzer/commands/entry-points.md +18 -0
- package/skills/security-entry-point-analyzer/skills/entry-point-analyzer/SKILL.md +251 -0
- package/skills/security-entry-point-analyzer/skills/entry-point-analyzer/references/cosmwasm.md +182 -0
- package/skills/security-entry-point-analyzer/skills/entry-point-analyzer/references/move-aptos.md +107 -0
- package/skills/security-entry-point-analyzer/skills/entry-point-analyzer/references/move-sui.md +87 -0
- package/skills/security-entry-point-analyzer/skills/entry-point-analyzer/references/solana.md +155 -0
- package/skills/security-entry-point-analyzer/skills/entry-point-analyzer/references/solidity.md +135 -0
- package/skills/security-entry-point-analyzer/skills/entry-point-analyzer/references/ton.md +185 -0
- package/skills/security-entry-point-analyzer/skills/entry-point-analyzer/references/vyper.md +141 -0
- package/skills/security-firebase-apk-scanner/.claude-plugin/plugin.json +10 -0
- package/skills/security-firebase-apk-scanner/README.md +85 -0
- package/skills/security-firebase-apk-scanner/commands/scan-apk.md +18 -0
- package/skills/security-firebase-apk-scanner/scanner.sh +1408 -0
- package/skills/security-firebase-apk-scanner/skills/firebase-apk-scanner/SKILL.md +197 -0
- package/skills/security-firebase-apk-scanner/skills/firebase-apk-scanner/references/vulnerabilities.md +803 -0
- package/skills/security-fix-review/.claude-plugin/plugin.json +13 -0
- package/skills/security-fix-review/README.md +118 -0
- package/skills/security-fix-review/commands/fix-review.md +24 -0
- package/skills/security-fix-review/skills/fix-review/SKILL.md +264 -0
- package/skills/security-fix-review/skills/fix-review/references/bug-detection.md +408 -0
- package/skills/security-fix-review/skills/fix-review/references/finding-matching.md +298 -0
- package/skills/security-fix-review/skills/fix-review/references/report-parsing.md +398 -0
- package/skills/security-insecure-defaults/.claude-plugin/plugin.json +10 -0
- package/skills/security-insecure-defaults/README.md +45 -0
- package/skills/security-insecure-defaults/skills/insecure-defaults/SKILL.md +117 -0
- package/skills/security-insecure-defaults/skills/insecure-defaults/references/examples.md +409 -0
- package/skills/security-modern-python/.claude-plugin/plugin.json +10 -0
- package/skills/security-modern-python/README.md +58 -0
- package/skills/security-modern-python/hooks/hooks.json +16 -0
- package/skills/security-modern-python/hooks/intercept-legacy-python.bats +388 -0
- package/skills/security-modern-python/hooks/intercept-legacy-python.sh +109 -0
- package/skills/security-modern-python/hooks/test_helper.bash +75 -0
- package/skills/security-modern-python/skills/modern-python/SKILL.md +333 -0
- package/skills/security-modern-python/skills/modern-python/references/dependabot.md +43 -0
- package/skills/security-modern-python/skills/modern-python/references/migration-checklist.md +141 -0
- package/skills/security-modern-python/skills/modern-python/references/pep723-scripts.md +259 -0
- package/skills/security-modern-python/skills/modern-python/references/prek.md +211 -0
- package/skills/security-modern-python/skills/modern-python/references/pyproject.md +254 -0
- package/skills/security-modern-python/skills/modern-python/references/ruff-config.md +240 -0
- package/skills/security-modern-python/skills/modern-python/references/security-setup.md +255 -0
- package/skills/security-modern-python/skills/modern-python/references/testing.md +284 -0
- package/skills/security-modern-python/skills/modern-python/references/uv-commands.md +200 -0
- package/skills/security-modern-python/skills/modern-python/templates/dependabot.yml +36 -0
- package/skills/security-modern-python/skills/modern-python/templates/pre-commit-config.yaml +66 -0
- package/skills/security-property-based-testing/.claude-plugin/plugin.json +9 -0
- package/skills/security-property-based-testing/README.md +47 -0
- package/skills/security-property-based-testing/skills/property-based-testing/README.md +88 -0
- package/skills/security-property-based-testing/skills/property-based-testing/SKILL.md +109 -0
- package/skills/security-property-based-testing/skills/property-based-testing/references/design.md +191 -0
- package/skills/security-property-based-testing/skills/property-based-testing/references/generating.md +200 -0
- package/skills/security-property-based-testing/skills/property-based-testing/references/libraries.md +130 -0
- package/skills/security-property-based-testing/skills/property-based-testing/references/refactoring.md +181 -0
- package/skills/security-property-based-testing/skills/property-based-testing/references/reviewing.md +209 -0
- package/skills/security-property-based-testing/skills/property-based-testing/references/strategies.md +124 -0
- package/skills/semgrep-rule-creator/.claude-plugin/plugin.json +8 -0
- package/skills/semgrep-rule-creator/README.md +43 -0
- package/skills/semgrep-rule-creator/commands/semgrep-rule.md +26 -0
- package/skills/semgrep-rule-creator/skills/semgrep-rule-creator/SKILL.md +168 -0
- package/skills/semgrep-rule-creator/skills/semgrep-rule-creator/references/quick-reference.md +203 -0
- package/skills/semgrep-rule-creator/skills/semgrep-rule-creator/references/workflow.md +240 -0
- package/skills/semgrep-rule-variant-creator/.claude-plugin/plugin.json +9 -0
- package/skills/semgrep-rule-variant-creator/README.md +86 -0
- package/skills/semgrep-rule-variant-creator/skills/semgrep-rule-variant-creator/SKILL.md +205 -0
- package/skills/semgrep-rule-variant-creator/skills/semgrep-rule-variant-creator/references/applicability-analysis.md +250 -0
- package/skills/semgrep-rule-variant-creator/skills/semgrep-rule-variant-creator/references/language-syntax-guide.md +324 -0
- package/skills/semgrep-rule-variant-creator/skills/semgrep-rule-variant-creator/references/workflow.md +518 -0
- package/skills/session-logs/SKILL.md +115 -0
- package/skills/sharp-edges/.claude-plugin/plugin.json +10 -0
- package/skills/sharp-edges/README.md +48 -0
- package/skills/sharp-edges/skills/sharp-edges/SKILL.md +292 -0
- package/skills/sharp-edges/skills/sharp-edges/references/auth-patterns.md +252 -0
- package/skills/sharp-edges/skills/sharp-edges/references/case-studies.md +274 -0
- package/skills/sharp-edges/skills/sharp-edges/references/config-patterns.md +333 -0
- package/skills/sharp-edges/skills/sharp-edges/references/crypto-apis.md +190 -0
- package/skills/sharp-edges/skills/sharp-edges/references/lang-c.md +205 -0
- package/skills/sharp-edges/skills/sharp-edges/references/lang-csharp.md +285 -0
- package/skills/sharp-edges/skills/sharp-edges/references/lang-go.md +270 -0
- package/skills/sharp-edges/skills/sharp-edges/references/lang-java.md +263 -0
- package/skills/sharp-edges/skills/sharp-edges/references/lang-javascript.md +269 -0
- package/skills/sharp-edges/skills/sharp-edges/references/lang-kotlin.md +265 -0
- package/skills/sharp-edges/skills/sharp-edges/references/lang-php.md +245 -0
- package/skills/sharp-edges/skills/sharp-edges/references/lang-python.md +274 -0
- package/skills/sharp-edges/skills/sharp-edges/references/lang-ruby.md +273 -0
- package/skills/sharp-edges/skills/sharp-edges/references/lang-rust.md +272 -0
- package/skills/sharp-edges/skills/sharp-edges/references/lang-swift.md +287 -0
- package/skills/sharp-edges/skills/sharp-edges/references/language-specific.md +588 -0
- package/skills/sherpa-onnx-tts/SKILL.md +103 -0
- package/skills/sherpa-onnx-tts/bin/sherpa-onnx-tts +178 -0
- package/skills/skill-creator/SKILL.md +370 -0
- package/skills/skill-creator/license.txt +202 -0
- package/skills/skill-creator/scripts/init_skill.py +378 -0
- package/skills/skill-creator/scripts/package_skill.py +111 -0
- package/skills/skill-creator/scripts/quick_validate.py +101 -0
- package/skills/slack/SKILL.md +144 -0
- package/skills/songsee/SKILL.md +49 -0
- package/skills/sonoscli/SKILL.md +46 -0
- package/skills/spec-to-code-compliance/.claude-plugin/plugin.json +10 -0
- package/skills/spec-to-code-compliance/README.md +67 -0
- package/skills/spec-to-code-compliance/commands/spec-compliance.md +22 -0
- package/skills/spec-to-code-compliance/skills/spec-to-code-compliance/SKILL.md +349 -0
- package/skills/spec-to-code-compliance/skills/spec-to-code-compliance/resources/COMPLETENESS_CHECKLIST.md +69 -0
- package/skills/spec-to-code-compliance/skills/spec-to-code-compliance/resources/IR_EXAMPLES.md +417 -0
- package/skills/spec-to-code-compliance/skills/spec-to-code-compliance/resources/OUTPUT_REQUIREMENTS.md +105 -0
- package/skills/spotify-player/SKILL.md +64 -0
- package/skills/static-analysis/.claude-plugin/plugin.json +8 -0
- package/skills/static-analysis/README.md +59 -0
- package/skills/static-analysis/skills/codeql/SKILL.md +315 -0
- package/skills/static-analysis/skills/sarif-parsing/SKILL.md +479 -0
- package/skills/static-analysis/skills/sarif-parsing/resources/jq-queries.md +162 -0
- package/skills/static-analysis/skills/sarif-parsing/resources/sarif_helpers.py +331 -0
- package/skills/static-analysis/skills/semgrep/SKILL.md +337 -0
- package/skills/summarize/SKILL.md +87 -0
- package/skills/testing-handbook-skills/.claude-plugin/plugin.json +8 -0
- package/skills/testing-handbook-skills/README.md +241 -0
- package/skills/testing-handbook-skills/scripts/pyproject.toml +8 -0
- package/skills/testing-handbook-skills/scripts/validate-skills.py +657 -0
- package/skills/testing-handbook-skills/skills/address-sanitizer/SKILL.md +341 -0
- package/skills/testing-handbook-skills/skills/aflpp/SKILL.md +640 -0
- package/skills/testing-handbook-skills/skills/atheris/SKILL.md +515 -0
- package/skills/testing-handbook-skills/skills/cargo-fuzz/SKILL.md +454 -0
- package/skills/testing-handbook-skills/skills/codeql/SKILL.md +549 -0
- package/skills/testing-handbook-skills/skills/constant-time-testing/SKILL.md +507 -0
- package/skills/testing-handbook-skills/skills/coverage-analysis/SKILL.md +607 -0
- package/skills/testing-handbook-skills/skills/fuzzing-dictionary/SKILL.md +297 -0
- package/skills/testing-handbook-skills/skills/fuzzing-obstacles/SKILL.md +426 -0
- package/skills/testing-handbook-skills/skills/harness-writing/SKILL.md +614 -0
- package/skills/testing-handbook-skills/skills/libafl/SKILL.md +625 -0
- package/skills/testing-handbook-skills/skills/libfuzzer/SKILL.md +795 -0
- package/skills/testing-handbook-skills/skills/ossfuzz/SKILL.md +426 -0
- package/skills/testing-handbook-skills/skills/ruzzy/SKILL.md +443 -0
- package/skills/testing-handbook-skills/skills/semgrep/SKILL.md +601 -0
- package/skills/testing-handbook-skills/skills/testing-handbook-generator/SKILL.md +372 -0
- package/skills/testing-handbook-skills/skills/testing-handbook-generator/agent-prompt.md +280 -0
- package/skills/testing-handbook-skills/skills/testing-handbook-generator/discovery.md +452 -0
- package/skills/testing-handbook-skills/skills/testing-handbook-generator/templates/domain-skill.md +504 -0
- package/skills/testing-handbook-skills/skills/testing-handbook-generator/templates/fuzzer-skill.md +454 -0
- package/skills/testing-handbook-skills/skills/testing-handbook-generator/templates/technique-skill.md +527 -0
- package/skills/testing-handbook-skills/skills/testing-handbook-generator/templates/tool-skill.md +366 -0
- package/skills/testing-handbook-skills/skills/testing-handbook-generator/testing.md +482 -0
- package/skills/testing-handbook-skills/skills/wycheproof/SKILL.md +533 -0
- package/skills/things-mac/SKILL.md +86 -0
- package/skills/tmux/SKILL.md +135 -0
- package/skills/tmux/scripts/find-sessions.sh +112 -0
- package/skills/tmux/scripts/wait-for-text.sh +83 -0
- package/skills/trello/SKILL.md +95 -0
- package/skills/variant-analysis/.claude-plugin/plugin.json +8 -0
- package/skills/variant-analysis/README.md +41 -0
- package/skills/variant-analysis/commands/variants.md +23 -0
- package/skills/variant-analysis/skills/variant-analysis/METHODOLOGY.md +327 -0
- package/skills/variant-analysis/skills/variant-analysis/SKILL.md +142 -0
- package/skills/variant-analysis/skills/variant-analysis/resources/codeql/cpp.ql +119 -0
- package/skills/variant-analysis/skills/variant-analysis/resources/codeql/go.ql +69 -0
- package/skills/variant-analysis/skills/variant-analysis/resources/codeql/java.ql +71 -0
- package/skills/variant-analysis/skills/variant-analysis/resources/codeql/javascript.ql +63 -0
- package/skills/variant-analysis/skills/variant-analysis/resources/codeql/python.ql +80 -0
- package/skills/variant-analysis/skills/variant-analysis/resources/semgrep/cpp.yaml +98 -0
- package/skills/variant-analysis/skills/variant-analysis/resources/semgrep/go.yaml +63 -0
- package/skills/variant-analysis/skills/variant-analysis/resources/semgrep/java.yaml +61 -0
- package/skills/variant-analysis/skills/variant-analysis/resources/semgrep/javascript.yaml +60 -0
- package/skills/variant-analysis/skills/variant-analysis/resources/semgrep/python.yaml +72 -0
- package/skills/variant-analysis/skills/variant-analysis/resources/variant-report-template.md +75 -0
- package/skills/video-frames/SKILL.md +46 -0
- package/skills/video-frames/scripts/frame.sh +81 -0
- package/skills/voice-call/SKILL.md +45 -0
- package/skills/wacli/SKILL.md +72 -0
- package/skills/weather/SKILL.md +54 -0
- package/skills/yara-authoring/.claude-plugin/plugin.json +9 -0
- package/skills/yara-authoring/README.md +131 -0
- package/skills/yara-authoring/skills/yara-rule-authoring/SKILL.md +645 -0
- package/skills/yara-authoring/skills/yara-rule-authoring/examples/MAL_Mac_ProtonRAT_Jan25.yar +99 -0
- package/skills/yara-authoring/skills/yara-rule-authoring/examples/MAL_NPM_SupplyChain_Jan25.yar +170 -0
- package/skills/yara-authoring/skills/yara-rule-authoring/examples/MAL_Win_Remcos_Jan25.yar +103 -0
- package/skills/yara-authoring/skills/yara-rule-authoring/examples/SUSP_CRX_SuspiciousPermissions.yar +134 -0
- package/skills/yara-authoring/skills/yara-rule-authoring/examples/SUSP_JS_Obfuscation_Jan25.yar +185 -0
- package/skills/yara-authoring/skills/yara-rule-authoring/references/crx-module.md +214 -0
- package/skills/yara-authoring/skills/yara-rule-authoring/references/dex-module.md +383 -0
- package/skills/yara-authoring/skills/yara-rule-authoring/references/performance.md +333 -0
- package/skills/yara-authoring/skills/yara-rule-authoring/references/strings.md +433 -0
- package/skills/yara-authoring/skills/yara-rule-authoring/references/style-guide.md +257 -0
- package/skills/yara-authoring/skills/yara-rule-authoring/references/testing.md +399 -0
- package/skills/yara-authoring/skills/yara-rule-authoring/scripts/atom_analyzer.py +526 -0
- package/skills/yara-authoring/skills/yara-rule-authoring/scripts/pyproject.toml +25 -0
- package/skills/yara-authoring/skills/yara-rule-authoring/scripts/yara_lint.py +631 -0
- package/skills/yara-authoring/skills/yara-rule-authoring/workflows/rule-development.md +493 -0
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
"""
|
|
2
|
+
SARIF Parsing Helper Functions
|
|
3
|
+
|
|
4
|
+
Reusable utilities for working with SARIF files.
|
|
5
|
+
No external dependencies beyond standard library.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import hashlib
|
|
9
|
+
import json
|
|
10
|
+
from collections import defaultdict
|
|
11
|
+
from collections.abc import Iterator
|
|
12
|
+
from dataclasses import dataclass, field
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from typing import Any
|
|
15
|
+
from urllib.parse import unquote
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass
|
|
19
|
+
class Finding:
|
|
20
|
+
"""Structured representation of a SARIF result."""
|
|
21
|
+
|
|
22
|
+
rule_id: str
|
|
23
|
+
level: str
|
|
24
|
+
message: str
|
|
25
|
+
file_path: str | None = None
|
|
26
|
+
start_line: int | None = None
|
|
27
|
+
end_line: int | None = None
|
|
28
|
+
start_column: int | None = None
|
|
29
|
+
end_column: int | None = None
|
|
30
|
+
fingerprint: str | None = None
|
|
31
|
+
tool_name: str | None = None
|
|
32
|
+
rule_name: str | None = None
|
|
33
|
+
raw: dict = field(default_factory=dict, repr=False)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def load_sarif(path: str | Path) -> dict:
|
|
37
|
+
"""Load and parse a SARIF file."""
|
|
38
|
+
with open(path) as f:
|
|
39
|
+
return json.load(f)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def save_sarif(sarif: dict, path: str | Path, indent: int = 2) -> None:
|
|
43
|
+
"""Save SARIF data to file."""
|
|
44
|
+
with open(path, "w") as f:
|
|
45
|
+
json.dump(sarif, f, indent=indent)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def validate_version(sarif: dict) -> bool:
|
|
49
|
+
"""Check if SARIF version is 2.1.0."""
|
|
50
|
+
return sarif.get("version") == "2.1.0"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def normalize_path(uri: str, base_path: str = "") -> str:
|
|
54
|
+
"""Normalize SARIF artifact URI to consistent path."""
|
|
55
|
+
if not uri:
|
|
56
|
+
return ""
|
|
57
|
+
|
|
58
|
+
# Remove file:// prefix
|
|
59
|
+
if uri.startswith("file://"):
|
|
60
|
+
uri = uri[7:]
|
|
61
|
+
|
|
62
|
+
# URL decode
|
|
63
|
+
uri = unquote(uri)
|
|
64
|
+
|
|
65
|
+
# Handle relative paths
|
|
66
|
+
if base_path and not Path(uri).is_absolute():
|
|
67
|
+
uri = str(Path(base_path) / uri)
|
|
68
|
+
|
|
69
|
+
return str(Path(uri))
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def safe_get(data: dict, *keys, default: Any = None) -> Any:
|
|
73
|
+
"""Safely navigate nested dict structure."""
|
|
74
|
+
for key in keys:
|
|
75
|
+
if isinstance(data, dict):
|
|
76
|
+
data = data.get(key, {})
|
|
77
|
+
elif isinstance(data, list) and isinstance(key, int):
|
|
78
|
+
data = data[key] if 0 <= key < len(data) else {}
|
|
79
|
+
else:
|
|
80
|
+
return default
|
|
81
|
+
return data if data != {} else default
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def extract_location(result: dict) -> tuple[str | None, int | None, int | None]:
|
|
85
|
+
"""Extract file path, start line, and end line from result."""
|
|
86
|
+
loc = safe_get(result, "locations", 0, default={})
|
|
87
|
+
phys = loc.get("physicalLocation", {})
|
|
88
|
+
region = phys.get("region", {})
|
|
89
|
+
|
|
90
|
+
file_path = safe_get(phys, "artifactLocation", "uri")
|
|
91
|
+
start_line = region.get("startLine")
|
|
92
|
+
end_line = region.get("endLine")
|
|
93
|
+
|
|
94
|
+
return file_path, start_line, end_line
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def iter_results(sarif: dict) -> Iterator[tuple[dict, dict]]:
|
|
98
|
+
"""Iterate over all results with their run context."""
|
|
99
|
+
for run in sarif.get("runs", []):
|
|
100
|
+
for result in run.get("results", []):
|
|
101
|
+
yield result, run
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def extract_findings(sarif: dict) -> list[Finding]:
|
|
105
|
+
"""Extract all findings as structured objects."""
|
|
106
|
+
findings = []
|
|
107
|
+
|
|
108
|
+
for result, run in iter_results(sarif):
|
|
109
|
+
tool_name = safe_get(run, "tool", "driver", "name")
|
|
110
|
+
file_path, start_line, end_line = extract_location(result)
|
|
111
|
+
|
|
112
|
+
loc = safe_get(result, "locations", 0, default={})
|
|
113
|
+
phys = loc.get("physicalLocation", {})
|
|
114
|
+
region = phys.get("region", {})
|
|
115
|
+
|
|
116
|
+
# Get fingerprint
|
|
117
|
+
fp = None
|
|
118
|
+
if result.get("partialFingerprints"):
|
|
119
|
+
fp = next(iter(result["partialFingerprints"].values()), None)
|
|
120
|
+
elif result.get("fingerprints"):
|
|
121
|
+
fp = next(iter(result["fingerprints"].values()), None)
|
|
122
|
+
|
|
123
|
+
findings.append(
|
|
124
|
+
Finding(
|
|
125
|
+
rule_id=result.get("ruleId", "unknown"),
|
|
126
|
+
level=result.get("level", "warning"),
|
|
127
|
+
message=safe_get(result, "message", "text", default=""),
|
|
128
|
+
file_path=file_path,
|
|
129
|
+
start_line=start_line,
|
|
130
|
+
end_line=end_line,
|
|
131
|
+
start_column=region.get("startColumn"),
|
|
132
|
+
end_column=region.get("endColumn"),
|
|
133
|
+
fingerprint=fp,
|
|
134
|
+
tool_name=tool_name,
|
|
135
|
+
raw=result,
|
|
136
|
+
)
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
return findings
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def filter_by_level(findings: list[Finding], *levels: str) -> list[Finding]:
|
|
143
|
+
"""Filter findings by severity level(s)."""
|
|
144
|
+
return [f for f in findings if f.level in levels]
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def filter_by_file(findings: list[Finding], pattern: str) -> list[Finding]:
|
|
148
|
+
"""Filter findings by file path pattern (substring match)."""
|
|
149
|
+
return [f for f in findings if f.file_path and pattern in f.file_path]
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def filter_by_rule(findings: list[Finding], *rule_ids: str) -> list[Finding]:
|
|
153
|
+
"""Filter findings by rule ID(s)."""
|
|
154
|
+
return [f for f in findings if f.rule_id in rule_ids]
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def sort_by_severity(findings: list[Finding], reverse: bool = False) -> list[Finding]:
|
|
158
|
+
"""Sort findings by severity (error > warning > note > none)."""
|
|
159
|
+
severity_order = {"error": 0, "warning": 1, "note": 2, "none": 3}
|
|
160
|
+
return sorted(findings, key=lambda f: severity_order.get(f.level, 99), reverse=reverse)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def group_by_file(findings: list[Finding]) -> dict[str, list[Finding]]:
|
|
164
|
+
"""Group findings by file path."""
|
|
165
|
+
grouped = defaultdict(list)
|
|
166
|
+
for f in findings:
|
|
167
|
+
key = f.file_path or "unknown"
|
|
168
|
+
grouped[key].append(f)
|
|
169
|
+
return dict(grouped)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def group_by_rule(findings: list[Finding]) -> dict[str, list[Finding]]:
|
|
173
|
+
"""Group findings by rule ID."""
|
|
174
|
+
grouped = defaultdict(list)
|
|
175
|
+
for f in findings:
|
|
176
|
+
grouped[f.rule_id].append(f)
|
|
177
|
+
return dict(grouped)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def count_by_level(findings: list[Finding]) -> dict[str, int]:
|
|
181
|
+
"""Count findings by severity level."""
|
|
182
|
+
counts = defaultdict(int)
|
|
183
|
+
for f in findings:
|
|
184
|
+
counts[f.level] += 1
|
|
185
|
+
return dict(counts)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def count_by_rule(findings: list[Finding]) -> dict[str, int]:
|
|
189
|
+
"""Count findings by rule ID."""
|
|
190
|
+
counts = defaultdict(int)
|
|
191
|
+
for f in findings:
|
|
192
|
+
counts[f.rule_id] += 1
|
|
193
|
+
return dict(counts)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def compute_fingerprint(result: dict, include_message: bool = True) -> str:
|
|
197
|
+
"""Compute stable fingerprint from result data."""
|
|
198
|
+
components = [result.get("ruleId", "")]
|
|
199
|
+
|
|
200
|
+
file_path, start_line, _ = extract_location(result)
|
|
201
|
+
if file_path:
|
|
202
|
+
# Use only filename, not full path (more stable across environments)
|
|
203
|
+
components.append(Path(file_path).name)
|
|
204
|
+
if start_line:
|
|
205
|
+
components.append(str(start_line))
|
|
206
|
+
if include_message:
|
|
207
|
+
msg = safe_get(result, "message", "text", default="")
|
|
208
|
+
# First 50 chars of message for stability
|
|
209
|
+
components.append(msg[:50])
|
|
210
|
+
|
|
211
|
+
return hashlib.sha256("|".join(components).encode()).hexdigest()[:16]
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def deduplicate(findings: list[Finding]) -> list[Finding]:
|
|
215
|
+
"""Remove duplicate findings based on fingerprints."""
|
|
216
|
+
seen = set()
|
|
217
|
+
unique = []
|
|
218
|
+
|
|
219
|
+
for f in findings:
|
|
220
|
+
key = f.fingerprint or compute_fingerprint(f.raw)
|
|
221
|
+
if key not in seen:
|
|
222
|
+
seen.add(key)
|
|
223
|
+
unique.append(f)
|
|
224
|
+
|
|
225
|
+
return unique
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def merge_sarif_files(*paths: str | Path) -> dict:
|
|
229
|
+
"""Merge multiple SARIF files into one."""
|
|
230
|
+
merged = {
|
|
231
|
+
"version": "2.1.0",
|
|
232
|
+
"$schema": "https://json.schemastore.org/sarif-2.1.0.json",
|
|
233
|
+
"runs": [],
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
for path in paths:
|
|
237
|
+
sarif = load_sarif(path)
|
|
238
|
+
merged["runs"].extend(sarif.get("runs", []))
|
|
239
|
+
|
|
240
|
+
return merged
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def diff_findings(
|
|
244
|
+
baseline: list[Finding], current: list[Finding]
|
|
245
|
+
) -> tuple[list[Finding], list[Finding], list[Finding]]:
|
|
246
|
+
"""
|
|
247
|
+
Compare two sets of findings.
|
|
248
|
+
|
|
249
|
+
Returns:
|
|
250
|
+
- new: findings in current but not baseline
|
|
251
|
+
- fixed: findings in baseline but not current
|
|
252
|
+
- unchanged: findings in both
|
|
253
|
+
"""
|
|
254
|
+
baseline_fps = {f.fingerprint or compute_fingerprint(f.raw) for f in baseline}
|
|
255
|
+
current_fps = {f.fingerprint or compute_fingerprint(f.raw) for f in current}
|
|
256
|
+
|
|
257
|
+
new = [f for f in current if (f.fingerprint or compute_fingerprint(f.raw)) not in baseline_fps]
|
|
258
|
+
fixed = [
|
|
259
|
+
f for f in baseline if (f.fingerprint or compute_fingerprint(f.raw)) not in current_fps
|
|
260
|
+
]
|
|
261
|
+
unchanged = [
|
|
262
|
+
f for f in current if (f.fingerprint or compute_fingerprint(f.raw)) in baseline_fps
|
|
263
|
+
]
|
|
264
|
+
|
|
265
|
+
return new, fixed, unchanged
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def get_rules(sarif: dict) -> dict[str, dict]:
|
|
269
|
+
"""Extract rule definitions from SARIF file."""
|
|
270
|
+
rules = {}
|
|
271
|
+
for run in sarif.get("runs", []):
|
|
272
|
+
for rule in safe_get(run, "tool", "driver", "rules", default=[]):
|
|
273
|
+
rules[rule.get("id", "")] = rule
|
|
274
|
+
return rules
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def to_csv_rows(findings: list[Finding]) -> list[list[str]]:
|
|
278
|
+
"""Convert findings to CSV-ready rows."""
|
|
279
|
+
rows = [["rule_id", "level", "file", "line", "message"]]
|
|
280
|
+
for f in findings:
|
|
281
|
+
rows.append(
|
|
282
|
+
[
|
|
283
|
+
f.rule_id,
|
|
284
|
+
f.level,
|
|
285
|
+
f.file_path or "",
|
|
286
|
+
str(f.start_line or ""),
|
|
287
|
+
f.message.replace("\n", " ")[:200],
|
|
288
|
+
]
|
|
289
|
+
)
|
|
290
|
+
return rows
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def summary(findings: list[Finding]) -> dict:
|
|
294
|
+
"""Generate summary statistics for findings."""
|
|
295
|
+
return {
|
|
296
|
+
"total": len(findings),
|
|
297
|
+
"by_level": count_by_level(findings),
|
|
298
|
+
"by_rule": count_by_rule(findings),
|
|
299
|
+
"files_affected": len(set(f.file_path for f in findings if f.file_path)),
|
|
300
|
+
"rules_triggered": len(set(f.rule_id for f in findings)),
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
# Example usage
|
|
305
|
+
if __name__ == "__main__":
|
|
306
|
+
import sys
|
|
307
|
+
|
|
308
|
+
if len(sys.argv) < 2:
|
|
309
|
+
print("Usage: python sarif_helpers.py <sarif_file>")
|
|
310
|
+
sys.exit(1)
|
|
311
|
+
|
|
312
|
+
sarif = load_sarif(sys.argv[1])
|
|
313
|
+
|
|
314
|
+
if not validate_version(sarif):
|
|
315
|
+
print("Warning: SARIF version is not 2.1.0")
|
|
316
|
+
|
|
317
|
+
findings = extract_findings(sarif)
|
|
318
|
+
findings = sort_by_severity(findings)
|
|
319
|
+
|
|
320
|
+
print("\nSummary:")
|
|
321
|
+
stats = summary(findings)
|
|
322
|
+
print(f" Total findings: {stats['total']}")
|
|
323
|
+
print(f" Files affected: {stats['files_affected']}")
|
|
324
|
+
print(f" Rules triggered: {stats['rules_triggered']}")
|
|
325
|
+
print("\nBy severity:")
|
|
326
|
+
for level, count in stats["by_level"].items():
|
|
327
|
+
print(f" {level}: {count}")
|
|
328
|
+
|
|
329
|
+
print("\nTop 5 rules:")
|
|
330
|
+
for rule, count in sorted(stats["by_rule"].items(), key=lambda x: -x[1])[:5]:
|
|
331
|
+
print(f" {rule}: {count}")
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: semgrep
|
|
3
|
+
description: Run Semgrep static analysis for fast security scanning and pattern matching. Use when asked to scan code with Semgrep, write custom YAML rules, find vulnerabilities quickly, use taint mode, or set up Semgrep in CI/CD pipelines.
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Bash
|
|
6
|
+
- Read
|
|
7
|
+
- Glob
|
|
8
|
+
- Grep
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Semgrep Static Analysis
|
|
12
|
+
|
|
13
|
+
## When to Use Semgrep
|
|
14
|
+
|
|
15
|
+
**Ideal scenarios:**
|
|
16
|
+
- Quick security scans (minutes, not hours)
|
|
17
|
+
- Pattern-based bug detection
|
|
18
|
+
- Enforcing coding standards and best practices
|
|
19
|
+
- Finding known vulnerability patterns
|
|
20
|
+
- Single-file analysis without complex data flow
|
|
21
|
+
- First-pass analysis before deeper tools
|
|
22
|
+
|
|
23
|
+
**Consider CodeQL instead when:**
|
|
24
|
+
- Need interprocedural taint tracking across files
|
|
25
|
+
- Complex data flow analysis required
|
|
26
|
+
- Analyzing custom proprietary frameworks
|
|
27
|
+
|
|
28
|
+
## When NOT to Use
|
|
29
|
+
|
|
30
|
+
Do NOT use this skill for:
|
|
31
|
+
- Complex interprocedural data flow analysis (use CodeQL instead)
|
|
32
|
+
- Binary analysis or compiled code without source
|
|
33
|
+
- Custom deep semantic analysis requiring AST/CFG traversal
|
|
34
|
+
- When you need to track taint across many function boundaries
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# pip
|
|
40
|
+
python3 -m pip install semgrep
|
|
41
|
+
|
|
42
|
+
# Homebrew
|
|
43
|
+
brew install semgrep
|
|
44
|
+
|
|
45
|
+
# Docker
|
|
46
|
+
docker run --rm -v "${PWD}:/src" returntocorp/semgrep semgrep --config auto /src
|
|
47
|
+
|
|
48
|
+
# Update
|
|
49
|
+
pip install --upgrade semgrep
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Core Workflow
|
|
53
|
+
|
|
54
|
+
### 1. Quick Scan
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
semgrep --config auto . # Auto-detect rules
|
|
58
|
+
semgrep --config auto --metrics=off . # Disable telemetry for proprietary code
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 2. Use Rulesets
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
semgrep --config p/<RULESET> . # Single ruleset
|
|
65
|
+
semgrep --config p/security-audit --config p/trailofbits . # Multiple
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
| Ruleset | Description |
|
|
69
|
+
|---------|-------------|
|
|
70
|
+
| `p/default` | General security and code quality |
|
|
71
|
+
| `p/security-audit` | Comprehensive security rules |
|
|
72
|
+
| `p/owasp-top-ten` | OWASP Top 10 vulnerabilities |
|
|
73
|
+
| `p/cwe-top-25` | CWE Top 25 vulnerabilities |
|
|
74
|
+
| `p/r2c-security-audit` | r2c security audit rules |
|
|
75
|
+
| `p/trailofbits` | Trail of Bits security rules |
|
|
76
|
+
| `p/python` | Python-specific |
|
|
77
|
+
| `p/javascript` | JavaScript-specific |
|
|
78
|
+
| `p/golang` | Go-specific |
|
|
79
|
+
|
|
80
|
+
### 3. Output Formats
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
semgrep --config p/security-audit --sarif -o results.sarif . # SARIF
|
|
84
|
+
semgrep --config p/security-audit --json -o results.json . # JSON
|
|
85
|
+
semgrep --config p/security-audit --dataflow-traces . # Show data flow
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 4. Scan Specific Paths
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
semgrep --config p/python app.py # Single file
|
|
92
|
+
semgrep --config p/javascript src/ # Directory
|
|
93
|
+
semgrep --config auto --include='**/test/**' . # Include tests (excluded by default)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Writing Custom Rules
|
|
97
|
+
|
|
98
|
+
### Basic Structure
|
|
99
|
+
|
|
100
|
+
```yaml
|
|
101
|
+
rules:
|
|
102
|
+
- id: hardcoded-password
|
|
103
|
+
languages: [python]
|
|
104
|
+
message: "Hardcoded password detected: $PASSWORD"
|
|
105
|
+
severity: ERROR
|
|
106
|
+
pattern: password = "$PASSWORD"
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Pattern Syntax
|
|
110
|
+
|
|
111
|
+
| Syntax | Description | Example |
|
|
112
|
+
|--------|-------------|---------|
|
|
113
|
+
| `...` | Match anything | `func(...)` |
|
|
114
|
+
| `$VAR` | Capture metavariable | `$FUNC($INPUT)` |
|
|
115
|
+
| `<... ...>` | Deep expression match | `<... user_input ...>` |
|
|
116
|
+
|
|
117
|
+
### Pattern Operators
|
|
118
|
+
|
|
119
|
+
| Operator | Description |
|
|
120
|
+
|----------|-------------|
|
|
121
|
+
| `pattern` | Match exact pattern |
|
|
122
|
+
| `patterns` | All must match (AND) |
|
|
123
|
+
| `pattern-either` | Any matches (OR) |
|
|
124
|
+
| `pattern-not` | Exclude matches |
|
|
125
|
+
| `pattern-inside` | Match only inside context |
|
|
126
|
+
| `pattern-not-inside` | Match only outside context |
|
|
127
|
+
| `pattern-regex` | Regex matching |
|
|
128
|
+
| `metavariable-regex` | Regex on captured value |
|
|
129
|
+
| `metavariable-comparison` | Compare values |
|
|
130
|
+
|
|
131
|
+
### Combining Patterns
|
|
132
|
+
|
|
133
|
+
```yaml
|
|
134
|
+
rules:
|
|
135
|
+
- id: sql-injection
|
|
136
|
+
languages: [python]
|
|
137
|
+
message: "Potential SQL injection"
|
|
138
|
+
severity: ERROR
|
|
139
|
+
patterns:
|
|
140
|
+
- pattern-either:
|
|
141
|
+
- pattern: cursor.execute($QUERY)
|
|
142
|
+
- pattern: db.execute($QUERY)
|
|
143
|
+
- pattern-not:
|
|
144
|
+
- pattern: cursor.execute("...", (...))
|
|
145
|
+
- metavariable-regex:
|
|
146
|
+
metavariable: $QUERY
|
|
147
|
+
regex: .*\+.*|.*\.format\(.*|.*%.*
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Taint Mode (Data Flow)
|
|
151
|
+
|
|
152
|
+
Simple pattern matching finds obvious cases:
|
|
153
|
+
|
|
154
|
+
```python
|
|
155
|
+
# Pattern `os.system($CMD)` catches this:
|
|
156
|
+
os.system(user_input) # Found
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
But misses indirect flows:
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
# Same pattern misses this:
|
|
163
|
+
cmd = user_input
|
|
164
|
+
processed = cmd.strip()
|
|
165
|
+
os.system(processed) # Missed - no direct match
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Taint mode tracks data through assignments and transformations:
|
|
169
|
+
- **Source**: Where untrusted data enters (`user_input`)
|
|
170
|
+
- **Propagators**: How it flows (`cmd = ...`, `processed = ...`)
|
|
171
|
+
- **Sanitizers**: What makes it safe (`shlex.quote()`)
|
|
172
|
+
- **Sink**: Where it becomes dangerous (`os.system()`)
|
|
173
|
+
|
|
174
|
+
```yaml
|
|
175
|
+
rules:
|
|
176
|
+
- id: command-injection
|
|
177
|
+
languages: [python]
|
|
178
|
+
message: "User input flows to command execution"
|
|
179
|
+
severity: ERROR
|
|
180
|
+
mode: taint
|
|
181
|
+
pattern-sources:
|
|
182
|
+
- pattern: request.args.get(...)
|
|
183
|
+
- pattern: request.form[...]
|
|
184
|
+
- pattern: request.json
|
|
185
|
+
pattern-sinks:
|
|
186
|
+
- pattern: os.system($SINK)
|
|
187
|
+
- pattern: subprocess.call($SINK, shell=True)
|
|
188
|
+
- pattern: subprocess.run($SINK, shell=True, ...)
|
|
189
|
+
pattern-sanitizers:
|
|
190
|
+
- pattern: shlex.quote(...)
|
|
191
|
+
- pattern: int(...)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Full Rule with Metadata
|
|
195
|
+
|
|
196
|
+
```yaml
|
|
197
|
+
rules:
|
|
198
|
+
- id: flask-sql-injection
|
|
199
|
+
languages: [python]
|
|
200
|
+
message: "SQL injection: user input flows to query without parameterization"
|
|
201
|
+
severity: ERROR
|
|
202
|
+
metadata:
|
|
203
|
+
cwe: "CWE-89: SQL Injection"
|
|
204
|
+
owasp: "A03:2021 - Injection"
|
|
205
|
+
confidence: HIGH
|
|
206
|
+
mode: taint
|
|
207
|
+
pattern-sources:
|
|
208
|
+
- pattern: request.args.get(...)
|
|
209
|
+
- pattern: request.form[...]
|
|
210
|
+
- pattern: request.json
|
|
211
|
+
pattern-sinks:
|
|
212
|
+
- pattern: cursor.execute($QUERY)
|
|
213
|
+
- pattern: db.execute($QUERY)
|
|
214
|
+
pattern-sanitizers:
|
|
215
|
+
- pattern: int(...)
|
|
216
|
+
fix: cursor.execute($QUERY, (params,))
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Testing Rules
|
|
220
|
+
|
|
221
|
+
### Test File Format
|
|
222
|
+
|
|
223
|
+
```python
|
|
224
|
+
# test_rule.py
|
|
225
|
+
def test_vulnerable():
|
|
226
|
+
user_input = request.args.get("id")
|
|
227
|
+
# ruleid: flask-sql-injection
|
|
228
|
+
cursor.execute("SELECT * FROM users WHERE id = " + user_input)
|
|
229
|
+
|
|
230
|
+
def test_safe():
|
|
231
|
+
user_input = request.args.get("id")
|
|
232
|
+
# ok: flask-sql-injection
|
|
233
|
+
cursor.execute("SELECT * FROM users WHERE id = ?", (user_input,))
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
semgrep --test rules/
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## CI/CD Integration (GitHub Actions)
|
|
241
|
+
|
|
242
|
+
```yaml
|
|
243
|
+
name: Semgrep
|
|
244
|
+
|
|
245
|
+
on:
|
|
246
|
+
push:
|
|
247
|
+
branches: [main]
|
|
248
|
+
pull_request:
|
|
249
|
+
schedule:
|
|
250
|
+
- cron: '0 0 1 * *' # Monthly
|
|
251
|
+
|
|
252
|
+
jobs:
|
|
253
|
+
semgrep:
|
|
254
|
+
runs-on: ubuntu-latest
|
|
255
|
+
container:
|
|
256
|
+
image: returntocorp/semgrep
|
|
257
|
+
|
|
258
|
+
steps:
|
|
259
|
+
- uses: actions/checkout@v4
|
|
260
|
+
with:
|
|
261
|
+
fetch-depth: 0 # Required for diff-aware scanning
|
|
262
|
+
|
|
263
|
+
- name: Run Semgrep
|
|
264
|
+
run: |
|
|
265
|
+
if [ "${{ github.event_name }}" = "pull_request" ]; then
|
|
266
|
+
semgrep ci --baseline-commit ${{ github.event.pull_request.base.sha }}
|
|
267
|
+
else
|
|
268
|
+
semgrep ci
|
|
269
|
+
fi
|
|
270
|
+
env:
|
|
271
|
+
SEMGREP_RULES: >-
|
|
272
|
+
p/security-audit
|
|
273
|
+
p/owasp-top-ten
|
|
274
|
+
p/trailofbits
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## Configuration
|
|
278
|
+
|
|
279
|
+
### .semgrepignore
|
|
280
|
+
|
|
281
|
+
```
|
|
282
|
+
tests/fixtures/
|
|
283
|
+
**/testdata/
|
|
284
|
+
generated/
|
|
285
|
+
vendor/
|
|
286
|
+
node_modules/
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Suppress False Positives
|
|
290
|
+
|
|
291
|
+
```python
|
|
292
|
+
password = get_from_vault() # nosemgrep: hardcoded-password
|
|
293
|
+
dangerous_but_safe() # nosemgrep
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## Performance
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
semgrep --config rules/ --time . # Check rule performance
|
|
300
|
+
ulimit -n 4096 # Increase file descriptors for large codebases
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Path Filtering in Rules
|
|
304
|
+
|
|
305
|
+
```yaml
|
|
306
|
+
rules:
|
|
307
|
+
- id: my-rule
|
|
308
|
+
paths:
|
|
309
|
+
include: [src/]
|
|
310
|
+
exclude: [src/generated/]
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
## Third-Party Rules
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
pip install semgrep-rules-manager
|
|
317
|
+
semgrep-rules-manager --dir ~/semgrep-rules download
|
|
318
|
+
semgrep -f ~/semgrep-rules .
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## Rationalizations to Reject
|
|
322
|
+
|
|
323
|
+
| Shortcut | Why It's Wrong |
|
|
324
|
+
|----------|----------------|
|
|
325
|
+
| "Semgrep found nothing, code is clean" | Semgrep is pattern-based; it can't track complex data flow across functions |
|
|
326
|
+
| "I wrote a rule, so we're covered" | Rules need testing with `semgrep --test`; false negatives are silent |
|
|
327
|
+
| "Taint mode catches injection" | Only if you defined all sources, sinks, AND sanitizers correctly |
|
|
328
|
+
| "Pro rules are comprehensive" | Pro rules are good but not exhaustive; supplement with custom rules for your codebase |
|
|
329
|
+
| "Too many findings = noisy tool" | High finding count often means real problems; tune rules, don't disable them |
|
|
330
|
+
|
|
331
|
+
## Resources
|
|
332
|
+
|
|
333
|
+
- Registry: https://semgrep.dev/explore
|
|
334
|
+
- Playground: https://semgrep.dev/playground
|
|
335
|
+
- Docs: https://semgrep.dev/docs/
|
|
336
|
+
- Trail of Bits Rules: https://github.com/trailofbits/semgrep-rules
|
|
337
|
+
- Blog: https://semgrep.dev/blog/
|