Identify dangerous-but-tempting API patterns in React/Next.js/Supabase. Finds "footguns" - APIs that look safe but fail silently or have dangerous defaults. Inspired by Trail of Bits methodology.
View on GitHubmralbertzwolle/vibe-coding-academy-tools
security-audit
plugins/security-audit/skills/sharp-edges/SKILL.md
January 21, 2026
Select agents to install to:
npx add-skill https://github.com/mralbertzwolle/vibe-coding-academy-tools/blob/main/plugins/security-audit/skills/sharp-edges/SKILL.md -a claude-code --skill sharp-edgesInstallation paths:
.claude/skills/sharp-edges/# Sharp Edges Skill
Identifies **misuse-prone APIs and dangerous defaults** in your React/Next.js/Supabase codebase. These are patterns that look correct but fail silently or have security implications.
## Philosophy
> "The pit of success: Secure usage should be the path of least resistance."
If developers must remember special rules to avoid vulnerabilities, the API design (or usage) has failed. This skill finds code where the "obvious" approach is wrong.
## The Three Adversaries
Every pattern is evaluated against:
1. **The Scoundrel** - Malicious user exploiting the code
2. **The Lazy Developer** - Copy-paste without understanding
3. **The Confused Developer** - Mixing up similar parameters
## Detection Categories
### 1. Dangerous Defaults (12 checks)
APIs where the default behavior is insecure.
| Pattern | Risk | Fix |
|---------|------|-----|
| `fetch()` without timeout | DoS via slow response | Add `AbortController` with timeout |
| `JSON.parse()` without try/catch | Crash on invalid JSON | Wrap in try/catch |
| `new Date(userInput)` | Invalid date = `NaN` propagates | Validate with `isNaN()` |
| `parseInt(input)` without radix | `parseInt('08')` = 0 in old JS | Always use `parseInt(x, 10)` |
| `Array.sort()` without comparator | Sorts as strings: `[1,10,2]` | Provide `(a,b) => a-b` |
| `Math.random()` for security | Predictable, not cryptographic | Use `crypto.randomUUID()` |
| `btoa()/atob()` for encoding | Fails on Unicode | Use `TextEncoder`/`TextDecoder` |
| `localStorage` for tokens | XSS = token theft | Use httpOnly cookies |
| `eval()` or `new Function()` | Code injection | Never use with user input |
| `innerHTML` assignment | XSS | Use `textContent` or sanitize |
| `document.write()` | Overwrites entire page | Use DOM methods |
| `setTimeout(string)` | Same as eval | Pass function reference |
### 2. Silent Failures (10 checks)
APIs that fail without throwing errors.
| Pattern | Risk | Fix |
|---------|------|-----|
| `array.find()` retur