guardvibe 0.4.0
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/LICENSE +21 -0
- package/README.md +205 -0
- package/build/cli.d.ts +3 -0
- package/build/cli.d.ts.map +1 -0
- package/build/cli.js +118 -0
- package/build/cli.js.map +1 -0
- package/build/data/framework-guides.d.ts +8 -0
- package/build/data/framework-guides.d.ts.map +1 -0
- package/build/data/framework-guides.js +500 -0
- package/build/data/framework-guides.js.map +1 -0
- package/build/data/owasp-rules.d.ts +12 -0
- package/build/data/owasp-rules.d.ts.map +1 -0
- package/build/data/owasp-rules.js +469 -0
- package/build/data/owasp-rules.js.map +1 -0
- package/build/data/rules/core.d.ts +3 -0
- package/build/data/rules/core.d.ts.map +1 -0
- package/build/data/rules/core.js +245 -0
- package/build/data/rules/core.js.map +1 -0
- package/build/data/rules/go.d.ts +3 -0
- package/build/data/rules/go.d.ts.map +1 -0
- package/build/data/rules/go.js +64 -0
- package/build/data/rules/go.js.map +1 -0
- package/build/data/rules/index.d.ts +3 -0
- package/build/data/rules/index.d.ts.map +1 -0
- package/build/data/rules/index.js +13 -0
- package/build/data/rules/index.js.map +1 -0
- package/build/data/rules/java.d.ts +3 -0
- package/build/data/rules/java.d.ts.map +1 -0
- package/build/data/rules/java.js +64 -0
- package/build/data/rules/java.js.map +1 -0
- package/build/data/rules/php.d.ts +3 -0
- package/build/data/rules/php.d.ts.map +1 -0
- package/build/data/rules/php.js +54 -0
- package/build/data/rules/php.js.map +1 -0
- package/build/data/rules/ruby.d.ts +3 -0
- package/build/data/rules/ruby.d.ts.map +1 -0
- package/build/data/rules/ruby.js +54 -0
- package/build/data/rules/ruby.js.map +1 -0
- package/build/data/rules/types.d.ts +11 -0
- package/build/data/rules/types.d.ts.map +1 -0
- package/build/data/rules/types.js +2 -0
- package/build/data/rules/types.js.map +1 -0
- package/build/data/secret-patterns.d.ts +9 -0
- package/build/data/secret-patterns.d.ts.map +1 -0
- package/build/data/secret-patterns.js +87 -0
- package/build/data/secret-patterns.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +117 -0
- package/build/index.js.map +1 -0
- package/build/tools/check-code.d.ts +9 -0
- package/build/tools/check-code.d.ts.map +1 -0
- package/build/tools/check-code.js +125 -0
- package/build/tools/check-code.js.map +1 -0
- package/build/tools/check-deps.d.ts +8 -0
- package/build/tools/check-deps.d.ts.map +1 -0
- package/build/tools/check-deps.js +57 -0
- package/build/tools/check-deps.js.map +1 -0
- package/build/tools/check-project.d.ts +7 -0
- package/build/tools/check-project.d.ts.map +1 -0
- package/build/tools/check-project.js +134 -0
- package/build/tools/check-project.js.map +1 -0
- package/build/tools/get-security-docs.d.ts +2 -0
- package/build/tools/get-security-docs.d.ts.map +1 -0
- package/build/tools/get-security-docs.js +61 -0
- package/build/tools/get-security-docs.js.map +1 -0
- package/build/tools/scan-dependencies.d.ts +2 -0
- package/build/tools/scan-dependencies.d.ts.map +1 -0
- package/build/tools/scan-dependencies.js +69 -0
- package/build/tools/scan-dependencies.js.map +1 -0
- package/build/tools/scan-directory.d.ts +2 -0
- package/build/tools/scan-directory.d.ts.map +1 -0
- package/build/tools/scan-directory.js +120 -0
- package/build/tools/scan-directory.js.map +1 -0
- package/build/tools/scan-secrets.d.ts +11 -0
- package/build/tools/scan-secrets.d.ts.map +1 -0
- package/build/tools/scan-secrets.js +150 -0
- package/build/tools/scan-secrets.js.map +1 -0
- package/build/utils/manifest-parser.d.ts +7 -0
- package/build/utils/manifest-parser.d.ts.map +1 -0
- package/build/utils/manifest-parser.js +102 -0
- package/build/utils/manifest-parser.js.map +1 -0
- package/build/utils/osv-client.d.ts +37 -0
- package/build/utils/osv-client.d.ts.map +1 -0
- package/build/utils/osv-client.js +78 -0
- package/build/utils/osv-client.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,500 @@
|
|
|
1
|
+
// NOTE: Code examples below intentionally show BOTH vulnerable and safe patterns
|
|
2
|
+
// for educational purposes. This is security documentation, not application code.
|
|
3
|
+
export const frameworkGuides = [
|
|
4
|
+
{
|
|
5
|
+
topic: "owasp",
|
|
6
|
+
keywords: ["owasp", "top 10", "top10", "web security", "common vulnerabilities"],
|
|
7
|
+
title: "OWASP Top 10:2025 - Quick Reference",
|
|
8
|
+
content: `# OWASP Top 10:2025
|
|
9
|
+
|
|
10
|
+
| # | Risk | Description |
|
|
11
|
+
|---|------|-------------|
|
|
12
|
+
| A01 | **Broken Access Control** | Users act outside intended permissions |
|
|
13
|
+
| A02 | **Injection** | SQL, NoSQL, OS, LDAP injection via untrusted data |
|
|
14
|
+
| A03 | **Software Supply Chain Failures** | Compromised dependencies, build pipelines |
|
|
15
|
+
| A04 | **Insecure Design** | Missing security controls in architecture |
|
|
16
|
+
| A05 | **Security Misconfiguration** | Default configs, open cloud storage, verbose errors |
|
|
17
|
+
| A06 | **Vulnerable and Outdated Components** | Components with known vulnerabilities |
|
|
18
|
+
| A07 | **Identification & Auth Failures** | Weak authentication, session management |
|
|
19
|
+
| A08 | **Software & Data Integrity Failures** | Insecure deserialization, unsigned updates |
|
|
20
|
+
| A09 | **Security Logging & Monitoring Failures** | Insufficient logging and alerting |
|
|
21
|
+
| A10 | **Server-Side Request Forgery (SSRF)** | Server fetches attacker-controlled URLs |
|
|
22
|
+
|
|
23
|
+
## Quick Wins for Vibe-Coders
|
|
24
|
+
|
|
25
|
+
1. **Always use parameterized queries** - never concatenate user input into SQL
|
|
26
|
+
2. **Use helmet** for Express apps - one line adds 11 security headers
|
|
27
|
+
3. **Hash passwords with bcrypt** - never MD5 or SHA-1
|
|
28
|
+
4. **Validate all input** - use zod, joi, or yup schemas
|
|
29
|
+
5. **Set cookie flags** - secure, httpOnly, sameSite: 'strict'
|
|
30
|
+
6. **Add rate limiting** - especially on auth endpoints
|
|
31
|
+
7. **Keep dependencies updated** - run npm audit weekly
|
|
32
|
+
8. **Never expose secrets** - use environment variables`,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
topic: "express",
|
|
36
|
+
keywords: ["express", "expressjs", "node", "nodejs", "api", "rest", "backend"],
|
|
37
|
+
title: "Express.js Security Best Practices",
|
|
38
|
+
content: `# Express.js Security Best Practices
|
|
39
|
+
|
|
40
|
+
## 1. Use Helmet (Security Headers)
|
|
41
|
+
\`\`\`
|
|
42
|
+
npm install helmet
|
|
43
|
+
\`\`\`
|
|
44
|
+
\`\`\`javascript
|
|
45
|
+
import helmet from 'helmet';
|
|
46
|
+
app.use(helmet());
|
|
47
|
+
// Sets: CSP, HSTS, X-Frame-Options, X-Content-Type-Options, and more.
|
|
48
|
+
\`\`\`
|
|
49
|
+
|
|
50
|
+
## 2. Rate Limiting
|
|
51
|
+
\`\`\`javascript
|
|
52
|
+
import rateLimit from 'express-rate-limit';
|
|
53
|
+
|
|
54
|
+
const limiter = rateLimit({
|
|
55
|
+
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
56
|
+
max: 100, // limit each IP to 100 requests per window
|
|
57
|
+
});
|
|
58
|
+
app.use('/api/', limiter);
|
|
59
|
+
|
|
60
|
+
// Stricter for auth endpoints
|
|
61
|
+
const authLimiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 5 });
|
|
62
|
+
app.use('/api/login', authLimiter);
|
|
63
|
+
\`\`\`
|
|
64
|
+
|
|
65
|
+
## 3. Input Validation with Zod
|
|
66
|
+
\`\`\`javascript
|
|
67
|
+
import { z } from 'zod';
|
|
68
|
+
|
|
69
|
+
const loginSchema = z.object({
|
|
70
|
+
email: z.string().email(),
|
|
71
|
+
password: z.string().min(8).max(128),
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
app.post('/api/login', (req, res) => {
|
|
75
|
+
const result = loginSchema.safeParse(req.body);
|
|
76
|
+
if (!result.success) return res.status(400).json({ error: result.error });
|
|
77
|
+
// proceed with validated data: result.data
|
|
78
|
+
});
|
|
79
|
+
\`\`\`
|
|
80
|
+
|
|
81
|
+
## 4. CORS Configuration
|
|
82
|
+
\`\`\`javascript
|
|
83
|
+
import cors from 'cors';
|
|
84
|
+
// GOOD: specific origins
|
|
85
|
+
app.use(cors({
|
|
86
|
+
origin: ['https://myapp.com'],
|
|
87
|
+
methods: ['GET', 'POST'],
|
|
88
|
+
credentials: true,
|
|
89
|
+
}));
|
|
90
|
+
// BAD: cors({ origin: '*' }) with authentication
|
|
91
|
+
\`\`\`
|
|
92
|
+
|
|
93
|
+
## 5. Secure Session/Cookie Config
|
|
94
|
+
\`\`\`javascript
|
|
95
|
+
app.use(session({
|
|
96
|
+
secret: process.env.SESSION_SECRET,
|
|
97
|
+
cookie: {
|
|
98
|
+
secure: true, // HTTPS only
|
|
99
|
+
httpOnly: true, // no JS access
|
|
100
|
+
sameSite: 'strict', // CSRF protection
|
|
101
|
+
maxAge: 3600000, // 1 hour
|
|
102
|
+
},
|
|
103
|
+
resave: false,
|
|
104
|
+
saveUninitialized: false,
|
|
105
|
+
}));
|
|
106
|
+
\`\`\`
|
|
107
|
+
|
|
108
|
+
## 6. Error Handling (Don't Leak Info)
|
|
109
|
+
\`\`\`javascript
|
|
110
|
+
// GOOD: generic error to user, detailed log internally
|
|
111
|
+
app.use((err, req, res, next) => {
|
|
112
|
+
console.error(err); // log internally
|
|
113
|
+
res.status(500).json({ error: 'Internal server error' });
|
|
114
|
+
});
|
|
115
|
+
\`\`\``,
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
topic: "nextjs",
|
|
119
|
+
keywords: ["next", "nextjs", "next.js", "react", "ssr", "server components", "app router"],
|
|
120
|
+
title: "Next.js Security Best Practices",
|
|
121
|
+
content: `# Next.js Security Best Practices
|
|
122
|
+
|
|
123
|
+
## 1. Server Components: Don't Leak Secrets
|
|
124
|
+
Server Components run on the server but be careful not to pass secrets to Client Components.
|
|
125
|
+
|
|
126
|
+
\`\`\`typescript
|
|
127
|
+
// SAFE: use server action, only data reaches client
|
|
128
|
+
'use server'
|
|
129
|
+
export async function fetchData() {
|
|
130
|
+
const res = await fetch(url, {
|
|
131
|
+
headers: { Authorization: process.env.SECRET_KEY }
|
|
132
|
+
});
|
|
133
|
+
return res.json();
|
|
134
|
+
}
|
|
135
|
+
\`\`\`
|
|
136
|
+
|
|
137
|
+
## 2. Server Actions: Validate Everything
|
|
138
|
+
\`\`\`typescript
|
|
139
|
+
'use server'
|
|
140
|
+
import { z } from 'zod';
|
|
141
|
+
|
|
142
|
+
const schema = z.object({
|
|
143
|
+
title: z.string().min(1).max(200),
|
|
144
|
+
content: z.string().max(10000),
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
export async function createPost(formData: FormData) {
|
|
148
|
+
const result = schema.safeParse({
|
|
149
|
+
title: formData.get('title'),
|
|
150
|
+
content: formData.get('content'),
|
|
151
|
+
});
|
|
152
|
+
if (!result.success) throw new Error('Invalid input');
|
|
153
|
+
// proceed with result.data
|
|
154
|
+
}
|
|
155
|
+
\`\`\`
|
|
156
|
+
|
|
157
|
+
## 3. CSRF Protection
|
|
158
|
+
Next.js Server Actions include built-in CSRF protection via Origin header checking.
|
|
159
|
+
For Route Handlers with cookie-based auth, add manual CSRF tokens.
|
|
160
|
+
|
|
161
|
+
## 4. Authentication with Proxy (Next.js 16+)
|
|
162
|
+
\`\`\`typescript
|
|
163
|
+
// proxy.ts (Next.js 16+)
|
|
164
|
+
import { auth } from './lib/auth';
|
|
165
|
+
|
|
166
|
+
export default async function proxy(request: Request) {
|
|
167
|
+
const session = await auth();
|
|
168
|
+
const { pathname } = new URL(request.url);
|
|
169
|
+
if (pathname.startsWith('/dashboard') && !session) {
|
|
170
|
+
return Response.redirect(new URL('/login', request.url));
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
\`\`\`
|
|
174
|
+
|
|
175
|
+
## 5. Security Headers
|
|
176
|
+
\`\`\`typescript
|
|
177
|
+
// next.config.ts
|
|
178
|
+
const securityHeaders = [
|
|
179
|
+
{ key: 'X-Frame-Options', value: 'DENY' },
|
|
180
|
+
{ key: 'X-Content-Type-Options', value: 'nosniff' },
|
|
181
|
+
{ key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
|
|
182
|
+
];
|
|
183
|
+
export default {
|
|
184
|
+
async headers() {
|
|
185
|
+
return [{ source: '/(.*)', headers: securityHeaders }];
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
\`\`\`
|
|
189
|
+
|
|
190
|
+
## 6. Environment Variables
|
|
191
|
+
- Prefix with NEXT_PUBLIC_ ONLY for truly public values
|
|
192
|
+
- Never put secrets in NEXT_PUBLIC_ variables
|
|
193
|
+
- Use .env.local for local secrets (gitignored by default)`,
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
topic: "sql-injection",
|
|
197
|
+
keywords: ["sql", "injection", "database", "query", "postgres", "mysql", "sqlite", "prisma", "drizzle"],
|
|
198
|
+
title: "SQL Injection Prevention Guide",
|
|
199
|
+
content: `# SQL Injection Prevention
|
|
200
|
+
|
|
201
|
+
SQL injection allows attackers to read, modify, or delete your entire database.
|
|
202
|
+
|
|
203
|
+
## The Fix: Parameterized Queries
|
|
204
|
+
|
|
205
|
+
### Node.js (pg)
|
|
206
|
+
\`\`\`javascript
|
|
207
|
+
// SAFE: parameterized query
|
|
208
|
+
const { rows } = await db.query(
|
|
209
|
+
'SELECT * FROM users WHERE id = $1',
|
|
210
|
+
[userId]
|
|
211
|
+
);
|
|
212
|
+
\`\`\`
|
|
213
|
+
|
|
214
|
+
### Prisma (Recommended ORM)
|
|
215
|
+
\`\`\`javascript
|
|
216
|
+
const user = await prisma.user.findUnique({
|
|
217
|
+
where: { id: userId },
|
|
218
|
+
});
|
|
219
|
+
\`\`\`
|
|
220
|
+
|
|
221
|
+
### Drizzle ORM
|
|
222
|
+
\`\`\`javascript
|
|
223
|
+
const user = await db.select()
|
|
224
|
+
.from(users)
|
|
225
|
+
.where(eq(users.id, userId));
|
|
226
|
+
\`\`\`
|
|
227
|
+
|
|
228
|
+
### Python (psycopg2)
|
|
229
|
+
\`\`\`python
|
|
230
|
+
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
|
|
231
|
+
\`\`\`
|
|
232
|
+
|
|
233
|
+
## Key Rules
|
|
234
|
+
1. **Never concatenate** user input into SQL strings
|
|
235
|
+
2. **Always use parameterized queries** or an ORM
|
|
236
|
+
3. **Apply least privilege** - DB user should only have needed permissions
|
|
237
|
+
4. **Validate input types** - if expecting a number, parse it first`,
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
topic: "xss",
|
|
241
|
+
keywords: ["xss", "cross-site scripting", "script injection", "sanitize", "html"],
|
|
242
|
+
title: "XSS (Cross-Site Scripting) Prevention",
|
|
243
|
+
content: `# XSS Prevention Guide
|
|
244
|
+
|
|
245
|
+
XSS allows attackers to inject malicious scripts into pages viewed by other users.
|
|
246
|
+
|
|
247
|
+
## Types
|
|
248
|
+
1. **Reflected** - malicious script in URL parameters
|
|
249
|
+
2. **Stored** - malicious script saved in database
|
|
250
|
+
3. **DOM-based** - script manipulates the DOM directly
|
|
251
|
+
|
|
252
|
+
## React / Next.js
|
|
253
|
+
React escapes content by default, which is the safest approach:
|
|
254
|
+
\`\`\`jsx
|
|
255
|
+
// SAFE - React auto-escapes
|
|
256
|
+
<div>{userContent}</div>
|
|
257
|
+
\`\`\`
|
|
258
|
+
|
|
259
|
+
If you MUST render HTML, sanitize it first:
|
|
260
|
+
\`\`\`javascript
|
|
261
|
+
import DOMPurify from 'dompurify';
|
|
262
|
+
const clean = DOMPurify.sanitize(dirtyHtml);
|
|
263
|
+
\`\`\`
|
|
264
|
+
|
|
265
|
+
## Vanilla JavaScript
|
|
266
|
+
\`\`\`javascript
|
|
267
|
+
// SAFE: use textContent for user-supplied data
|
|
268
|
+
element.textContent = userInput;
|
|
269
|
+
\`\`\`
|
|
270
|
+
|
|
271
|
+
## Content Security Policy
|
|
272
|
+
Add CSP headers to block inline scripts:
|
|
273
|
+
\`\`\`
|
|
274
|
+
Content-Security-Policy: default-src 'self'; script-src 'self';
|
|
275
|
+
\`\`\`
|
|
276
|
+
|
|
277
|
+
## Key Rules
|
|
278
|
+
1. Use **textContent** instead of innerHTML where possible
|
|
279
|
+
2. **Sanitize HTML** with DOMPurify if rendering is needed
|
|
280
|
+
3. **Set CSP headers** to prevent inline script execution
|
|
281
|
+
4. **Encode output** based on context (HTML, URL, JS, CSS)`,
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
topic: "authentication",
|
|
285
|
+
keywords: ["auth", "authentication", "login", "password", "jwt", "session", "bcrypt", "oauth", "clerk"],
|
|
286
|
+
title: "Authentication Security Guide",
|
|
287
|
+
content: `# Authentication Security Guide
|
|
288
|
+
|
|
289
|
+
## Password Hashing
|
|
290
|
+
\`\`\`javascript
|
|
291
|
+
import bcrypt from 'bcrypt';
|
|
292
|
+
|
|
293
|
+
// Hash password (registration) - use 12+ salt rounds
|
|
294
|
+
const hash = await bcrypt.hash(password, 12);
|
|
295
|
+
|
|
296
|
+
// Verify password (login)
|
|
297
|
+
const isValid = await bcrypt.compare(password, hash);
|
|
298
|
+
\`\`\`
|
|
299
|
+
|
|
300
|
+
**Never use:** MD5, SHA-1, SHA-256 for passwords. They're too fast to brute-force.
|
|
301
|
+
|
|
302
|
+
## JWT Best Practices
|
|
303
|
+
\`\`\`javascript
|
|
304
|
+
import jwt from 'jsonwebtoken';
|
|
305
|
+
|
|
306
|
+
// Always set expiration
|
|
307
|
+
const token = jwt.sign(
|
|
308
|
+
{ userId: user.id, role: user.role },
|
|
309
|
+
process.env.JWT_SECRET,
|
|
310
|
+
{ expiresIn: '15m' }
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
const payload = jwt.verify(token, process.env.JWT_SECRET);
|
|
314
|
+
\`\`\`
|
|
315
|
+
|
|
316
|
+
**Rules:**
|
|
317
|
+
- Always set expiresIn
|
|
318
|
+
- Use strong secrets (256+ bits)
|
|
319
|
+
- Store refresh tokens in httpOnly cookies
|
|
320
|
+
- Never store JWTs in localStorage (XSS risk)
|
|
321
|
+
|
|
322
|
+
## OAuth / Third-Party Auth (Recommended)
|
|
323
|
+
For most apps, use a managed auth provider:
|
|
324
|
+
- **Clerk** - best for Next.js/Vercel
|
|
325
|
+
- **Auth0** - enterprise-grade
|
|
326
|
+
- **Supabase Auth** - if using Supabase
|
|
327
|
+
|
|
328
|
+
This eliminates password storage, MFA implementation, and session management.
|
|
329
|
+
|
|
330
|
+
## Session Security
|
|
331
|
+
\`\`\`javascript
|
|
332
|
+
// Always set all security flags on session cookies
|
|
333
|
+
{
|
|
334
|
+
secure: true, // HTTPS only
|
|
335
|
+
httpOnly: true, // no JavaScript access
|
|
336
|
+
sameSite: 'strict', // CSRF protection
|
|
337
|
+
maxAge: 3600000, // 1 hour
|
|
338
|
+
}
|
|
339
|
+
\`\`\``,
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
topic: "fastapi",
|
|
343
|
+
keywords: ["fastapi", "python", "api", "pydantic", "starlette"],
|
|
344
|
+
title: "FastAPI Security Best Practices",
|
|
345
|
+
content: `# FastAPI Security Best Practices
|
|
346
|
+
|
|
347
|
+
## 1. Input Validation with Pydantic
|
|
348
|
+
\`\`\`python
|
|
349
|
+
from pydantic import BaseModel, EmailStr, Field
|
|
350
|
+
|
|
351
|
+
class UserCreate(BaseModel):
|
|
352
|
+
email: EmailStr
|
|
353
|
+
password: str = Field(min_length=8, max_length=128)
|
|
354
|
+
name: str = Field(min_length=1, max_length=100)
|
|
355
|
+
|
|
356
|
+
@app.post("/users")
|
|
357
|
+
async def create_user(user: UserCreate):
|
|
358
|
+
# user is already validated by Pydantic
|
|
359
|
+
pass
|
|
360
|
+
\`\`\`
|
|
361
|
+
|
|
362
|
+
## 2. CORS Configuration
|
|
363
|
+
\`\`\`python
|
|
364
|
+
from fastapi.middleware.cors import CORSMiddleware
|
|
365
|
+
|
|
366
|
+
app.add_middleware(
|
|
367
|
+
CORSMiddleware,
|
|
368
|
+
allow_origins=["https://myapp.com"], # never use "*"
|
|
369
|
+
allow_credentials=True,
|
|
370
|
+
allow_methods=["GET", "POST"],
|
|
371
|
+
allow_headers=["Authorization"],
|
|
372
|
+
)
|
|
373
|
+
\`\`\`
|
|
374
|
+
|
|
375
|
+
## 3. Rate Limiting
|
|
376
|
+
\`\`\`python
|
|
377
|
+
from slowapi import Limiter
|
|
378
|
+
from slowapi.util import get_remote_address
|
|
379
|
+
|
|
380
|
+
limiter = Limiter(key_func=get_remote_address)
|
|
381
|
+
|
|
382
|
+
@app.post("/login")
|
|
383
|
+
@limiter.limit("5/minute")
|
|
384
|
+
async def login(request: Request):
|
|
385
|
+
pass
|
|
386
|
+
\`\`\`
|
|
387
|
+
|
|
388
|
+
## 4. SQL Injection Prevention
|
|
389
|
+
\`\`\`python
|
|
390
|
+
# Use SQLAlchemy ORM - never raw SQL with f-strings
|
|
391
|
+
from sqlalchemy.orm import Session
|
|
392
|
+
|
|
393
|
+
def get_user(db: Session, user_id: int):
|
|
394
|
+
return db.query(User).filter(User.id == user_id).first()
|
|
395
|
+
\`\`\`
|
|
396
|
+
|
|
397
|
+
## 5. Environment Variables
|
|
398
|
+
\`\`\`python
|
|
399
|
+
from pydantic_settings import BaseSettings
|
|
400
|
+
|
|
401
|
+
class Settings(BaseSettings):
|
|
402
|
+
secret_key: str
|
|
403
|
+
database_url: str
|
|
404
|
+
class Config:
|
|
405
|
+
env_file = ".env"
|
|
406
|
+
\`\`\``,
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
topic: "react",
|
|
410
|
+
keywords: ["react", "reactjs", "component", "hook", "jsx", "tsx", "frontend", "client"],
|
|
411
|
+
title: "React Security Best Practices",
|
|
412
|
+
content: `# React Security Best Practices
|
|
413
|
+
|
|
414
|
+
## 1. React Auto-Escapes by Default (Use This!)
|
|
415
|
+
\`\`\`jsx
|
|
416
|
+
// SAFE - React auto-escapes content
|
|
417
|
+
<div>{userContent}</div>
|
|
418
|
+
\`\`\`
|
|
419
|
+
|
|
420
|
+
If HTML rendering is needed, always sanitize:
|
|
421
|
+
\`\`\`javascript
|
|
422
|
+
import DOMPurify from 'dompurify';
|
|
423
|
+
const cleanHtml = DOMPurify.sanitize(untrustedContent);
|
|
424
|
+
\`\`\`
|
|
425
|
+
|
|
426
|
+
## 2. Validate URL Parameters
|
|
427
|
+
\`\`\`jsx
|
|
428
|
+
// SAFE: validate before using
|
|
429
|
+
const redirect = searchParams.get('redirect');
|
|
430
|
+
const safeUrl = redirect?.startsWith('/') ? redirect : '/';
|
|
431
|
+
<a href={safeUrl}>Click</a>
|
|
432
|
+
\`\`\`
|
|
433
|
+
|
|
434
|
+
## 3. Secure API Calls
|
|
435
|
+
\`\`\`javascript
|
|
436
|
+
const res = await fetch('/api/data', {
|
|
437
|
+
method: 'POST',
|
|
438
|
+
headers: {
|
|
439
|
+
'Content-Type': 'application/json',
|
|
440
|
+
'X-CSRF-Token': csrfToken,
|
|
441
|
+
},
|
|
442
|
+
credentials: 'same-origin',
|
|
443
|
+
body: JSON.stringify(data),
|
|
444
|
+
});
|
|
445
|
+
\`\`\`
|
|
446
|
+
|
|
447
|
+
## 4. Secure State Management
|
|
448
|
+
- Never store sensitive data (tokens, passwords) in React state
|
|
449
|
+
- Use httpOnly cookies for auth tokens
|
|
450
|
+
- Clear sensitive data on logout
|
|
451
|
+
|
|
452
|
+
## 5. Dependency Security
|
|
453
|
+
\`\`\`
|
|
454
|
+
npm audit # check for known vulnerabilities
|
|
455
|
+
npm audit fix # auto-fix where possible
|
|
456
|
+
\`\`\``,
|
|
457
|
+
},
|
|
458
|
+
{
|
|
459
|
+
topic: "env",
|
|
460
|
+
keywords: ["env", "environment", "variables", "secrets", "dotenv", ".env", "api key", "credentials"],
|
|
461
|
+
title: "Environment Variables & Secrets Management",
|
|
462
|
+
content: `# Environment Variables & Secrets Management
|
|
463
|
+
|
|
464
|
+
## Golden Rules
|
|
465
|
+
1. **Never commit .env files** to git
|
|
466
|
+
2. **Never prefix secrets** with NEXT_PUBLIC_ or VITE_
|
|
467
|
+
3. **Use different secrets** per environment (dev/staging/prod)
|
|
468
|
+
4. **Rotate secrets regularly**
|
|
469
|
+
|
|
470
|
+
## .gitignore (Must Have)
|
|
471
|
+
\`\`\`
|
|
472
|
+
.env
|
|
473
|
+
.env.local
|
|
474
|
+
.env.*.local
|
|
475
|
+
\`\`\`
|
|
476
|
+
|
|
477
|
+
## Access Patterns
|
|
478
|
+
\`\`\`javascript
|
|
479
|
+
// Validate at startup - fail fast if missing
|
|
480
|
+
const secret = process.env.DATABASE_URL;
|
|
481
|
+
if (!secret) {
|
|
482
|
+
throw new Error('DATABASE_URL is required');
|
|
483
|
+
}
|
|
484
|
+
\`\`\`
|
|
485
|
+
|
|
486
|
+
## Vercel / Production
|
|
487
|
+
\`\`\`
|
|
488
|
+
vercel env pull .env.local # Pull env vars from Vercel
|
|
489
|
+
vercel env add SECRET_NAME # Add a secret
|
|
490
|
+
\`\`\`
|
|
491
|
+
|
|
492
|
+
## For Vibe-Coders
|
|
493
|
+
When your AI generates code with hardcoded secrets:
|
|
494
|
+
1. **Stop and move them to .env**
|
|
495
|
+
2. Replace with process.env.VARIABLE_NAME
|
|
496
|
+
3. Add .env to .gitignore
|
|
497
|
+
4. Tell your AI: "Use environment variables for secrets"`,
|
|
498
|
+
},
|
|
499
|
+
];
|
|
500
|
+
//# sourceMappingURL=framework-guides.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework-guides.js","sourceRoot":"","sources":["../../src/data/framework-guides.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface SecurityRule {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
severity: "critical" | "high" | "medium" | "low" | "info";
|
|
5
|
+
owasp: string;
|
|
6
|
+
description: string;
|
|
7
|
+
pattern: RegExp;
|
|
8
|
+
languages: string[];
|
|
9
|
+
fix: string;
|
|
10
|
+
}
|
|
11
|
+
export declare const owaspRules: SecurityRule[];
|
|
12
|
+
//# sourceMappingURL=owasp-rules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"owasp-rules.d.ts","sourceRoot":"","sources":["../../src/data/owasp-rules.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;CACb;AAID,eAAO,MAAM,UAAU,EAAE,YAAY,EA6gBpC,CAAC"}
|