@elizaos/skills 2.0.0-alpha.10
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/dist/formatter.d.ts +44 -0
- package/dist/formatter.d.ts.map +1 -0
- package/dist/formatter.js +182 -0
- package/dist/frontmatter.d.ts +39 -0
- package/dist/frontmatter.d.ts.map +1 -0
- package/dist/frontmatter.js +105 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/loader.d.ts +33 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +362 -0
- package/dist/resolver.d.ts +18 -0
- package/dist/resolver.d.ts.map +1 -0
- package/dist/resolver.js +90 -0
- package/dist/types.d.ts +201 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +57 -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/SKILL.md +85 -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/SKILL.md +297 -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/SKILL.md +67 -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-differential-review/.claude-plugin/plugin.json +10 -0
- package/skills/security-differential-review/README.md +109 -0
- package/skills/security-differential-review/SKILL.md +220 -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-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/SKILL.md +251 -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-fix-review/.claude-plugin/plugin.json +13 -0
- package/skills/security-fix-review/README.md +118 -0
- package/skills/security-fix-review/SKILL.md +264 -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/SKILL.md +117 -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/SKILL.md +333 -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/SKILL.md +109 -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/SKILL.md +168 -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/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/SKILL.md +292 -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/SKILL.md +349 -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/SKILL.md +91 -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/SKILL.md +104 -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/SKILL.md +142 -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
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# Authentication & Session Footguns
|
|
2
|
+
|
|
3
|
+
Patterns that make authentication and session management error-prone.
|
|
4
|
+
|
|
5
|
+
## Password Handling
|
|
6
|
+
|
|
7
|
+
### Comparison Vulnerabilities
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
# DANGEROUS: Short-circuit evaluation
|
|
11
|
+
def check_password(user_input, stored):
|
|
12
|
+
return user_input == stored # Timing attack
|
|
13
|
+
|
|
14
|
+
# DANGEROUS: Empty password bypass
|
|
15
|
+
def check_password(user_input, stored):
|
|
16
|
+
if not stored:
|
|
17
|
+
return True # No password set = access granted?
|
|
18
|
+
return constant_time_compare(user_input, stored)
|
|
19
|
+
|
|
20
|
+
# DANGEROUS: Null bypass
|
|
21
|
+
def authenticate(username, password):
|
|
22
|
+
user = get_user(username)
|
|
23
|
+
if user is None:
|
|
24
|
+
return None # No user = return None
|
|
25
|
+
if password == user.password: # None == None if both None
|
|
26
|
+
return user
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Length Limits That Truncate
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
# DANGEROUS: Password truncated before hashing
|
|
33
|
+
def hash_password(password: str) -> str:
|
|
34
|
+
password = password[:72] # bcrypt limit
|
|
35
|
+
return bcrypt.hash(password)
|
|
36
|
+
|
|
37
|
+
# User sets: "password123" + 64 more characters + "IMPORTANT_ENTROPY"
|
|
38
|
+
# Stored: hash of just "password123" + first 61 characters
|
|
39
|
+
# Attacker only needs to brute force truncated version
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Fix**: Reject passwords over limit; don't silently truncate.
|
|
43
|
+
|
|
44
|
+
### Validation Ordering
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
# DANGEROUS: Username enumeration
|
|
48
|
+
def login(username, password):
|
|
49
|
+
user = db.get_user(username)
|
|
50
|
+
if not user:
|
|
51
|
+
return "User not found" # Reveals user doesn't exist
|
|
52
|
+
if not verify_password(password, user.password_hash):
|
|
53
|
+
return "Wrong password" # Reveals user DOES exist
|
|
54
|
+
return create_session(user)
|
|
55
|
+
|
|
56
|
+
# SECURE: Uniform error
|
|
57
|
+
def login(username, password):
|
|
58
|
+
user = db.get_user(username)
|
|
59
|
+
if not user or not verify_password(password, user.password_hash):
|
|
60
|
+
return "Invalid credentials"
|
|
61
|
+
return create_session(user)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Session Management
|
|
65
|
+
|
|
66
|
+
### Session Fixation Enablers
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
# DANGEROUS: Session ID accepted from request
|
|
70
|
+
def login(request):
|
|
71
|
+
session_id = request.cookies.get("session") or generate_session_id()
|
|
72
|
+
# Attacker gives victim a known session ID before login
|
|
73
|
+
# After login, attacker knows victim's session
|
|
74
|
+
sessions[session_id] = user
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Fix**: Always generate new session ID on authentication state change.
|
|
78
|
+
|
|
79
|
+
### Token Generation Weakness
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
# DANGEROUS: Predictable tokens
|
|
83
|
+
import time
|
|
84
|
+
session_id = hashlib.md5(str(time.time()).encode()).hexdigest()
|
|
85
|
+
# Attacker knows approximate login time = can guess session
|
|
86
|
+
|
|
87
|
+
# DANGEROUS: Insufficient entropy
|
|
88
|
+
session_id = ''.join(random.choice('abcdef') for _ in range(8))
|
|
89
|
+
# Only 6^8 = 1.6M possibilities
|
|
90
|
+
|
|
91
|
+
# SECURE: Cryptographic randomness
|
|
92
|
+
session_id = secrets.token_urlsafe(32)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Session Timeout Footguns
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
# DANGEROUS: Timeout of 0 means "never"?
|
|
99
|
+
class SessionConfig:
|
|
100
|
+
timeout_seconds: int = 3600 # 1 hour
|
|
101
|
+
# What if someone sets 0? Infinite session?
|
|
102
|
+
|
|
103
|
+
# DANGEROUS: Negative timeout
|
|
104
|
+
if current_time - session_created > timeout:
|
|
105
|
+
# If timeout is negative, this is always False
|
|
106
|
+
# Session never expires
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Token/OTP Handling
|
|
110
|
+
|
|
111
|
+
### OTP Lifetime Issues
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
# DANGEROUS: lifetime=0 accepts all
|
|
115
|
+
def verify_otp(code, user, lifetime=300):
|
|
116
|
+
if lifetime == 0:
|
|
117
|
+
return True # Skip expiry check entirely
|
|
118
|
+
|
|
119
|
+
# DANGEROUS: Negative lifetime
|
|
120
|
+
if otp.created_at + lifetime > current_time:
|
|
121
|
+
return True
|
|
122
|
+
# If lifetime is negative, always expired? Or underflow?
|
|
123
|
+
|
|
124
|
+
# DANGEROUS: No rate limiting
|
|
125
|
+
def verify_otp(code, user):
|
|
126
|
+
return code == user.current_otp
|
|
127
|
+
# Attacker can try all 1,000,000 6-digit codes
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Token Reuse
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
# DANGEROUS: OTP valid until next OTP generated
|
|
134
|
+
def verify_otp(code, user):
|
|
135
|
+
return code == user.otp
|
|
136
|
+
|
|
137
|
+
# DANGEROUS: Reset token valid forever
|
|
138
|
+
def verify_reset_token(token):
|
|
139
|
+
return token in valid_tokens
|
|
140
|
+
# Never expires, never invalidated on use
|
|
141
|
+
|
|
142
|
+
# SECURE: Single-use, time-limited
|
|
143
|
+
def verify_reset_token(token):
|
|
144
|
+
record = db.get_token(token)
|
|
145
|
+
if not record:
|
|
146
|
+
return False
|
|
147
|
+
if record.used or record.expired:
|
|
148
|
+
return False
|
|
149
|
+
record.mark_used() # Invalidate immediately
|
|
150
|
+
return True
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Authorization Footguns
|
|
154
|
+
|
|
155
|
+
### Role/Permission Accumulation
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
# DANGEROUS: String-based permissions
|
|
159
|
+
user.permissions = "read,write"
|
|
160
|
+
user.permissions += ",admin" # Too easy
|
|
161
|
+
|
|
162
|
+
# DANGEROUS: Any-match logic
|
|
163
|
+
def has_permission(user, required):
|
|
164
|
+
return any(p in user.permissions for p in required.split(","))
|
|
165
|
+
# has_permission(user, "admin,readonly") - matches if ANY is present
|
|
166
|
+
|
|
167
|
+
# DANGEROUS: Substring matching
|
|
168
|
+
if "admin" in user.role:
|
|
169
|
+
grant_admin_access()
|
|
170
|
+
# "readonly_admin_viewer" contains "admin"
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Missing Authorization Checks
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
# DANGEROUS: Auth check in one place, not others
|
|
177
|
+
@require_login
|
|
178
|
+
def list_documents(request):
|
|
179
|
+
return Document.objects.all()
|
|
180
|
+
|
|
181
|
+
def get_document(request, doc_id):
|
|
182
|
+
# Developer forgot @require_login
|
|
183
|
+
return Document.objects.get(id=doc_id)
|
|
184
|
+
|
|
185
|
+
def delete_document(request, doc_id):
|
|
186
|
+
# Developer also forgot authorization check
|
|
187
|
+
Document.objects.get(id=doc_id).delete()
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**Fix**: Centralized authorization; deny-by-default.
|
|
191
|
+
|
|
192
|
+
### IDOR Enablers
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
# DANGEROUS: User ID from request
|
|
196
|
+
def get_profile(request):
|
|
197
|
+
user_id = request.GET["user_id"] # Attacker changes this
|
|
198
|
+
return User.objects.get(id=user_id)
|
|
199
|
+
|
|
200
|
+
# DANGEROUS: Sequential IDs
|
|
201
|
+
user = User.objects.create(...) # Gets ID 12345
|
|
202
|
+
# Attacker tries 12344, 12346, etc.
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Multi-Factor Authentication
|
|
206
|
+
|
|
207
|
+
### Bypassable MFA
|
|
208
|
+
|
|
209
|
+
```python
|
|
210
|
+
# DANGEROUS: MFA check in frontend only
|
|
211
|
+
# API directly accessible without MFA
|
|
212
|
+
|
|
213
|
+
# DANGEROUS: "Remember this device" with weak token
|
|
214
|
+
device_token = hashlib.md5(user_agent.encode()).hexdigest()
|
|
215
|
+
# Attacker spoofs User-Agent to bypass MFA
|
|
216
|
+
|
|
217
|
+
# DANGEROUS: MFA disabled by user preference
|
|
218
|
+
if user.preferences.get("mfa_enabled", True):
|
|
219
|
+
require_mfa()
|
|
220
|
+
# Preference stored in same session = attacker disables it
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Recovery Code Issues
|
|
224
|
+
|
|
225
|
+
```python
|
|
226
|
+
# DANGEROUS: Predictable recovery codes
|
|
227
|
+
recovery_code = str(user.id).zfill(8) # Just the user ID
|
|
228
|
+
|
|
229
|
+
# DANGEROUS: Unlimited recovery attempts
|
|
230
|
+
for _ in range(1000000):
|
|
231
|
+
try_recovery_code(guess)
|
|
232
|
+
|
|
233
|
+
# DANGEROUS: Recovery codes don't invalidate
|
|
234
|
+
if code in user.recovery_codes:
|
|
235
|
+
login(user)
|
|
236
|
+
# Code still valid for reuse
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Auth API Design Checklist
|
|
240
|
+
|
|
241
|
+
For authentication APIs, verify:
|
|
242
|
+
|
|
243
|
+
- [ ] **Constant-time comparison**: Password/token checks use constant-time compare
|
|
244
|
+
- [ ] **Empty value rejection**: Empty passwords/tokens explicitly rejected
|
|
245
|
+
- [ ] **Uniform errors**: No user enumeration via different error messages
|
|
246
|
+
- [ ] **Session regeneration**: New session ID on auth state changes
|
|
247
|
+
- [ ] **Cryptographic tokens**: secrets module, not random or time-based
|
|
248
|
+
- [ ] **Positive timeouts**: Zero/negative values rejected or have safe meaning
|
|
249
|
+
- [ ] **Single-use tokens**: OTPs/reset tokens invalidated on use
|
|
250
|
+
- [ ] **Rate limiting**: Brute force protection on all auth endpoints
|
|
251
|
+
- [ ] **Authorization centralized**: Not scattered across endpoints
|
|
252
|
+
- [ ] **MFA in backend**: Not bypassable by skipping frontend
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
# Real-World Case Studies
|
|
2
|
+
|
|
3
|
+
Analysis of sharp edges in widely-used libraries. These aren't implementation bugs—they're design decisions that make secure usage difficult.
|
|
4
|
+
|
|
5
|
+
## GNU Multiple Precision Arithmetic Library (GMP)
|
|
6
|
+
|
|
7
|
+
GMP is used extensively for cryptographic implementations (RSA, Paillier, ElGamal, etc.) despite being fundamentally unsuitable for cryptography.
|
|
8
|
+
|
|
9
|
+
### Sharp Edge: Variable-Time Operations
|
|
10
|
+
|
|
11
|
+
**The Problem**: GMP operations are not constant-time. Timing varies based on input values.
|
|
12
|
+
|
|
13
|
+
```c
|
|
14
|
+
// DANGEROUS: Timing leaks secret exponent bits
|
|
15
|
+
mpz_powm(result, base, secret_exponent, modulus);
|
|
16
|
+
|
|
17
|
+
// Each bit of secret_exponent affects timing differently
|
|
18
|
+
// Attacker can recover secret_exponent via timing analysis
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Why This Matters**:
|
|
22
|
+
- Paillier encryption uses `mpz_powm` with secret keys
|
|
23
|
+
- RSA implementations using GMP leak private key bits
|
|
24
|
+
- Even "blinded" implementations often have residual timing leaks
|
|
25
|
+
|
|
26
|
+
**Detection Pattern**: Any use of GMP (`mpz_*` functions) with secret values:
|
|
27
|
+
- `mpz_powm`, `mpz_powm_sec` (the "sec" version is still not fully constant-time)
|
|
28
|
+
- `mpz_mul`, `mpz_mod` with secret operands
|
|
29
|
+
- `mpz_cmp` for secret comparison
|
|
30
|
+
|
|
31
|
+
**Real Vulnerabilities**:
|
|
32
|
+
- CVE-2018-16152: Timing attack on strongSwan IKEv2
|
|
33
|
+
- Numerous academic papers demonstrating key recovery from GMP-based crypto
|
|
34
|
+
|
|
35
|
+
### Sharp Edge: Memory Not Securely Cleared
|
|
36
|
+
|
|
37
|
+
```c
|
|
38
|
+
mpz_t secret_key;
|
|
39
|
+
mpz_init(secret_key);
|
|
40
|
+
// ... use secret_key ...
|
|
41
|
+
mpz_clear(secret_key); // Memory NOT securely wiped
|
|
42
|
+
// Secret data may persist in freed memory
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**The Problem**: `mpz_clear` doesn't zero memory before freeing. Secrets persist.
|
|
46
|
+
|
|
47
|
+
### Sharp Edge: Confusing Import/Export API
|
|
48
|
+
|
|
49
|
+
```c
|
|
50
|
+
// What does this do?
|
|
51
|
+
mpz_export(buf, &count, order, size, endian, nails, op);
|
|
52
|
+
|
|
53
|
+
// Parameters:
|
|
54
|
+
// - order: 1 = most significant word first, -1 = least significant
|
|
55
|
+
// - endian: 1 = big, -1 = little, 0 = native
|
|
56
|
+
// - nails: bits to skip at top of each word (?!)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**The Problem**: Seven parameters, three of which control byte ordering in different ways. Easy to get wrong, hard to verify correctness.
|
|
60
|
+
|
|
61
|
+
### Mitigation
|
|
62
|
+
|
|
63
|
+
For cryptographic use, prefer:
|
|
64
|
+
- **libsodium** for common operations
|
|
65
|
+
- **OpenSSL BIGNUM** (has constant-time variants)
|
|
66
|
+
- **libgmp with mpz_powm_sec** (partial mitigation, not complete)
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## OpenSSL
|
|
71
|
+
|
|
72
|
+
The canonical example of a powerful but footgun-laden cryptographic library.
|
|
73
|
+
|
|
74
|
+
### Sharp Edge: SSL_CTX_set_verify Callback
|
|
75
|
+
|
|
76
|
+
```c
|
|
77
|
+
// DANGEROUS: Easy to write callback that always returns 1
|
|
78
|
+
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback);
|
|
79
|
+
|
|
80
|
+
int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) {
|
|
81
|
+
// Developer thinks: "I'll add logging here"
|
|
82
|
+
log_certificate(ctx);
|
|
83
|
+
return 1; // OOPS: Always accepts, ignoring preverify_ok!
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**The Problem**: The callback's return value determines whether verification succeeds. Developers often:
|
|
88
|
+
- Return 1 (success) unconditionally while "just adding logging"
|
|
89
|
+
- Forget that returning non-zero bypasses all verification
|
|
90
|
+
- Copy-paste examples that return 1 for "debugging"
|
|
91
|
+
|
|
92
|
+
**Correct Pattern**:
|
|
93
|
+
```c
|
|
94
|
+
int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) {
|
|
95
|
+
if (!preverify_ok) {
|
|
96
|
+
// Log failure details
|
|
97
|
+
log_verification_failure(ctx);
|
|
98
|
+
}
|
|
99
|
+
return preverify_ok; // Preserve original decision
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Sharp Edge: Error Handling via ERR_get_error
|
|
104
|
+
|
|
105
|
+
```c
|
|
106
|
+
// DANGEROUS: Error easily ignored
|
|
107
|
+
EVP_EncryptFinal_ex(ctx, outbuf, &outlen);
|
|
108
|
+
// Did it succeed? Who knows!
|
|
109
|
+
|
|
110
|
+
// Correct but verbose:
|
|
111
|
+
if (EVP_EncryptFinal_ex(ctx, outbuf, &outlen) != 1) {
|
|
112
|
+
unsigned long err = ERR_get_error();
|
|
113
|
+
char buf[256];
|
|
114
|
+
ERR_error_string_n(err, buf, sizeof(buf));
|
|
115
|
+
// Handle error...
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**The Problem**:
|
|
120
|
+
- Functions return 1 for success (not 0!)
|
|
121
|
+
- Errors accumulate in a thread-local queue
|
|
122
|
+
- Easy to forget to check, easy to check wrong way
|
|
123
|
+
- Error queue must be cleared or errors persist
|
|
124
|
+
|
|
125
|
+
### Sharp Edge: RAND_bytes vs RAND_pseudo_bytes
|
|
126
|
+
|
|
127
|
+
```c
|
|
128
|
+
// These look almost identical:
|
|
129
|
+
RAND_bytes(buf, len); // Cryptographically secure
|
|
130
|
+
RAND_pseudo_bytes(buf, len); // NOT guaranteed secure!
|
|
131
|
+
|
|
132
|
+
// Worse: RAND_pseudo_bytes returns 1 even when insecure
|
|
133
|
+
int rc = RAND_pseudo_bytes(buf, len);
|
|
134
|
+
// rc == 1 means "success", not "cryptographically random"
|
|
135
|
+
// rc == 0 means "success but not crypto-strength" (!!)
|
|
136
|
+
// rc == -1 means "not supported"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**The Problem**: Function names differ by one word; return values are confusing; the insecure function is not clearly marked dangerous.
|
|
140
|
+
|
|
141
|
+
### Sharp Edge: Memory Ownership Confusion
|
|
142
|
+
|
|
143
|
+
```c
|
|
144
|
+
// Who frees this?
|
|
145
|
+
X509 *cert = SSL_get_peer_certificate(ssl);
|
|
146
|
+
// Answer: YOU do (it's a copy)
|
|
147
|
+
|
|
148
|
+
// Who frees this?
|
|
149
|
+
X509 *cert = SSL_get0_peer_certificate(ssl); // OpenSSL 3.0+
|
|
150
|
+
// Answer: NOBODY (it's a reference)
|
|
151
|
+
|
|
152
|
+
// The difference: "get" vs "get0"
|
|
153
|
+
// This convention is NOT obvious or consistently applied
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**The Problem**: Memory ownership indicated by subtle naming conventions that aren't documented together and aren't consistent across the API.
|
|
157
|
+
|
|
158
|
+
### Sharp Edge: EVP_CIPHER_CTX Reuse
|
|
159
|
+
|
|
160
|
+
```c
|
|
161
|
+
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
|
|
162
|
+
EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, key, iv);
|
|
163
|
+
EVP_EncryptUpdate(ctx, out, &outlen, in, inlen);
|
|
164
|
+
EVP_EncryptFinal_ex(ctx, out + outlen, &tmplen);
|
|
165
|
+
|
|
166
|
+
// DANGEROUS: Reusing ctx without reset
|
|
167
|
+
EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv2); // New IV only
|
|
168
|
+
// Some state from previous encryption may persist!
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**The Problem**: Context reuse rules are complex and vary by cipher mode.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Python's `pickle`
|
|
176
|
+
|
|
177
|
+
### Sharp Edge: Arbitrary Code Execution by Design
|
|
178
|
+
|
|
179
|
+
```python
|
|
180
|
+
import pickle
|
|
181
|
+
|
|
182
|
+
# DANGEROUS: Deserializes arbitrary Python objects
|
|
183
|
+
data = pickle.loads(untrusted_input)
|
|
184
|
+
|
|
185
|
+
# Attacker sends:
|
|
186
|
+
# b"cos\nsystem\n(S'rm -rf /'\ntR."
|
|
187
|
+
# Result: Executes shell command
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**The Problem**: `pickle` is not a data format—it's a code execution format. There is no safe way to unpickle untrusted data, but:
|
|
191
|
+
- The function looks like a data parser
|
|
192
|
+
- The name suggests food preservation, not danger
|
|
193
|
+
- Many developers don't realize the risk
|
|
194
|
+
|
|
195
|
+
**Mitigation**: Use `json` for data. If you need pickle, use `hmac` to authenticate before unpickling (but even then, prefer safer formats).
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## YAML Libraries
|
|
200
|
+
|
|
201
|
+
### Sharp Edge: Code Execution via Tags
|
|
202
|
+
|
|
203
|
+
```python
|
|
204
|
+
import yaml
|
|
205
|
+
|
|
206
|
+
# DANGEROUS: yaml.load() executes arbitrary code
|
|
207
|
+
data = yaml.load(untrusted_input)
|
|
208
|
+
|
|
209
|
+
# Attacker sends:
|
|
210
|
+
# !!python/object/apply:os.system ['rm -rf /']
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**The Problem**: YAML's tag system allows arbitrary object instantiation. The "safe" loader is:
|
|
214
|
+
```python
|
|
215
|
+
data = yaml.safe_load(untrusted_input) # Safe
|
|
216
|
+
data = yaml.load(untrusted_input, Loader=yaml.SafeLoader) # Also safe
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
But the dangerous version is the obvious one (`yaml.load()`).
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## PHP's `strcmp` for Password Comparison
|
|
224
|
+
|
|
225
|
+
### Sharp Edge: Type Juggling Bypass
|
|
226
|
+
|
|
227
|
+
```php
|
|
228
|
+
// DANGEROUS: Type juggling attack
|
|
229
|
+
if (strcmp($_POST['password'], $stored_password) == 0) {
|
|
230
|
+
authenticate();
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Attacker sends: password[]=anything
|
|
234
|
+
// strcmp(array, string) returns NULL
|
|
235
|
+
// NULL == 0 is TRUE in PHP!
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
**The Problem**:
|
|
239
|
+
- `strcmp` returns `NULL` on type error, not `-1` or `1`
|
|
240
|
+
- PHP's `==` operator coerces `NULL` to `0`
|
|
241
|
+
- `NULL == 0` evaluates to `TRUE`
|
|
242
|
+
- Authentication bypassed
|
|
243
|
+
|
|
244
|
+
**Fix**:
|
|
245
|
+
```php
|
|
246
|
+
if (hash_equals($stored_hash, hash('sha256', $_POST['password']))) {
|
|
247
|
+
// Use hash_equals for timing-safe comparison
|
|
248
|
+
// AND proper password hashing (not shown)
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Analysis Template
|
|
255
|
+
|
|
256
|
+
When examining a library for sharp edges:
|
|
257
|
+
|
|
258
|
+
### Input → Expected Output
|
|
259
|
+
|
|
260
|
+
| Input | Expected | Actual | Vulnerability |
|
|
261
|
+
|-------|----------|--------|---------------|
|
|
262
|
+
| `verify_ssl=false` | Clear warning | Silent acceptance | Config cliff |
|
|
263
|
+
| `password=""` | Rejection | Login success | Empty bypass |
|
|
264
|
+
| `algorithm="none"` | Error | Signature skipped | Downgrade |
|
|
265
|
+
| `timeout=-1` | Error | Infinite timeout | Magic value |
|
|
266
|
+
|
|
267
|
+
### Library Comparison
|
|
268
|
+
|
|
269
|
+
| Feature | Dangerous Library | Safer Alternative |
|
|
270
|
+
|---------|------------------|-------------------|
|
|
271
|
+
| Bignum crypto | GMP | libsodium, OpenSSL BIGNUM |
|
|
272
|
+
| TLS | Raw OpenSSL | Higher-level wrappers |
|
|
273
|
+
| Serialization | pickle, YAML | JSON, protobuf |
|
|
274
|
+
| Password compare | strcmp | hash_equals, secrets.compare_digest |
|