xploitscan 1.0.3 → 1.0.7
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/dist/index.js +243 -15
- package/dist/index.js.map +1 -1
- package/dist/templates/cursor-security.mdc +112 -0
- package/dist/templates/cursorrules-legacy.txt +51 -0
- package/package.json +2 -1
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: XploitScan security rules for AI-generated code. Apply when writing or modifying any backend, API, auth, payment, or config code.
|
|
3
|
+
globs:
|
|
4
|
+
- "**/*.js"
|
|
5
|
+
- "**/*.jsx"
|
|
6
|
+
- "**/*.ts"
|
|
7
|
+
- "**/*.tsx"
|
|
8
|
+
- "**/*.py"
|
|
9
|
+
- "**/*.go"
|
|
10
|
+
- "**/*.rb"
|
|
11
|
+
- "**/*.php"
|
|
12
|
+
- "**/.env*"
|
|
13
|
+
- "**/Dockerfile"
|
|
14
|
+
- "**/docker-compose*.yml"
|
|
15
|
+
alwaysApply: true
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# XploitScan Security Rules
|
|
19
|
+
|
|
20
|
+
These rules cover the most common security mistakes XploitScan finds in AI-generated code (Cursor, Bolt, Lovable, Replit). Follow them when generating new code or modifying existing code. Source: https://xploitscan.com
|
|
21
|
+
|
|
22
|
+
## 1. Never trust webhook bodies without verifying signatures
|
|
23
|
+
|
|
24
|
+
When implementing a webhook handler for Stripe, Clerk, GitHub, Resend, SendGrid, or any other provider:
|
|
25
|
+
|
|
26
|
+
- ALWAYS read the raw request body, not parsed JSON. In Express that means `express.raw({ type: "application/json" })`, not `express.json()`.
|
|
27
|
+
- ALWAYS verify the provider's signature header before using any body fields.
|
|
28
|
+
- For Stripe specifically: use `stripe.webhooks.constructEvent(rawBody, signature, secret)`. Do NOT just `JSON.parse(req.body)` and trust `event.type`. An attacker can send any payload they want.
|
|
29
|
+
- Throw / return 400 if verification fails. Never fall through to processing.
|
|
30
|
+
|
|
31
|
+
## 2. Never hardcode secrets in source
|
|
32
|
+
|
|
33
|
+
- Never write API keys, tokens, passwords, JWT secrets, database URLs, or webhook secrets as string literals in any committed file.
|
|
34
|
+
- Never put real secret values in `.env.example` or any committed `.env*` file. Use placeholder values like `your_api_key_here`.
|
|
35
|
+
- All secrets must be read from `process.env.X` (Node) / `os.environ["X"]` (Python) / equivalent at runtime.
|
|
36
|
+
- Service-account keys, Firebase config with API keys, and OAuth client secrets count as secrets.
|
|
37
|
+
|
|
38
|
+
## 3. Every API route needs an explicit auth check
|
|
39
|
+
|
|
40
|
+
When generating any HTTP route handler that touches user data, billing, admin, or write operations:
|
|
41
|
+
|
|
42
|
+
- Verify the caller's identity at the top of the handler (Clerk `auth()`, Supabase `getUser()`, NextAuth `getServerSession()`, etc).
|
|
43
|
+
- Check permissions / role / ownership BEFORE the database query, not after.
|
|
44
|
+
- Routes named `/admin/*`, `/api/internal/*`, `/api/users/[id]/...`, or anything dealing with billing must reject unauthenticated requests with 401.
|
|
45
|
+
- For object access (getting user 123's data), verify `caller.id === resource.userId` — IDOR is the most common vibe-coded vulnerability.
|
|
46
|
+
|
|
47
|
+
## 4. Never build SQL with string concatenation or template literals
|
|
48
|
+
|
|
49
|
+
- ALWAYS use parameterized queries / prepared statements / an ORM with bind parameters.
|
|
50
|
+
- Forbidden: `` `SELECT * FROM users WHERE id = ${req.params.id}` ``
|
|
51
|
+
- Required: `db.query('SELECT * FROM users WHERE id = $1', [req.params.id])` or equivalent ORM method.
|
|
52
|
+
- Same rule applies to LIKE patterns, ORDER BY clauses, and column names — escape or whitelist, never interpolate.
|
|
53
|
+
|
|
54
|
+
## 5. CORS must be specific, never wildcard with credentials
|
|
55
|
+
|
|
56
|
+
- `Access-Control-Allow-Origin: *` combined with `Access-Control-Allow-Credentials: true` is rejected by browsers but signals you don't understand CORS.
|
|
57
|
+
- Set `origin` to the exact domain(s) your frontend runs on, or use a function that allowlists known domains.
|
|
58
|
+
- For Next.js API routes: never set `Access-Control-Allow-Origin: *` on routes that read cookies or session tokens.
|
|
59
|
+
|
|
60
|
+
## 6. User-controlled URLs must be validated before fetch / redirect
|
|
61
|
+
|
|
62
|
+
When implementing a "preview link" feature, "import from URL", "OAuth callback", or any handler that takes a URL parameter and either fetches it or redirects to it:
|
|
63
|
+
|
|
64
|
+
- Reject any URL whose hostname is in a private CIDR (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `127.0.0.0/8`, `169.254.169.254` AWS metadata).
|
|
65
|
+
- For redirect handlers, allowlist the destination domains. Never blindly redirect to a user-supplied URL.
|
|
66
|
+
- For server-side fetch handlers (SSRF protection), use a library like `ssrf-req-filter` or implement DNS-based validation.
|
|
67
|
+
|
|
68
|
+
## 7. Never put session tokens or PII in localStorage
|
|
69
|
+
|
|
70
|
+
- `localStorage.setItem('token', ...)` and `localStorage.setItem('access_token', ...)` are forbidden — XSS can read it.
|
|
71
|
+
- Use HttpOnly secure cookies for session tokens. The browser sends them automatically.
|
|
72
|
+
- The same rule applies to React Native `AsyncStorage` for tokens.
|
|
73
|
+
|
|
74
|
+
## 8. Never use eval, new Function, or child_process.exec with user input
|
|
75
|
+
|
|
76
|
+
- `eval(req.body.expr)` is RCE.
|
|
77
|
+
- `new Function(userInput)()` is RCE.
|
|
78
|
+
- `exec("convert " + req.body.filename)` is command injection — use `execFile("convert", [req.body.filename])` or escape with `shell-quote`.
|
|
79
|
+
|
|
80
|
+
## 9. Set the standard security headers on every response
|
|
81
|
+
|
|
82
|
+
When generating Express, Next.js, or Hono setup code, include security headers:
|
|
83
|
+
|
|
84
|
+
- `Content-Security-Policy: default-src 'self'` (and progressively relax for needed sources)
|
|
85
|
+
- `Strict-Transport-Security: max-age=63072000; includeSubDomains; preload`
|
|
86
|
+
- `X-Content-Type-Options: nosniff`
|
|
87
|
+
- `X-Frame-Options: DENY`
|
|
88
|
+
- `Referrer-Policy: strict-origin-when-cross-origin`
|
|
89
|
+
|
|
90
|
+
For Next.js, set these in `next.config.js` `headers()`. For Express, use `helmet()`.
|
|
91
|
+
|
|
92
|
+
## 10. dangerouslySetInnerHTML and v-html require sanitization
|
|
93
|
+
|
|
94
|
+
- Never pass user content to `dangerouslySetInnerHTML` (React) or `v-html` (Vue) without sanitizing.
|
|
95
|
+
- Use `DOMPurify.sanitize(userContent)` first.
|
|
96
|
+
- Better: render markdown via `react-markdown` with default sanitization instead of converting to HTML.
|
|
97
|
+
|
|
98
|
+
## 11. JWT verification must check signature, not just decode
|
|
99
|
+
|
|
100
|
+
- `jwt.decode()` does NOT verify the signature — it just parses the payload. Never trust it.
|
|
101
|
+
- Use `jwt.verify(token, secret, { algorithms: ['HS256'] })` and always pin the algorithm. Without `algorithms`, `alg: none` attacks become possible.
|
|
102
|
+
|
|
103
|
+
## 12. Don't log secrets, tokens, or PII
|
|
104
|
+
|
|
105
|
+
- `console.log({ user, token })` may leak credentials into Vercel/CloudWatch logs.
|
|
106
|
+
- Strip `password`, `token`, `secret`, `apiKey`, `creditCard`, `ssn`, `authorization` headers, etc., before logging.
|
|
107
|
+
- Same for error messages returned to the client — don't echo back the request body.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
If you're unsure whether something is safe, scan with XploitScan: `npx xploitscan scan .`
|
|
112
|
+
Full ruleset and explanations: https://xploitscan.com/docs
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# XploitScan security rules (legacy .cursorrules format)
|
|
2
|
+
# Modern format: .cursor/rules/xploitscan-security.mdc — see https://xploitscan.com/cursor
|
|
3
|
+
|
|
4
|
+
When generating or modifying any backend, API, auth, payment, config, or DB code, follow these security rules. Source: https://xploitscan.com
|
|
5
|
+
|
|
6
|
+
1. WEBHOOKS MUST BE SIGNATURE-VERIFIED
|
|
7
|
+
- Stripe: use stripe.webhooks.constructEvent with the raw body and signature header. Use express.raw, not express.json. Never trust event.type from req.body without verification.
|
|
8
|
+
- Clerk / GitHub / Resend / SendGrid webhooks: same rule, use the provider's verify function.
|
|
9
|
+
- Throw / return 400 on verification failure. Never fall through.
|
|
10
|
+
|
|
11
|
+
2. NO HARDCODED SECRETS
|
|
12
|
+
- No string literal API keys, tokens, passwords, JWT secrets, DB URLs, or webhook secrets in source.
|
|
13
|
+
- .env.example must contain placeholder values like "your_api_key_here", never real secrets.
|
|
14
|
+
- Read all secrets from process.env at runtime.
|
|
15
|
+
|
|
16
|
+
3. EVERY API ROUTE NEEDS EXPLICIT AUTH
|
|
17
|
+
- Verify identity at the top of the handler before any DB query.
|
|
18
|
+
- Check role / permissions / resource ownership before reading or writing.
|
|
19
|
+
- For object access, verify caller.id === resource.userId (IDOR is the top vibe-coded vulnerability).
|
|
20
|
+
|
|
21
|
+
4. NO STRING-CONCATENATED SQL
|
|
22
|
+
- Always use parameterized queries / ORM bind parameters.
|
|
23
|
+
- Forbidden: `SELECT * FROM users WHERE id = ${id}`
|
|
24
|
+
- Required: db.query('SELECT * FROM users WHERE id = $1', [id])
|
|
25
|
+
|
|
26
|
+
5. CORS WILDCARDS WITH CREDENTIALS ARE FORBIDDEN
|
|
27
|
+
- Never combine Access-Control-Allow-Origin: * with Allow-Credentials: true.
|
|
28
|
+
- Allowlist exact origins.
|
|
29
|
+
|
|
30
|
+
6. SSRF: VALIDATE USER-CONTROLLED URLS BEFORE FETCH OR REDIRECT
|
|
31
|
+
- Reject private CIDRs (10/8, 172.16/12, 192.168/16, 127/8, 169.254.169.254).
|
|
32
|
+
- Allowlist destinations for redirect handlers.
|
|
33
|
+
|
|
34
|
+
7. NEVER PUT SESSION TOKENS IN LOCALSTORAGE
|
|
35
|
+
- Use HttpOnly secure cookies. Same for React Native AsyncStorage.
|
|
36
|
+
|
|
37
|
+
8. NEVER eval / new Function / exec WITH USER INPUT
|
|
38
|
+
- Use execFile with arg arrays, not exec with concatenated strings.
|
|
39
|
+
|
|
40
|
+
9. SET SECURITY HEADERS BY DEFAULT
|
|
41
|
+
- CSP, HSTS, X-Content-Type-Options, X-Frame-Options, Referrer-Policy. Use helmet() for Express, headers() in next.config.js.
|
|
42
|
+
|
|
43
|
+
10. dangerouslySetInnerHTML / v-html REQUIRE DOMPurify
|
|
44
|
+
|
|
45
|
+
11. JWT.VERIFY, NEVER JWT.DECODE
|
|
46
|
+
- Always pin algorithms: jwt.verify(token, secret, { algorithms: ['HS256'] })
|
|
47
|
+
|
|
48
|
+
12. DON'T LOG SECRETS
|
|
49
|
+
- Strip password, token, secret, apiKey, authorization, ssn, creditCard before any log call.
|
|
50
|
+
|
|
51
|
+
If unsure, scan with: npx xploitscan scan .
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xploitscan",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "AI security scanner for vibe-coded apps. Find vulnerabilities before attackers do.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"dist/chunk-*.js.map",
|
|
14
14
|
"dist/api-*.js",
|
|
15
15
|
"dist/api-*.js.map",
|
|
16
|
+
"dist/templates/",
|
|
16
17
|
"README.md",
|
|
17
18
|
"LICENSE"
|
|
18
19
|
],
|