start-vibing 4.0.2 → 4.1.1
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/package.json +1 -1
- package/template/.claude/CLAUDE.md +86 -20
- package/template/.claude/agents/sd-audit.md +197 -0
- package/template/.claude/agents/sd-fix-verify-semantic.md +112 -0
- package/template/.claude/agents/sd-fix-verify-technical.md +36 -0
- package/template/.claude/agents/sd-fix.md +194 -0
- package/template/.claude/agents/sd-research.md +61 -0
- package/template/.claude/agents/sd-synthesis.md +74 -0
- package/template/.claude/commands/super-design.md +15 -0
- package/template/.claude/hooks/super-design-session-start.sh +4 -0
- package/template/.claude/settings.json +14 -0
- package/template/.claude/skills/codebase-knowledge/SKILL.md +145 -0
- package/template/.claude/skills/codebase-knowledge/TEMPLATE.md +35 -0
- package/template/.claude/skills/codebase-knowledge/domains/claude-system.md +93 -0
- package/template/.claude/skills/composition-patterns/SKILL.md +89 -0
- package/template/.claude/skills/docs-tracker/SKILL.md +239 -0
- package/template/.claude/skills/mcp-builder/SKILL.md +236 -0
- package/template/.claude/skills/quality-gate/scripts/check-all.sh +83 -0
- package/template/.claude/skills/react-best-practices/SKILL.md +146 -0
- package/template/.claude/skills/security-scan/reference/owasp-top-10.md +257 -0
- package/template/.claude/skills/security-scan/scripts/scan.py +190 -0
- package/template/.claude/skills/super-design/README.md +37 -0
- package/template/.claude/skills/super-design/SKILL.md +105 -0
- package/template/.claude/skills/super-design/hooks/guard-paths.py +35 -0
- package/template/.claude/skills/super-design/hooks/post-edit-lint.py +57 -0
- package/template/.claude/skills/super-design/references/audit-methodology.md +513 -0
- package/template/.claude/skills/super-design/references/change-detection-playbook.md +1432 -0
- package/template/.claude/skills/super-design/references/design-theory.md +706 -0
- package/template/.claude/skills/super-design/references/fix-agent-playbook.md +118 -0
- package/template/.claude/skills/super-design/references/market-research-playbook.md +773 -0
- package/template/.claude/skills/super-design/references/playwright-mcp-reference.md +1057 -0
- package/template/.claude/skills/super-design/references/skills-subagents-reference.md +784 -0
- package/template/.claude/skills/super-design/references/superpowers-and-distribution.md +136 -0
- package/template/.claude/skills/super-design/scripts/detect-changes.sh +61 -0
- package/template/.claude/skills/super-design/scripts/diff-tokens.sh +13 -0
- package/template/.claude/skills/super-design/scripts/discover-routes.sh +45 -0
- package/template/.claude/skills/super-design/scripts/extract-tokens.mjs +41 -0
- package/template/.claude/skills/super-design/scripts/hash-pages.sh +42 -0
- package/template/.claude/skills/super-design/scripts/validate-state.sh +15 -0
- package/template/.claude/skills/super-design/scripts/verify-audit.sh +19 -0
- package/template/.claude/skills/super-design/templates/audit-state.schema.json +57 -0
- package/template/.claude/skills/super-design/templates/findings.schema.json +57 -0
- package/template/.claude/skills/super-design/templates/fix-history.md.tpl +26 -0
- package/template/.claude/skills/super-design/templates/overview.md.tpl +52 -0
- package/template/.claude/skills/test-coverage/reference/playwright-patterns.md +260 -0
- package/template/.claude/skills/test-coverage/scripts/coverage-check.sh +52 -0
- package/template/.claude/skills/typeui-ant/SKILL.md +133 -0
- package/template/.claude/skills/typeui-application/SKILL.md +128 -0
- package/template/.claude/skills/typeui-artistic/SKILL.md +133 -0
- package/template/.claude/skills/typeui-bento/SKILL.md +127 -0
- package/template/.claude/skills/typeui-bold/SKILL.md +127 -0
- package/template/.claude/skills/typeui-clean/SKILL.md +128 -0
- package/template/.claude/skills/typeui-dashboard/SKILL.md +133 -0
- package/template/.claude/skills/typeui-doodle/SKILL.md +142 -0
- package/template/.claude/skills/typeui-dramatic/SKILL.md +127 -0
- package/template/.claude/skills/typeui-enterprise/SKILL.md +132 -0
- package/template/.claude/skills/typeui-neobrutalism/SKILL.md +127 -0
- package/template/.claude/skills/typeui-paper/SKILL.md +127 -0
- package/template/.claude/skills/ui-ux-audit/QUICK-START.md +450 -0
- package/template/.claude/skills/ui-ux-audit/README.md +470 -0
- package/template/.claude/skills/ui-ux-audit/templates/audit-report.md +591 -0
- package/template/.claude/skills/ui-ux-audit/templates/competitor-analysis.md +363 -0
- package/template/.claude/skills/ui-ux-audit/templates/component-spec.md +491 -0
- package/template/.claude/skills/ui-ux-audit/templates/improvement-recommendation.md +450 -0
- package/template/.claude/skills/web-design-guidelines/SKILL.md +39 -0
- package/template/.claude/skills/webapp-testing/SKILL.md +96 -0
- package/template/.claude/skills/workflow-state/workflow-state.json +77 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vercel-react-best-practices
|
|
3
|
+
description: React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
|
|
4
|
+
license: MIT
|
|
5
|
+
metadata:
|
|
6
|
+
author: vercel
|
|
7
|
+
version: "1.0.0"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Vercel React Best Practices
|
|
11
|
+
|
|
12
|
+
Comprehensive performance optimization guide for React and Next.js applications, maintained by Vercel. Contains 67 rules across 8 categories, prioritized by impact to guide automated refactoring and code generation.
|
|
13
|
+
|
|
14
|
+
## When to Apply
|
|
15
|
+
|
|
16
|
+
Reference these guidelines when:
|
|
17
|
+
- Writing new React components or Next.js pages
|
|
18
|
+
- Implementing data fetching (client or server-side)
|
|
19
|
+
- Reviewing code for performance issues
|
|
20
|
+
- Refactoring existing React/Next.js code
|
|
21
|
+
- Optimizing bundle size or load times
|
|
22
|
+
|
|
23
|
+
## Rule Categories by Priority
|
|
24
|
+
|
|
25
|
+
| Priority | Category | Impact | Prefix |
|
|
26
|
+
|----------|----------|--------|--------|
|
|
27
|
+
| 1 | Eliminating Waterfalls | CRITICAL | `async-` |
|
|
28
|
+
| 2 | Bundle Size Optimization | CRITICAL | `bundle-` |
|
|
29
|
+
| 3 | Server-Side Performance | HIGH | `server-` |
|
|
30
|
+
| 4 | Client-Side Data Fetching | MEDIUM-HIGH | `client-` |
|
|
31
|
+
| 5 | Re-render Optimization | MEDIUM | `rerender-` |
|
|
32
|
+
| 6 | Rendering Performance | MEDIUM | `rendering-` |
|
|
33
|
+
| 7 | JavaScript Performance | LOW-MEDIUM | `js-` |
|
|
34
|
+
| 8 | Advanced Patterns | LOW | `advanced-` |
|
|
35
|
+
|
|
36
|
+
## Quick Reference
|
|
37
|
+
|
|
38
|
+
### 1. Eliminating Waterfalls (CRITICAL)
|
|
39
|
+
|
|
40
|
+
- `async-cheap-condition-before-await` - Check cheap sync conditions before awaiting flags or remote values
|
|
41
|
+
- `async-defer-await` - Move await into branches where actually used
|
|
42
|
+
- `async-parallel` - Use Promise.all() for independent operations
|
|
43
|
+
- `async-dependencies` - Use better-all for partial dependencies
|
|
44
|
+
- `async-api-routes` - Start promises early, await late in API routes
|
|
45
|
+
- `async-suspense-boundaries` - Use Suspense to stream content
|
|
46
|
+
|
|
47
|
+
### 2. Bundle Size Optimization (CRITICAL)
|
|
48
|
+
|
|
49
|
+
- `bundle-barrel-imports` - Import directly, avoid barrel files
|
|
50
|
+
- `bundle-dynamic-imports` - Use next/dynamic for heavy components
|
|
51
|
+
- `bundle-defer-third-party` - Load analytics/logging after hydration
|
|
52
|
+
- `bundle-conditional` - Load modules only when feature is activated
|
|
53
|
+
- `bundle-preload` - Preload on hover/focus for perceived speed
|
|
54
|
+
|
|
55
|
+
### 3. Server-Side Performance (HIGH)
|
|
56
|
+
|
|
57
|
+
- `server-auth-actions` - Authenticate server actions like API routes
|
|
58
|
+
- `server-cache-react` - Use React.cache() for per-request deduplication
|
|
59
|
+
- `server-cache-lru` - Use LRU cache for cross-request caching
|
|
60
|
+
- `server-dedup-props` - Avoid duplicate serialization in RSC props
|
|
61
|
+
- `server-hoist-static-io` - Hoist static I/O (fonts, logos) to module level
|
|
62
|
+
- `server-serialization` - Minimize data passed to client components
|
|
63
|
+
- `server-parallel-fetching` - Restructure components to parallelize fetches
|
|
64
|
+
- `server-parallel-nested-fetching` - Chain nested fetches per item in Promise.all
|
|
65
|
+
- `server-after-nonblocking` - Use after() for non-blocking operations
|
|
66
|
+
|
|
67
|
+
### 4. Client-Side Data Fetching (MEDIUM-HIGH)
|
|
68
|
+
|
|
69
|
+
- `client-swr-dedup` - Use SWR for automatic request deduplication
|
|
70
|
+
- `client-event-listeners` - Deduplicate global event listeners
|
|
71
|
+
- `client-passive-event-listeners` - Use passive listeners for scroll
|
|
72
|
+
- `client-localstorage-schema` - Version and minimize localStorage data
|
|
73
|
+
|
|
74
|
+
### 5. Re-render Optimization (MEDIUM)
|
|
75
|
+
|
|
76
|
+
- `rerender-defer-reads` - Don't subscribe to state only used in callbacks
|
|
77
|
+
- `rerender-memo` - Extract expensive work into memoized components
|
|
78
|
+
- `rerender-memo-with-default-value` - Hoist default non-primitive props
|
|
79
|
+
- `rerender-dependencies` - Use primitive dependencies in effects
|
|
80
|
+
- `rerender-derived-state` - Subscribe to derived booleans, not raw values
|
|
81
|
+
- `rerender-derived-state-no-effect` - Derive state during render, not effects
|
|
82
|
+
- `rerender-functional-setstate` - Use functional setState for stable callbacks
|
|
83
|
+
- `rerender-lazy-state-init` - Pass function to useState for expensive values
|
|
84
|
+
- `rerender-simple-expression-in-memo` - Avoid memo for simple primitives
|
|
85
|
+
- `rerender-split-combined-hooks` - Split hooks with independent dependencies
|
|
86
|
+
- `rerender-move-effect-to-event` - Put interaction logic in event handlers
|
|
87
|
+
- `rerender-transitions` - Use startTransition for non-urgent updates
|
|
88
|
+
- `rerender-use-deferred-value` - Defer expensive renders to keep input responsive
|
|
89
|
+
- `rerender-use-ref-transient-values` - Use refs for transient frequent values
|
|
90
|
+
- `rerender-no-inline-components` - Don't define components inside components
|
|
91
|
+
|
|
92
|
+
### 6. Rendering Performance (MEDIUM)
|
|
93
|
+
|
|
94
|
+
- `rendering-animate-svg-wrapper` - Animate div wrapper, not SVG element
|
|
95
|
+
- `rendering-content-visibility` - Use content-visibility for long lists
|
|
96
|
+
- `rendering-hoist-jsx` - Extract static JSX outside components
|
|
97
|
+
- `rendering-svg-precision` - Reduce SVG coordinate precision
|
|
98
|
+
- `rendering-hydration-no-flicker` - Use inline script for client-only data
|
|
99
|
+
- `rendering-hydration-suppress-warning` - Suppress expected mismatches
|
|
100
|
+
- `rendering-activity` - Use Activity component for show/hide
|
|
101
|
+
- `rendering-conditional-render` - Use ternary, not && for conditionals
|
|
102
|
+
- `rendering-usetransition-loading` - Prefer useTransition for loading state
|
|
103
|
+
- `rendering-resource-hints` - Use React DOM resource hints for preloading
|
|
104
|
+
- `rendering-script-defer-async` - Use defer or async on script tags
|
|
105
|
+
|
|
106
|
+
### 7. JavaScript Performance (LOW-MEDIUM)
|
|
107
|
+
|
|
108
|
+
- `js-batch-dom-css` - Group CSS changes via classes or cssText
|
|
109
|
+
- `js-index-maps` - Build Map for repeated lookups
|
|
110
|
+
- `js-cache-property-access` - Cache object properties in loops
|
|
111
|
+
- `js-cache-function-results` - Cache function results in module-level Map
|
|
112
|
+
- `js-cache-storage` - Cache localStorage/sessionStorage reads
|
|
113
|
+
- `js-combine-iterations` - Combine multiple filter/map into one loop
|
|
114
|
+
- `js-length-check-first` - Check array length before expensive comparison
|
|
115
|
+
- `js-early-exit` - Return early from functions
|
|
116
|
+
- `js-hoist-regexp` - Hoist RegExp creation outside loops
|
|
117
|
+
- `js-min-max-loop` - Use loop for min/max instead of sort
|
|
118
|
+
- `js-set-map-lookups` - Use Set/Map for O(1) lookups
|
|
119
|
+
- `js-tosorted-immutable` - Use toSorted() for immutability
|
|
120
|
+
- `js-flatmap-filter` - Use flatMap to map and filter in one pass
|
|
121
|
+
- `js-request-idle-callback` - Defer non-critical work to browser idle time
|
|
122
|
+
|
|
123
|
+
### 8. Advanced Patterns (LOW)
|
|
124
|
+
|
|
125
|
+
- `advanced-event-handler-refs` - Store event handlers in refs
|
|
126
|
+
- `advanced-init-once` - Initialize app once per app load
|
|
127
|
+
- `advanced-use-latest` - useLatest for stable callback refs
|
|
128
|
+
|
|
129
|
+
## How to Use
|
|
130
|
+
|
|
131
|
+
Read individual rule files for detailed explanations and code examples:
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
rules/async-parallel.md
|
|
135
|
+
rules/bundle-barrel-imports.md
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Each rule file contains:
|
|
139
|
+
- Brief explanation of why it matters
|
|
140
|
+
- Incorrect code example with explanation
|
|
141
|
+
- Correct code example with explanation
|
|
142
|
+
- Additional context and references
|
|
143
|
+
|
|
144
|
+
## Full Compiled Document
|
|
145
|
+
|
|
146
|
+
For the complete guide with all rules expanded: `AGENTS.md`
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# OWASP Top 10 (2021) - Detailed Checklist
|
|
2
|
+
|
|
3
|
+
## A01:2021 - Broken Access Control
|
|
4
|
+
|
|
5
|
+
### What to Check
|
|
6
|
+
|
|
7
|
+
- [ ] All protected routes use authentication middleware
|
|
8
|
+
- [ ] User ID always comes from session, never from input
|
|
9
|
+
- [ ] Resources filtered by user/tenant before returning
|
|
10
|
+
- [ ] Admin routes check admin role explicitly
|
|
11
|
+
- [ ] CORS configured correctly (not `*` in production)
|
|
12
|
+
- [ ] Directory listing disabled
|
|
13
|
+
- [ ] Rate limiting on sensitive endpoints
|
|
14
|
+
|
|
15
|
+
### Detection Patterns
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Find routes without auth middleware
|
|
19
|
+
grep -r "router\." --include="*.ts" | grep -v "auth\|middleware"
|
|
20
|
+
|
|
21
|
+
# Find user ID from input
|
|
22
|
+
grep -rn "userId.*req\.(body\|params\|query)" --include="*.ts"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Fix Examples
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
// BAD
|
|
29
|
+
router.get('/users/:userId', async (req, res) => {
|
|
30
|
+
const user = await User.findById(req.params.userId);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// GOOD
|
|
34
|
+
router.get('/users/:userId', authMiddleware, async (req, res) => {
|
|
35
|
+
if (req.user._id.toString() !== req.params.userId) {
|
|
36
|
+
return res.status(403).json({ error: 'Forbidden' });
|
|
37
|
+
}
|
|
38
|
+
const user = await User.findById(req.params.userId);
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## A02:2021 - Cryptographic Failures
|
|
45
|
+
|
|
46
|
+
### What to Check
|
|
47
|
+
|
|
48
|
+
- [ ] Passwords hashed with bcrypt/argon2 (not MD5/SHA1)
|
|
49
|
+
- [ ] Tokens generated with crypto.randomBytes
|
|
50
|
+
- [ ] HTTPS enforced in production
|
|
51
|
+
- [ ] Sensitive data not in URLs
|
|
52
|
+
- [ ] Cookies have Secure, HttpOnly, SameSite flags
|
|
53
|
+
- [ ] No secrets in code or logs
|
|
54
|
+
|
|
55
|
+
### Detection Patterns
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Find weak hashing
|
|
59
|
+
grep -rn "md5\|sha1\|createHash" --include="*.ts"
|
|
60
|
+
|
|
61
|
+
# Find hardcoded secrets
|
|
62
|
+
grep -rn "password\s*=\s*[\"']" --include="*.ts"
|
|
63
|
+
grep -rn "secret\s*=\s*[\"']" --include="*.ts"
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Fix Examples
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
// BAD
|
|
70
|
+
const hash = crypto.createHash('md5').update(password).digest('hex');
|
|
71
|
+
|
|
72
|
+
// GOOD
|
|
73
|
+
import bcrypt from 'bcrypt';
|
|
74
|
+
const hash = await bcrypt.hash(password, 12);
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## A03:2021 - Injection
|
|
80
|
+
|
|
81
|
+
### What to Check
|
|
82
|
+
|
|
83
|
+
- [ ] SQL queries use parameterized statements
|
|
84
|
+
- [ ] MongoDB queries use Mongoose (not raw)
|
|
85
|
+
- [ ] User input never concatenated into queries
|
|
86
|
+
- [ ] Command execution avoids user input
|
|
87
|
+
- [ ] LDAP/XML queries sanitized
|
|
88
|
+
|
|
89
|
+
### Detection Patterns
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# Find raw query concatenation
|
|
93
|
+
grep -rn "\$where\|eval\|exec(" --include="*.ts"
|
|
94
|
+
|
|
95
|
+
# Find string concatenation in queries
|
|
96
|
+
grep -rn "find.*\+" --include="*.ts"
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Fix Examples
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
// BAD - NoSQL injection
|
|
103
|
+
User.find({ username: req.body.username });
|
|
104
|
+
// Attacker sends: { "$gt": "" }
|
|
105
|
+
|
|
106
|
+
// GOOD - Validate type
|
|
107
|
+
const username = z.string().parse(req.body.username);
|
|
108
|
+
User.find({ username });
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## A04:2021 - Insecure Design
|
|
114
|
+
|
|
115
|
+
### What to Check
|
|
116
|
+
|
|
117
|
+
- [ ] Business logic validated server-side
|
|
118
|
+
- [ ] Multi-step processes maintain state
|
|
119
|
+
- [ ] Resource limits enforced
|
|
120
|
+
- [ ] Rate limiting on expensive operations
|
|
121
|
+
- [ ] Threat modeling performed
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## A05:2021 - Security Misconfiguration
|
|
126
|
+
|
|
127
|
+
### What to Check
|
|
128
|
+
|
|
129
|
+
- [ ] Error messages don't leak stack traces
|
|
130
|
+
- [ ] Default credentials changed
|
|
131
|
+
- [ ] Unnecessary features disabled
|
|
132
|
+
- [ ] Security headers set (CSP, HSTS, etc.)
|
|
133
|
+
- [ ] Dependencies updated regularly
|
|
134
|
+
|
|
135
|
+
### Security Headers
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
app.use(
|
|
139
|
+
helmet({
|
|
140
|
+
contentSecurityPolicy: true,
|
|
141
|
+
crossOriginEmbedderPolicy: true,
|
|
142
|
+
crossOriginOpenerPolicy: true,
|
|
143
|
+
crossOriginResourcePolicy: true,
|
|
144
|
+
dnsPrefetchControl: true,
|
|
145
|
+
frameguard: true,
|
|
146
|
+
hidePoweredBy: true,
|
|
147
|
+
hsts: true,
|
|
148
|
+
ieNoOpen: true,
|
|
149
|
+
noSniff: true,
|
|
150
|
+
originAgentCluster: true,
|
|
151
|
+
permittedCrossDomainPolicies: true,
|
|
152
|
+
referrerPolicy: true,
|
|
153
|
+
xssFilter: true,
|
|
154
|
+
})
|
|
155
|
+
);
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## A06:2021 - Vulnerable Components
|
|
161
|
+
|
|
162
|
+
### What to Check
|
|
163
|
+
|
|
164
|
+
- [ ] Dependencies audited regularly
|
|
165
|
+
- [ ] No known CVEs in dependencies
|
|
166
|
+
- [ ] Outdated packages updated
|
|
167
|
+
- [ ] Lock file committed
|
|
168
|
+
|
|
169
|
+
### Commands
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
# Check for vulnerabilities
|
|
173
|
+
bun audit
|
|
174
|
+
|
|
175
|
+
# Update dependencies
|
|
176
|
+
bun update --latest
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## A07:2021 - Authentication Failures
|
|
182
|
+
|
|
183
|
+
### What to Check
|
|
184
|
+
|
|
185
|
+
- [ ] Passwords have minimum requirements
|
|
186
|
+
- [ ] Brute force protection (rate limiting)
|
|
187
|
+
- [ ] Sessions invalidated on logout
|
|
188
|
+
- [ ] Session timeout implemented
|
|
189
|
+
- [ ] MFA available for sensitive ops
|
|
190
|
+
- [ ] Password reset tokens expire
|
|
191
|
+
|
|
192
|
+
### Detection Patterns
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
# Find login without rate limiting
|
|
196
|
+
grep -rn "login\|signin" --include="*.ts" | grep -v "rateLimit"
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## A08:2021 - Software and Data Integrity
|
|
202
|
+
|
|
203
|
+
### What to Check
|
|
204
|
+
|
|
205
|
+
- [ ] CI/CD pipeline secured
|
|
206
|
+
- [ ] Dependencies from trusted sources
|
|
207
|
+
- [ ] Code signing for releases
|
|
208
|
+
- [ ] Integrity checks on downloads
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## A09:2021 - Security Logging and Monitoring
|
|
213
|
+
|
|
214
|
+
### What to Check
|
|
215
|
+
|
|
216
|
+
- [ ] Authentication attempts logged
|
|
217
|
+
- [ ] Access control failures logged
|
|
218
|
+
- [ ] Input validation failures logged
|
|
219
|
+
- [ ] Logs don't contain sensitive data
|
|
220
|
+
- [ ] Alerting configured for anomalies
|
|
221
|
+
|
|
222
|
+
### What to Log
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
logger.warn('Failed login attempt', {
|
|
226
|
+
ip: req.ip,
|
|
227
|
+
username: req.body.username,
|
|
228
|
+
timestamp: new Date().toISOString(),
|
|
229
|
+
// Never log password!
|
|
230
|
+
});
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## A10:2021 - Server-Side Request Forgery (SSRF)
|
|
236
|
+
|
|
237
|
+
### What to Check
|
|
238
|
+
|
|
239
|
+
- [ ] URLs validated before fetching
|
|
240
|
+
- [ ] Internal networks blocked
|
|
241
|
+
- [ ] Allowlist for external services
|
|
242
|
+
- [ ] Response type validated
|
|
243
|
+
|
|
244
|
+
### Fix Examples
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
// BAD - SSRF vulnerable
|
|
248
|
+
const response = await fetch(req.body.url);
|
|
249
|
+
|
|
250
|
+
// GOOD - Validate URL
|
|
251
|
+
const allowedHosts = ['api.example.com'];
|
|
252
|
+
const url = new URL(req.body.url);
|
|
253
|
+
if (!allowedHosts.includes(url.hostname)) {
|
|
254
|
+
throw new Error('Host not allowed');
|
|
255
|
+
}
|
|
256
|
+
const response = await fetch(url.toString());
|
|
257
|
+
```
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Security Scanner Script
|
|
4
|
+
Scans codebase for common security vulnerabilities.
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
python .claude/skills/security-scan/scripts/scan.py [path]
|
|
8
|
+
|
|
9
|
+
Returns JSON with findings.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import os
|
|
13
|
+
import re
|
|
14
|
+
import json
|
|
15
|
+
import sys
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
from typing import List, Dict, Any
|
|
18
|
+
|
|
19
|
+
# Patterns to detect vulnerabilities
|
|
20
|
+
VULNERABILITY_PATTERNS = {
|
|
21
|
+
"user_id_from_input": {
|
|
22
|
+
"pattern": r"userId.*req\.(body|params|query)",
|
|
23
|
+
"severity": "CRITICAL",
|
|
24
|
+
"message": "User ID from request input - use session instead",
|
|
25
|
+
"owasp": "A01"
|
|
26
|
+
},
|
|
27
|
+
"password_in_response": {
|
|
28
|
+
"pattern": r"(password|senha).*res\.(json|send)",
|
|
29
|
+
"severity": "CRITICAL",
|
|
30
|
+
"message": "Password may be sent in response",
|
|
31
|
+
"owasp": "A02"
|
|
32
|
+
},
|
|
33
|
+
"weak_hash": {
|
|
34
|
+
"pattern": r"createHash\(['\"]md5['\"]\)|createHash\(['\"]sha1['\"]\)",
|
|
35
|
+
"severity": "HIGH",
|
|
36
|
+
"message": "Weak hashing algorithm - use bcrypt or argon2",
|
|
37
|
+
"owasp": "A02"
|
|
38
|
+
},
|
|
39
|
+
"hardcoded_secret": {
|
|
40
|
+
"pattern": r"(password|secret|api_key)\s*=\s*['\"][^'\"]+['\"]",
|
|
41
|
+
"severity": "HIGH",
|
|
42
|
+
"message": "Hardcoded secret detected",
|
|
43
|
+
"owasp": "A02"
|
|
44
|
+
},
|
|
45
|
+
"no_input_validation": {
|
|
46
|
+
"pattern": r"\.mutation\(\s*async\s*\(\s*\{\s*input\s*\}\s*\)",
|
|
47
|
+
"severity": "MEDIUM",
|
|
48
|
+
"message": "Mutation without .input() validation",
|
|
49
|
+
"owasp": "A03"
|
|
50
|
+
},
|
|
51
|
+
"eval_usage": {
|
|
52
|
+
"pattern": r"\beval\s*\(|new\s+Function\s*\(",
|
|
53
|
+
"severity": "CRITICAL",
|
|
54
|
+
"message": "Dangerous eval() or Function() usage",
|
|
55
|
+
"owasp": "A03"
|
|
56
|
+
},
|
|
57
|
+
"sql_concatenation": {
|
|
58
|
+
"pattern": r"(SELECT|INSERT|UPDATE|DELETE).*\+.*req\.",
|
|
59
|
+
"severity": "CRITICAL",
|
|
60
|
+
"message": "SQL query with string concatenation",
|
|
61
|
+
"owasp": "A03"
|
|
62
|
+
},
|
|
63
|
+
"missing_auth_check": {
|
|
64
|
+
"pattern": r"router\.(get|post|put|delete)\s*\([^,]+,\s*async",
|
|
65
|
+
"severity": "MEDIUM",
|
|
66
|
+
"message": "Route may be missing auth middleware",
|
|
67
|
+
"owasp": "A01"
|
|
68
|
+
},
|
|
69
|
+
"cors_wildcard": {
|
|
70
|
+
"pattern": r"cors\(\s*\{\s*origin:\s*['\"]?\*['\"]?\s*\}",
|
|
71
|
+
"severity": "MEDIUM",
|
|
72
|
+
"message": "CORS with wildcard origin",
|
|
73
|
+
"owasp": "A05"
|
|
74
|
+
},
|
|
75
|
+
"stack_trace_leak": {
|
|
76
|
+
"pattern": r"res\.(json|send)\s*\(\s*\{[^}]*error\.stack",
|
|
77
|
+
"severity": "MEDIUM",
|
|
78
|
+
"message": "Stack trace may be leaked in response",
|
|
79
|
+
"owasp": "A05"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
# File extensions to scan
|
|
84
|
+
SCAN_EXTENSIONS = {'.ts', '.tsx', '.js', '.jsx'}
|
|
85
|
+
|
|
86
|
+
# Directories to skip
|
|
87
|
+
SKIP_DIRS = {
|
|
88
|
+
'node_modules', '.next', 'dist', 'build',
|
|
89
|
+
'.git', '__pycache__', 'coverage'
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def should_scan_file(path: Path) -> bool:
|
|
94
|
+
"""Check if file should be scanned."""
|
|
95
|
+
# Skip directories
|
|
96
|
+
for skip in SKIP_DIRS:
|
|
97
|
+
if skip in path.parts:
|
|
98
|
+
return False
|
|
99
|
+
|
|
100
|
+
# Check extension
|
|
101
|
+
return path.suffix in SCAN_EXTENSIONS
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def scan_file(file_path: Path) -> List[Dict[str, Any]]:
|
|
105
|
+
"""Scan a single file for vulnerabilities."""
|
|
106
|
+
findings = []
|
|
107
|
+
|
|
108
|
+
try:
|
|
109
|
+
content = file_path.read_text(encoding='utf-8', errors='ignore')
|
|
110
|
+
lines = content.split('\n')
|
|
111
|
+
|
|
112
|
+
for vuln_name, vuln_info in VULNERABILITY_PATTERNS.items():
|
|
113
|
+
pattern = re.compile(vuln_info['pattern'], re.IGNORECASE)
|
|
114
|
+
|
|
115
|
+
for line_num, line in enumerate(lines, 1):
|
|
116
|
+
if pattern.search(line):
|
|
117
|
+
findings.append({
|
|
118
|
+
"file": str(file_path),
|
|
119
|
+
"line": line_num,
|
|
120
|
+
"vulnerability": vuln_name,
|
|
121
|
+
"severity": vuln_info['severity'],
|
|
122
|
+
"message": vuln_info['message'],
|
|
123
|
+
"owasp": vuln_info['owasp'],
|
|
124
|
+
"code": line.strip()[:100]
|
|
125
|
+
})
|
|
126
|
+
except Exception as e:
|
|
127
|
+
pass # Skip unreadable files
|
|
128
|
+
|
|
129
|
+
return findings
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def scan_directory(path: str) -> Dict[str, Any]:
|
|
133
|
+
"""Scan directory for vulnerabilities."""
|
|
134
|
+
root = Path(path)
|
|
135
|
+
all_findings = []
|
|
136
|
+
files_scanned = 0
|
|
137
|
+
|
|
138
|
+
for file_path in root.rglob('*'):
|
|
139
|
+
if file_path.is_file() and should_scan_file(file_path):
|
|
140
|
+
files_scanned += 1
|
|
141
|
+
findings = scan_file(file_path)
|
|
142
|
+
all_findings.extend(findings)
|
|
143
|
+
|
|
144
|
+
# Group by severity
|
|
145
|
+
by_severity = {
|
|
146
|
+
"CRITICAL": [],
|
|
147
|
+
"HIGH": [],
|
|
148
|
+
"MEDIUM": [],
|
|
149
|
+
"LOW": []
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
for finding in all_findings:
|
|
153
|
+
severity = finding['severity']
|
|
154
|
+
if severity in by_severity:
|
|
155
|
+
by_severity[severity].append(finding)
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
"summary": {
|
|
159
|
+
"files_scanned": files_scanned,
|
|
160
|
+
"total_findings": len(all_findings),
|
|
161
|
+
"critical": len(by_severity["CRITICAL"]),
|
|
162
|
+
"high": len(by_severity["HIGH"]),
|
|
163
|
+
"medium": len(by_severity["MEDIUM"]),
|
|
164
|
+
"low": len(by_severity["LOW"])
|
|
165
|
+
},
|
|
166
|
+
"findings": by_severity,
|
|
167
|
+
"status": "FAIL" if by_severity["CRITICAL"] else "PASS"
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def main():
|
|
172
|
+
"""Main entry point."""
|
|
173
|
+
scan_path = sys.argv[1] if len(sys.argv) > 1 else '.'
|
|
174
|
+
|
|
175
|
+
if not os.path.exists(scan_path):
|
|
176
|
+
print(json.dumps({"error": f"Path not found: {scan_path}"}))
|
|
177
|
+
sys.exit(1)
|
|
178
|
+
|
|
179
|
+
results = scan_directory(scan_path)
|
|
180
|
+
print(json.dumps(results, indent=2))
|
|
181
|
+
|
|
182
|
+
# Exit with error if critical findings
|
|
183
|
+
if results['status'] == 'FAIL':
|
|
184
|
+
sys.exit(1)
|
|
185
|
+
|
|
186
|
+
sys.exit(0)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
if __name__ == '__main__':
|
|
190
|
+
main()
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# super-design
|
|
2
|
+
|
|
3
|
+
End-to-end design audit skill for Claude Code. Produces market analysis,
|
|
4
|
+
live-site UX/WCAG/CWV audit, and optional safe remediation — all with
|
|
5
|
+
evidence trails and per-finding severity.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
1. Copy this plugin to `~/.claude/plugins/super-design/` OR install via
|
|
10
|
+
`/plugin install super-design@<marketplace>`.
|
|
11
|
+
2. Verify MCP: `claude mcp list` — Playwright should connect.
|
|
12
|
+
3. Install browsers if missing: `npx playwright install chromium`.
|
|
13
|
+
4. Invoke: "run super-design" or "audit my site with super-design".
|
|
14
|
+
|
|
15
|
+
## Outputs
|
|
16
|
+
|
|
17
|
+
- `docs/super-design/overview.md` — executive report (committed)
|
|
18
|
+
- `docs/super-design/.audit-state.json` — re-audit state (committed)
|
|
19
|
+
- `docs/super-design/findings/F-NNNN.md` — per-finding records (committed)
|
|
20
|
+
- `docs/super-design/audit-history.md` — append-only log (committed)
|
|
21
|
+
- `docs/super-design/baseline-screenshots/` — visual regression baselines (Git LFS)
|
|
22
|
+
- `docs/super-design/.cache/` — ephemeral session artifacts (gitignored)
|
|
23
|
+
|
|
24
|
+
## Commands
|
|
25
|
+
|
|
26
|
+
`/super-design` — slash command. Flags: `--force-full`, `--refresh-research`,
|
|
27
|
+
`--only <cat>`, `--scope <url>`, `--fix`, `--dry-run`, `--ci`.
|
|
28
|
+
|
|
29
|
+
## Requirements
|
|
30
|
+
|
|
31
|
+
- Node ≥18, git ≥2.30, Python ≥3.9, Claude Code ≥2.1.
|
|
32
|
+
- `@playwright/mcp@0.0.70` (pinned).
|
|
33
|
+
- Optional: `gh` CLI, Git LFS.
|
|
34
|
+
|
|
35
|
+
## License
|
|
36
|
+
|
|
37
|
+
See LICENSE (Elastic License 2.0) and EULA.md.
|