@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,722 @@
|
|
|
1
|
+
## 6. Vulnerability Checklist (6 Patterns)
|
|
2
|
+
|
|
3
|
+
### 6.1 FELT252 ARITHMETIC OVERFLOW/UNDERFLOW ⚠️ HIGH
|
|
4
|
+
|
|
5
|
+
**Description**: The `felt252` type in Cairo represents field elements in range [0, P] where P is the StarkNet prime. Unchecked arithmetic can overflow (wrapping to 0) or underflow (wrapping to P-1), similar to unsigned integers.
|
|
6
|
+
|
|
7
|
+
**Detection Patterns**:
|
|
8
|
+
```rust
|
|
9
|
+
// VULNERABLE: Direct arithmetic on felt252 without bounds checking
|
|
10
|
+
#[external(v0)]
|
|
11
|
+
fn transfer(ref self: ContractState, to: ContractAddress, amount: felt252) {
|
|
12
|
+
let sender = get_caller_address();
|
|
13
|
+
let mut sender_balance = self.balances.read(sender);
|
|
14
|
+
|
|
15
|
+
// OVERFLOW/UNDERFLOW: No bounds checking!
|
|
16
|
+
sender_balance = sender_balance - amount; // Can underflow to ~P
|
|
17
|
+
sender_balance = sender_balance + amount; // Can overflow past P
|
|
18
|
+
|
|
19
|
+
self.balances.write(sender, sender_balance);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// VULNERABLE: felt252 arithmetic in calculations
|
|
23
|
+
let reward = base_reward * multiplier; // Can overflow
|
|
24
|
+
let remaining = total - claimed; // Can underflow
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**What to Check**:
|
|
28
|
+
- [ ] Direct arithmetic on `felt252` type without overflow/underflow checks
|
|
29
|
+
- [ ] Balance updates using felt252
|
|
30
|
+
- [ ] Reward/fee calculations using felt252
|
|
31
|
+
- [ ] No explicit validation that values stay within expected range
|
|
32
|
+
- [ ] Consider using default integer types (u8, u16, u32, u64, u128, u256)
|
|
33
|
+
|
|
34
|
+
**Mitigation**:
|
|
35
|
+
```rust
|
|
36
|
+
// OPTION 1: Use default integer types (RECOMMENDED)
|
|
37
|
+
#[storage]
|
|
38
|
+
struct Storage {
|
|
39
|
+
// Use u128 or u256 instead of felt252 for balances
|
|
40
|
+
balances: LegacyMap<ContractAddress, u128>,
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
#[external(v0)]
|
|
44
|
+
fn transfer(ref self: ContractState, to: ContractAddress, amount: u128) {
|
|
45
|
+
let sender = get_caller_address();
|
|
46
|
+
let sender_balance = self.balances.read(sender);
|
|
47
|
+
|
|
48
|
+
// u128 has built-in overflow/underflow protection
|
|
49
|
+
assert(sender_balance >= amount, 'Insufficient balance');
|
|
50
|
+
|
|
51
|
+
self.balances.write(sender, sender_balance - amount);
|
|
52
|
+
self.balances.write(to, self.balances.read(to) + amount);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// OPTION 2: Explicit checks with felt252
|
|
56
|
+
#[external(v0)]
|
|
57
|
+
fn transfer_felt(ref self: ContractState, to: ContractAddress, amount: felt252) {
|
|
58
|
+
let sender = get_caller_address();
|
|
59
|
+
let sender_balance = self.balances_felt.read(sender);
|
|
60
|
+
|
|
61
|
+
// Explicit overflow/underflow checks
|
|
62
|
+
assert(sender_balance >= amount, 'Insufficient balance');
|
|
63
|
+
|
|
64
|
+
let new_sender_balance = sender_balance - amount;
|
|
65
|
+
let recipient_balance = self.balances_felt.read(to);
|
|
66
|
+
let new_recipient_balance = recipient_balance + amount;
|
|
67
|
+
|
|
68
|
+
// Verify no overflow occurred
|
|
69
|
+
assert(new_recipient_balance >= recipient_balance, 'Overflow');
|
|
70
|
+
|
|
71
|
+
self.balances_felt.write(sender, new_sender_balance);
|
|
72
|
+
self.balances_felt.write(to, new_recipient_balance);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// OPTION 3: SafeMath-style library (if available)
|
|
76
|
+
use openzeppelin::security::safemath::SafeMath;
|
|
77
|
+
|
|
78
|
+
let safe_result = SafeMath::add(balance, amount)?;
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Tool Detection**:
|
|
82
|
+
- Caracal detector: `unchecked-felt252-arithmetic`
|
|
83
|
+
- Look for: felt252 used in balances, arithmetic operations without bounds checks
|
|
84
|
+
|
|
85
|
+
**References**: building-secure-contracts/not-so-smart-contracts/cairo/arithmetic_overflow
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
### 4.2 L1 TO L2 ADDRESS CONVERSION ⚠️ HIGH
|
|
90
|
+
|
|
91
|
+
**Description**: Ethereum L1 addresses are uint256 (256 bits), but StarkNet addresses are felt252 with range [0, P] where P < 2^256. L1 addresses >= P will map to zero address or unexpected address on L2.
|
|
92
|
+
|
|
93
|
+
**Detection Patterns**:
|
|
94
|
+
```rust
|
|
95
|
+
// VULNERABLE: L1 contract doesn't validate address range
|
|
96
|
+
// L1 Bridge contract (Solidity)
|
|
97
|
+
function depositToL2(address l2Recipient, uint256 amount) external {
|
|
98
|
+
// WRONG: No check that l2Recipient < STARKNET_FIELD_PRIME
|
|
99
|
+
uint256[] memory payload = new uint256[](2);
|
|
100
|
+
payload[0] = uint256(uint160(l2Recipient)); // Direct conversion!
|
|
101
|
+
payload[1] = amount;
|
|
102
|
+
|
|
103
|
+
starknetCore.sendMessageToL2(l2Contract, selector, payload);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// VULNERABLE: L2 handler assumes address is valid
|
|
107
|
+
// L2 Contract (Cairo)
|
|
108
|
+
#[l1_handler]
|
|
109
|
+
fn handle_deposit(
|
|
110
|
+
ref self: ContractState,
|
|
111
|
+
from_address: felt252,
|
|
112
|
+
user: ContractAddress, // Could be zero if L1 address >= P!
|
|
113
|
+
amount: u256
|
|
114
|
+
) {
|
|
115
|
+
// No validation that user != 0
|
|
116
|
+
let current_balance = self.balances.read(user);
|
|
117
|
+
self.balances.write(user, current_balance + amount);
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**What to Check**:
|
|
122
|
+
- [ ] L1 bridge contracts validate addresses before sending to L2
|
|
123
|
+
- [ ] Validation: `0 < address < STARKNET_FIELD_PRIME`
|
|
124
|
+
- [ ] L2 contracts check that addresses != 0
|
|
125
|
+
- [ ] Documentation warns about address conversion issues
|
|
126
|
+
|
|
127
|
+
**Mitigation**:
|
|
128
|
+
```solidity
|
|
129
|
+
// SECURE: L1 Bridge with address validation (Solidity)
|
|
130
|
+
contract L1Bridge {
|
|
131
|
+
// StarkNet field prime (approximately)
|
|
132
|
+
uint256 constant STARKNET_FIELD_PRIME =
|
|
133
|
+
0x0800000000000011000000000000000000000000000000000000000000000001;
|
|
134
|
+
|
|
135
|
+
function depositToL2(uint256 l2Recipient, uint256 amount) external {
|
|
136
|
+
// Validate L2 address is within valid range
|
|
137
|
+
require(l2Recipient != 0, "Zero address");
|
|
138
|
+
require(l2Recipient < STARKNET_FIELD_PRIME, "Address out of range");
|
|
139
|
+
|
|
140
|
+
uint256[] memory payload = new uint256[](2);
|
|
141
|
+
payload[0] = l2Recipient;
|
|
142
|
+
payload[1] = amount;
|
|
143
|
+
|
|
144
|
+
starknetCore.sendMessageToL2(l2Contract, selector, payload);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
```rust
|
|
150
|
+
// SECURE: L2 handler with validation (Cairo)
|
|
151
|
+
#[l1_handler]
|
|
152
|
+
fn handle_deposit(
|
|
153
|
+
ref self: ContractState,
|
|
154
|
+
from_address: felt252,
|
|
155
|
+
user: ContractAddress,
|
|
156
|
+
amount: u256
|
|
157
|
+
) {
|
|
158
|
+
// Validate user address is not zero
|
|
159
|
+
let zero_address: ContractAddress = 0.try_into().unwrap();
|
|
160
|
+
assert(user != zero_address, 'Invalid user address');
|
|
161
|
+
|
|
162
|
+
// Validate L1 sender is authorized bridge
|
|
163
|
+
let expected_l1_bridge: felt252 = self.l1_bridge_address.read();
|
|
164
|
+
assert(from_address == expected_l1_bridge, 'Unauthorized L1 sender');
|
|
165
|
+
|
|
166
|
+
let current_balance = self.balances.read(user);
|
|
167
|
+
self.balances.write(user, current_balance + amount);
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Testing**:
|
|
172
|
+
```rust
|
|
173
|
+
// Test with edge case addresses
|
|
174
|
+
#[test]
|
|
175
|
+
fn test_large_address_conversion() {
|
|
176
|
+
// Address close to STARKNET_FIELD_PRIME
|
|
177
|
+
let large_address = STARKNET_FIELD_PRIME - 1;
|
|
178
|
+
// Should handle correctly
|
|
179
|
+
|
|
180
|
+
let invalid_address = STARKNET_FIELD_PRIME + 1;
|
|
181
|
+
// Should reject on L1
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**References**: building-secure-contracts/not-so-smart-contracts/cairo/l1_to_l2_address_conversion
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
### 4.3 L1 TO L2 MESSAGE FAILURE ⚠️ HIGH
|
|
190
|
+
|
|
191
|
+
**Description**: Messages from L1 to L2 may not be processed by the sequencer (due to gas spikes, congestion, etc.). Without a cancellation mechanism, funds sent via failed messages are locked permanently.
|
|
192
|
+
|
|
193
|
+
**Detection Patterns**:
|
|
194
|
+
```solidity
|
|
195
|
+
// VULNERABLE: L1 bridge without cancellation mechanism
|
|
196
|
+
contract L1Bridge {
|
|
197
|
+
function depositToL2(uint256 l2Recipient, uint256 amount) external payable {
|
|
198
|
+
// Lock funds on L1
|
|
199
|
+
require(msg.value == amount, "Incorrect amount");
|
|
200
|
+
|
|
201
|
+
// Send message to L2
|
|
202
|
+
starknetCore.sendMessageToL2(l2Contract, selector, payload);
|
|
203
|
+
|
|
204
|
+
// PROBLEM: If message fails to process on L2, funds locked forever!
|
|
205
|
+
// No way to cancel and return funds to user
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**What to Check**:
|
|
211
|
+
- [ ] L1 bridge implements message cancellation mechanism
|
|
212
|
+
- [ ] Uses `startL1ToL2MessageCancellation` and `cancelL1ToL2Message`
|
|
213
|
+
- [ ] Cancellation delay period documented
|
|
214
|
+
- [ ] Users can recover funds if L2 message not processed
|
|
215
|
+
|
|
216
|
+
**Mitigation**:
|
|
217
|
+
```solidity
|
|
218
|
+
// SECURE: L1 Bridge with cancellation support
|
|
219
|
+
contract L1Bridge {
|
|
220
|
+
IStarknetCore public starknetCore;
|
|
221
|
+
uint256 public constant MESSAGE_CANCEL_DELAY = 5 days;
|
|
222
|
+
|
|
223
|
+
// Track message hashes for cancellation
|
|
224
|
+
mapping(bytes32 => address) public messageOwner;
|
|
225
|
+
|
|
226
|
+
function depositToL2(
|
|
227
|
+
uint256 l2Contract,
|
|
228
|
+
uint256 l2Recipient,
|
|
229
|
+
uint256 amount
|
|
230
|
+
) external payable returns (bytes32 msgHash) {
|
|
231
|
+
require(msg.value == amount, "Incorrect amount");
|
|
232
|
+
|
|
233
|
+
uint256[] memory payload = new uint256[](2);
|
|
234
|
+
payload[0] = l2Recipient;
|
|
235
|
+
payload[1] = amount;
|
|
236
|
+
|
|
237
|
+
// Send message and get hash
|
|
238
|
+
msgHash = starknetCore.sendMessageToL2{value: msg.value}(
|
|
239
|
+
l2Contract,
|
|
240
|
+
DEPOSIT_SELECTOR,
|
|
241
|
+
payload
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
// Track message owner for cancellation
|
|
245
|
+
messageOwner[msgHash] = msg.sender;
|
|
246
|
+
|
|
247
|
+
emit DepositInitiated(msg.sender, l2Recipient, amount, msgHash);
|
|
248
|
+
return msgHash;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function startCancellation(bytes32 msgHash, uint256 nonce) external {
|
|
252
|
+
require(messageOwner[msgHash] == msg.sender, "Not message owner");
|
|
253
|
+
|
|
254
|
+
uint256[] memory payload = new uint256[](2);
|
|
255
|
+
payload[0] = uint256(uint160(msg.sender));
|
|
256
|
+
payload[1] = msg.value;
|
|
257
|
+
|
|
258
|
+
// Start cancellation process
|
|
259
|
+
starknetCore.startL1ToL2MessageCancellation(
|
|
260
|
+
l2Contract,
|
|
261
|
+
DEPOSIT_SELECTOR,
|
|
262
|
+
payload,
|
|
263
|
+
nonce
|
|
264
|
+
);
|
|
265
|
+
|
|
266
|
+
emit CancellationStarted(msgHash, msg.sender);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function completeCancellation(
|
|
270
|
+
bytes32 msgHash,
|
|
271
|
+
uint256 nonce
|
|
272
|
+
) external {
|
|
273
|
+
require(messageOwner[msgHash] == msg.sender, "Not message owner");
|
|
274
|
+
|
|
275
|
+
uint256[] memory payload = new uint256[](2);
|
|
276
|
+
payload[0] = uint256(uint160(msg.sender));
|
|
277
|
+
payload[1] = msg.value;
|
|
278
|
+
|
|
279
|
+
// Complete cancellation (after delay)
|
|
280
|
+
starknetCore.cancelL1ToL2Message(
|
|
281
|
+
l2Contract,
|
|
282
|
+
DEPOSIT_SELECTOR,
|
|
283
|
+
payload,
|
|
284
|
+
nonce
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
// Return funds to user
|
|
288
|
+
(bool success, ) = msg.sender.call{value: msg.value}("");
|
|
289
|
+
require(success, "Transfer failed");
|
|
290
|
+
|
|
291
|
+
delete messageOwner[msgHash];
|
|
292
|
+
|
|
293
|
+
emit DepositCancelled(msgHash, msg.sender);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**L2 Considerations**:
|
|
299
|
+
```rust
|
|
300
|
+
// L2 contract should handle idempotent deposits
|
|
301
|
+
#[l1_handler]
|
|
302
|
+
fn handle_deposit(
|
|
303
|
+
ref self: ContractState,
|
|
304
|
+
from_address: felt252,
|
|
305
|
+
user: ContractAddress,
|
|
306
|
+
amount: u256
|
|
307
|
+
) {
|
|
308
|
+
// If message is replayed after cancellation attempt,
|
|
309
|
+
// should handle gracefully (idempotency)
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
**References**: building-secure-contracts/not-so-smart-contracts/cairo/l1_to_l2_message_failure
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
### 4.4 OVERCONSTRAINED L1 <-> L2 INTERACTION ⚠️ MEDIUM
|
|
318
|
+
|
|
319
|
+
**Description**: Asymmetrical validation on L1 vs L2 sides creates situations where funds can be deposited but not withdrawn, or vice versa. Different access control rules trap user funds.
|
|
320
|
+
|
|
321
|
+
**Detection Patterns**:
|
|
322
|
+
```solidity
|
|
323
|
+
// VULNERABLE: L1 has whitelist, L2 doesn't
|
|
324
|
+
contract L1Bridge {
|
|
325
|
+
mapping(address => bool) public whitelist;
|
|
326
|
+
|
|
327
|
+
function depositToL2(uint256 l2Recipient, uint256 amount) external {
|
|
328
|
+
require(whitelist[msg.sender], "Not whitelisted"); // Whitelist on L1
|
|
329
|
+
// Send to L2
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
function withdrawFromL2(uint256 amount) external {
|
|
333
|
+
// No whitelist check - anyone can withdraw!
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
```rust
|
|
339
|
+
// VULNERABLE: L2 allows deposits but L1 blocks withdrawals
|
|
340
|
+
#[l1_handler]
|
|
341
|
+
fn handle_deposit(
|
|
342
|
+
ref self: ContractState,
|
|
343
|
+
from_address: felt252,
|
|
344
|
+
user: ContractAddress,
|
|
345
|
+
amount: u256
|
|
346
|
+
) {
|
|
347
|
+
// No restrictions - accepts from any L1 address
|
|
348
|
+
self.balances.write(user, self.balances.read(user) + amount);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
#[external(v0)]
|
|
352
|
+
fn initiate_withdrawal(ref self: ContractState, amount: u256) {
|
|
353
|
+
// User can initiate withdrawal on L2
|
|
354
|
+
send_message_to_l1_syscall(to_address, payload);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// But L1 contract has restrictions preventing withdrawal completion!
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
**What to Check**:
|
|
361
|
+
- [ ] Same validation rules on both L1 and L2
|
|
362
|
+
- [ ] If L1 has whitelist, L2 should too (or vice versa)
|
|
363
|
+
- [ ] If L1 has blacklist, L2 should too
|
|
364
|
+
- [ ] Access controls symmetric across layers
|
|
365
|
+
- [ ] Test full roundtrip: deposit on L1 → withdraw on L1
|
|
366
|
+
|
|
367
|
+
**Mitigation**:
|
|
368
|
+
```solidity
|
|
369
|
+
// SECURE: Symmetric validation on L1
|
|
370
|
+
contract L1Bridge {
|
|
371
|
+
mapping(address => bool) public blockedUsers;
|
|
372
|
+
|
|
373
|
+
function depositToL2(uint256 l2Recipient, uint256 amount) external {
|
|
374
|
+
require(!blockedUsers[msg.sender], "User blocked");
|
|
375
|
+
// Process deposit
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
function finalizeWithdrawal(uint256 recipient, uint256 amount) external {
|
|
379
|
+
// Validate L2 message
|
|
380
|
+
require(!blockedUsers[msg.sender], "User blocked");
|
|
381
|
+
// Process withdrawal
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
```rust
|
|
387
|
+
// SECURE: Symmetric validation on L2
|
|
388
|
+
#[storage]
|
|
389
|
+
struct Storage {
|
|
390
|
+
blocked_users: LegacyMap<ContractAddress, bool>,
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
#[l1_handler]
|
|
394
|
+
fn handle_deposit(
|
|
395
|
+
ref self: ContractState,
|
|
396
|
+
from_address: felt252,
|
|
397
|
+
user: ContractAddress,
|
|
398
|
+
amount: u256
|
|
399
|
+
) {
|
|
400
|
+
// Same validation as L1
|
|
401
|
+
assert(!self.blocked_users.read(user), 'User blocked');
|
|
402
|
+
self.balances.write(user, self.balances.read(user) + amount);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
#[external(v0)]
|
|
406
|
+
fn initiate_withdrawal(ref self: ContractState, amount: u256) {
|
|
407
|
+
let user = get_caller_address();
|
|
408
|
+
|
|
409
|
+
// Same validation as L1
|
|
410
|
+
assert(!self.blocked_users.read(user), 'User blocked');
|
|
411
|
+
|
|
412
|
+
// Process withdrawal
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
**Testing Strategy**:
|
|
417
|
+
```rust
|
|
418
|
+
// Test full roundtrip scenarios
|
|
419
|
+
#[test]
|
|
420
|
+
fn test_deposit_and_withdraw_roundtrip() {
|
|
421
|
+
// 1. Deposit on L1
|
|
422
|
+
// 2. Verify balance on L2
|
|
423
|
+
// 3. Initiate withdrawal on L2
|
|
424
|
+
// 4. Finalize withdrawal on L1
|
|
425
|
+
// 5. Verify funds returned
|
|
426
|
+
|
|
427
|
+
// Should succeed for all valid users
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
#[test]
|
|
431
|
+
fn test_blocked_user_cannot_roundtrip() {
|
|
432
|
+
// Blocked user should fail at EVERY step
|
|
433
|
+
// Not just one side
|
|
434
|
+
}
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
**References**: building-secure-contracts/not-so-smart-contracts/cairo/l1_l2_overconstrained
|
|
438
|
+
|
|
439
|
+
---
|
|
440
|
+
|
|
441
|
+
### 4.5 SIGNATURE REPLAY PROTECTION ⚠️ HIGH
|
|
442
|
+
|
|
443
|
+
**Description**: Signatures without nonce tracking and domain separation can be replayed: same signature used multiple times on the same chain, or across different chains (mainnet/testnet).
|
|
444
|
+
|
|
445
|
+
**Detection Patterns**:
|
|
446
|
+
```rust
|
|
447
|
+
// VULNERABLE: No nonce tracking
|
|
448
|
+
#[external(v0)]
|
|
449
|
+
fn execute_with_signature(
|
|
450
|
+
ref self: ContractState,
|
|
451
|
+
to: ContractAddress,
|
|
452
|
+
amount: u128,
|
|
453
|
+
signature: Array<felt252>
|
|
454
|
+
) {
|
|
455
|
+
// Verify signature
|
|
456
|
+
let message_hash = hash_message(to, amount);
|
|
457
|
+
let signer = recover_signer(message_hash, signature);
|
|
458
|
+
|
|
459
|
+
// WRONG: No nonce! Same signature can be replayed infinitely
|
|
460
|
+
self.transfer_internal(signer, to, amount);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// VULNERABLE: No chain ID in signature
|
|
464
|
+
fn hash_message(to: ContractAddress, amount: u128) -> felt252 {
|
|
465
|
+
// Missing chain ID - signature valid on mainnet AND testnet!
|
|
466
|
+
pedersen_hash(to.into(), amount.into())
|
|
467
|
+
}
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
**What to Check**:
|
|
471
|
+
- [ ] Signatures include nonce that is incremented after each use
|
|
472
|
+
- [ ] Nonce stored per signer address
|
|
473
|
+
- [ ] Signatures include domain separator (chain ID, contract address)
|
|
474
|
+
- [ ] Signature hash includes all relevant parameters
|
|
475
|
+
- [ ] Cannot replay same signature twice
|
|
476
|
+
- [ ] Cannot replay signature from testnet on mainnet
|
|
477
|
+
|
|
478
|
+
**Mitigation**:
|
|
479
|
+
```rust
|
|
480
|
+
// SECURE: Proper signature with nonce and domain separator
|
|
481
|
+
use openzeppelin::account::interface::ISRC6;
|
|
482
|
+
|
|
483
|
+
#[storage]
|
|
484
|
+
struct Storage {
|
|
485
|
+
nonces: LegacyMap<ContractAddress, felt252>,
|
|
486
|
+
// Other storage
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
#[external(v0)]
|
|
490
|
+
fn execute_with_signature(
|
|
491
|
+
ref self: ContractState,
|
|
492
|
+
to: ContractAddress,
|
|
493
|
+
amount: u128,
|
|
494
|
+
nonce: felt252,
|
|
495
|
+
signature: Array<felt252>
|
|
496
|
+
) {
|
|
497
|
+
// Get signer's current nonce
|
|
498
|
+
let signer = get_caller_address();
|
|
499
|
+
let current_nonce = self.nonces.read(signer);
|
|
500
|
+
|
|
501
|
+
// Verify nonce matches
|
|
502
|
+
assert(nonce == current_nonce, 'Invalid nonce');
|
|
503
|
+
|
|
504
|
+
// Build message hash with domain separator
|
|
505
|
+
let message_hash = self.hash_message_with_domain(
|
|
506
|
+
signer,
|
|
507
|
+
to,
|
|
508
|
+
amount,
|
|
509
|
+
nonce
|
|
510
|
+
);
|
|
511
|
+
|
|
512
|
+
// Verify signature
|
|
513
|
+
let is_valid = self.verify_signature(signer, message_hash, signature);
|
|
514
|
+
assert(is_valid, 'Invalid signature');
|
|
515
|
+
|
|
516
|
+
// Increment nonce BEFORE execution (reentrancy protection)
|
|
517
|
+
self.nonces.write(signer, current_nonce + 1);
|
|
518
|
+
|
|
519
|
+
// Execute operation
|
|
520
|
+
self.transfer_internal(signer, to, amount);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
fn hash_message_with_domain(
|
|
524
|
+
self: @ContractState,
|
|
525
|
+
signer: ContractAddress,
|
|
526
|
+
to: ContractAddress,
|
|
527
|
+
amount: u128,
|
|
528
|
+
nonce: felt252
|
|
529
|
+
) -> felt252 {
|
|
530
|
+
// Include domain separator for replay protection
|
|
531
|
+
let domain_separator = self.get_domain_separator();
|
|
532
|
+
|
|
533
|
+
// Hash all parameters including domain and nonce
|
|
534
|
+
let mut message = array![
|
|
535
|
+
domain_separator,
|
|
536
|
+
signer.into(),
|
|
537
|
+
to.into(),
|
|
538
|
+
amount.into(),
|
|
539
|
+
nonce
|
|
540
|
+
];
|
|
541
|
+
|
|
542
|
+
poseidon_hash_span(message.span())
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
fn get_domain_separator(self: @ContractState) -> felt252 {
|
|
546
|
+
// EIP-712 style domain separator
|
|
547
|
+
let chain_id = get_tx_info().unbox().chain_id;
|
|
548
|
+
let contract_address = get_contract_address();
|
|
549
|
+
|
|
550
|
+
poseidon_hash_span(
|
|
551
|
+
array!['StarkNet Domain', chain_id, contract_address.into()].span()
|
|
552
|
+
)
|
|
553
|
+
}
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
**Using OpenZeppelin**:
|
|
557
|
+
```rust
|
|
558
|
+
// BETTER: Use OpenZeppelin Account implementation
|
|
559
|
+
use openzeppelin::account::Account;
|
|
560
|
+
use openzeppelin::account::interface::AccountABIDispatcher;
|
|
561
|
+
|
|
562
|
+
// OpenZeppelin Account automatically handles:
|
|
563
|
+
// - Nonce management
|
|
564
|
+
// - Domain separation
|
|
565
|
+
// - Signature verification
|
|
566
|
+
// - Replay protection
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
**Testing**:
|
|
570
|
+
```rust
|
|
571
|
+
#[test]
|
|
572
|
+
#[should_panic(expected: ('Invalid nonce',))]
|
|
573
|
+
fn test_cannot_replay_signature() {
|
|
574
|
+
// Execute with signature once
|
|
575
|
+
contract.execute_with_signature(to, amount, nonce, signature);
|
|
576
|
+
|
|
577
|
+
// Try to replay same signature - should fail
|
|
578
|
+
contract.execute_with_signature(to, amount, nonce, signature);
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
#[test]
|
|
582
|
+
#[should_panic]
|
|
583
|
+
fn test_cannot_use_testnet_signature_on_mainnet() {
|
|
584
|
+
// Generate signature on testnet
|
|
585
|
+
let testnet_signature = sign_on_testnet(message);
|
|
586
|
+
|
|
587
|
+
// Try to use on mainnet - should fail due to domain separator
|
|
588
|
+
mainnet_contract.execute_with_signature(..., testnet_signature);
|
|
589
|
+
}
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
**Tool Detection**:
|
|
593
|
+
- Caracal detector: `missing-nonce-validation`
|
|
594
|
+
- Look for: Signature verification without nonce checks
|
|
595
|
+
|
|
596
|
+
**References**: building-secure-contracts/not-so-smart-contracts/cairo/signature_replay
|
|
597
|
+
|
|
598
|
+
---
|
|
599
|
+
|
|
600
|
+
### 4.6 UNCHECKED from_address IN L1 HANDLER ⚠️ CRITICAL
|
|
601
|
+
|
|
602
|
+
**Description**: L1 handler functions (`#[l1_handler]`) can be invoked by any L1 contract unless `from_address` is validated. Missing validation allows unauthorized L1 contracts to send messages.
|
|
603
|
+
|
|
604
|
+
**Detection Patterns**:
|
|
605
|
+
```rust
|
|
606
|
+
// VULNERABLE: No from_address validation
|
|
607
|
+
#[l1_handler]
|
|
608
|
+
fn handle_deposit(
|
|
609
|
+
ref self: ContractState,
|
|
610
|
+
from_address: felt252, // Not validated!
|
|
611
|
+
user: ContractAddress,
|
|
612
|
+
amount: u256
|
|
613
|
+
) {
|
|
614
|
+
// WRONG: Any L1 contract can call this and mint tokens!
|
|
615
|
+
let current_balance = self.balances.read(user);
|
|
616
|
+
self.balances.write(user, current_balance + amount);
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
// VULNERABLE: Only validates on L1 side
|
|
620
|
+
// L1 Contract has access control
|
|
621
|
+
function depositToL2() external onlyAuthorized {
|
|
622
|
+
starknetCore.sendMessageToL2(...);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
// But L2 doesn't check - attacker deploys their own L1 contract!
|
|
626
|
+
#[l1_handler]
|
|
627
|
+
fn handle_deposit(ref self: ContractState, from_address: felt252, ...) {
|
|
628
|
+
// No check that from_address == AUTHORIZED_L1_CONTRACT
|
|
629
|
+
}
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
**What to Check**:
|
|
633
|
+
- [ ] ALL `#[l1_handler]` functions validate `from_address`
|
|
634
|
+
- [ ] Validation: `from_address == expected_l1_contract_address`
|
|
635
|
+
- [ ] Expected L1 addresses stored in contract storage
|
|
636
|
+
- [ ] Cannot skip validation even if L1 contract has access control
|
|
637
|
+
|
|
638
|
+
**Mitigation**:
|
|
639
|
+
```rust
|
|
640
|
+
// SECURE: Validate from_address in L1 handler
|
|
641
|
+
#[storage]
|
|
642
|
+
struct Storage {
|
|
643
|
+
l1_bridge_address: felt252,
|
|
644
|
+
balances: LegacyMap<ContractAddress, u256>,
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
#[constructor]
|
|
648
|
+
fn constructor(ref self: ContractState, l1_bridge: felt252) {
|
|
649
|
+
self.l1_bridge_address.write(l1_bridge);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
#[l1_handler]
|
|
653
|
+
fn handle_deposit(
|
|
654
|
+
ref self: ContractState,
|
|
655
|
+
from_address: felt252,
|
|
656
|
+
user: ContractAddress,
|
|
657
|
+
amount: u256
|
|
658
|
+
) {
|
|
659
|
+
// CRITICAL: Validate from_address is authorized L1 bridge
|
|
660
|
+
let authorized_l1_bridge = self.l1_bridge_address.read();
|
|
661
|
+
assert(from_address == authorized_l1_bridge, 'Unauthorized L1 sender');
|
|
662
|
+
|
|
663
|
+
// Validate user address
|
|
664
|
+
let zero_address: ContractAddress = 0.try_into().unwrap();
|
|
665
|
+
assert(user != zero_address, 'Invalid user address');
|
|
666
|
+
|
|
667
|
+
// Now safe to process deposit
|
|
668
|
+
let current_balance = self.balances.read(user);
|
|
669
|
+
self.balances.write(user, current_balance + amount);
|
|
670
|
+
|
|
671
|
+
// Emit event
|
|
672
|
+
self.emit(DepositProcessed { user, amount, from_l1: from_address });
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
// Admin function to update L1 bridge (if needed)
|
|
676
|
+
#[external(v0)]
|
|
677
|
+
fn update_l1_bridge(ref self: ContractState, new_l1_bridge: felt252) {
|
|
678
|
+
// Access control
|
|
679
|
+
self.ownable.assert_only_owner();
|
|
680
|
+
|
|
681
|
+
self.l1_bridge_address.write(new_l1_bridge);
|
|
682
|
+
self.emit(L1BridgeUpdated { new_address: new_l1_bridge });
|
|
683
|
+
}
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
**Testing**:
|
|
687
|
+
```rust
|
|
688
|
+
#[test]
|
|
689
|
+
#[should_panic(expected: ('Unauthorized L1 sender',))]
|
|
690
|
+
fn test_unauthorized_l1_sender_rejected() {
|
|
691
|
+
let unauthorized_address = 0x123; // Wrong L1 address
|
|
692
|
+
|
|
693
|
+
// Should reject
|
|
694
|
+
contract.handle_deposit(
|
|
695
|
+
from_address: unauthorized_address,
|
|
696
|
+
user: user_address,
|
|
697
|
+
amount: 1000
|
|
698
|
+
);
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
#[test]
|
|
702
|
+
fn test_authorized_l1_sender_accepted() {
|
|
703
|
+
let authorized_address = l1_bridge_address;
|
|
704
|
+
|
|
705
|
+
// Should succeed
|
|
706
|
+
contract.handle_deposit(
|
|
707
|
+
from_address: authorized_address,
|
|
708
|
+
user: user_address,
|
|
709
|
+
amount: 1000
|
|
710
|
+
);
|
|
711
|
+
|
|
712
|
+
assert(contract.balances(user_address) == 1000);
|
|
713
|
+
}
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
**Tool Detection**:
|
|
717
|
+
- Caracal detector: `unchecked-l1-handler-from`
|
|
718
|
+
- Look for: `#[l1_handler]` without `from_address` validation
|
|
719
|
+
|
|
720
|
+
**References**: building-secure-contracts/not-so-smart-contracts/cairo/unchecked_l1_handler_from
|
|
721
|
+
|
|
722
|
+
---
|