@intentsolutionsio/penetration-tester 2.0.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.
@@ -0,0 +1,452 @@
1
+ # Remediation Playbook
2
+
3
+ Copy-paste fix templates for common security vulnerabilities. Each entry includes
4
+ the vulnerable pattern, the fix, and a verification command.
5
+
6
+ ---
7
+
8
+ ## SQL Injection
9
+
10
+ **Vulnerable pattern (Python):**
11
+ ```python
12
+ query = "SELECT * FROM users WHERE username = '" + username + "'"
13
+ cursor.execute(query)
14
+ ```
15
+
16
+ **Fix (Python - parameterized query):**
17
+ ```python
18
+ cursor.execute("SELECT * FROM users WHERE username = %s", (username,))
19
+ ```
20
+
21
+ **Fix (Python - SQLAlchemy):**
22
+ ```python
23
+ from sqlalchemy import text
24
+ result = session.execute(text("SELECT * FROM users WHERE username = :name"),
25
+ {"name": username})
26
+ ```
27
+
28
+ **Vulnerable pattern (Node.js):**
29
+ ```javascript
30
+ const query = `SELECT * FROM users WHERE username = '${username}'`;
31
+ db.query(query);
32
+ ```
33
+
34
+ **Fix (Node.js - parameterized):**
35
+ ```javascript
36
+ db.query("SELECT * FROM users WHERE username = $1", [username]);
37
+ ```
38
+
39
+ **Fix (Node.js - Knex.js):**
40
+ ```javascript
41
+ knex("users").where("username", username).first();
42
+ ```
43
+
44
+ **Verification:**
45
+ ```bash
46
+ python3 code_security_scanner.py /path/to/code --tools regex
47
+ # Check that no SQL string concatenation findings remain
48
+ ```
49
+
50
+ ---
51
+
52
+ ## Cross-Site Scripting (XSS)
53
+
54
+ **Vulnerable pattern (Python/Jinja2):**
55
+ ```python
56
+ # Marking user input as safe bypasses auto-escaping
57
+ return Markup(f"<p>Hello {user_input}</p>")
58
+ ```
59
+
60
+ **Fix (Python/Jinja2):**
61
+ ```python
62
+ # Let the template engine auto-escape (default in Jinja2)
63
+ return render_template("greeting.html", name=user_input)
64
+ ```
65
+ ```html
66
+ <!-- greeting.html - auto-escaped by default -->
67
+ <p>Hello {{ name }}</p>
68
+ ```
69
+
70
+ **Vulnerable pattern (Node.js/Express):**
71
+ ```javascript
72
+ res.send(`<p>Search results for: ${req.query.q}</p>`);
73
+ ```
74
+
75
+ **Fix (Node.js - use template engine with auto-escaping):**
76
+ ```javascript
77
+ // With EJS (auto-escapes by default with <%= %>)
78
+ res.render("search", { query: req.query.q });
79
+ ```
80
+ ```html
81
+ <!-- search.ejs -->
82
+ <p>Search results for: <%= query %></p>
83
+ ```
84
+
85
+ **Fix (React - auto-escapes by default):**
86
+ ```jsx
87
+ // React auto-escapes variables in JSX
88
+ return <p>Search results for: {query}</p>;
89
+ // NEVER use dangerouslySetInnerHTML with user input
90
+ ```
91
+
92
+ **Additional protection - CSP header:**
93
+ ```
94
+ Content-Security-Policy: default-src 'self'; script-src 'self'
95
+ ```
96
+
97
+ **Verification:**
98
+ ```bash
99
+ python3 security_scanner.py https://your-site.com --checks headers
100
+ # Verify CSP header is present and configured
101
+ ```
102
+
103
+ ---
104
+
105
+ ## Hardcoded Secrets
106
+
107
+ **Vulnerable pattern:**
108
+ ```python
109
+ API_KEY = "sk-abc123def456ghi789"
110
+ DATABASE_URL = "postgresql://admin:password123@db.example.com/prod"
111
+ AWS_SECRET_KEY = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
112
+ ```
113
+
114
+ **Fix (Python - environment variables):**
115
+ ```python
116
+ import os
117
+
118
+ API_KEY = os.environ["API_KEY"]
119
+ DATABASE_URL = os.environ["DATABASE_URL"]
120
+ AWS_SECRET_KEY = os.environ["AWS_SECRET_ACCESS_KEY"]
121
+ ```
122
+
123
+ **Fix (Python - dotenv for development):**
124
+ ```python
125
+ from dotenv import load_dotenv
126
+ import os
127
+
128
+ load_dotenv() # loads from .env file (NEVER commit .env)
129
+ API_KEY = os.environ["API_KEY"]
130
+ ```
131
+
132
+ **Fix (Node.js):**
133
+ ```javascript
134
+ // npm install dotenv
135
+ require("dotenv").config();
136
+
137
+ const apiKey = process.env.API_KEY;
138
+ const dbUrl = process.env.DATABASE_URL;
139
+ ```
140
+
141
+ **Prevention - .gitignore:**
142
+ ```gitignore
143
+ .env
144
+ .env.local
145
+ .env.production
146
+ *.pem
147
+ *.key
148
+ credentials.json
149
+ ```
150
+
151
+ **Verification:**
152
+ ```bash
153
+ python3 code_security_scanner.py /path/to/code --tools regex
154
+ # Check for hardcoded-secret findings
155
+ # Also verify .env is in .gitignore:
156
+ grep -q '.env' .gitignore && echo "OK" || echo "MISSING"
157
+ ```
158
+
159
+ ---
160
+
161
+ ## Missing Security Headers
162
+
163
+ **Vulnerable:** No security headers configured (defaults to none).
164
+
165
+ **Fix (Express.js - Helmet):**
166
+ ```javascript
167
+ const helmet = require("helmet");
168
+ app.use(helmet());
169
+ ```
170
+
171
+ **Fix (Django):**
172
+ ```python
173
+ # settings.py
174
+ MIDDLEWARE = [
175
+ "django.middleware.security.SecurityMiddleware",
176
+ # ... other middleware
177
+ ]
178
+
179
+ SECURE_HSTS_SECONDS = 31536000
180
+ SECURE_HSTS_INCLUDE_SUBDOMAINS = True
181
+ SECURE_CONTENT_TYPE_NOSNIFF = True
182
+ X_FRAME_OPTIONS = "DENY"
183
+ SECURE_REFERRER_POLICY = "strict-origin-when-cross-origin"
184
+ ```
185
+
186
+ **Fix (Flask):**
187
+ ```python
188
+ from flask_talisman import Talisman
189
+
190
+ Talisman(app, content_security_policy={
191
+ "default-src": "'self'",
192
+ "script-src": "'self'",
193
+ "frame-ancestors": "'none'",
194
+ })
195
+ ```
196
+
197
+ **Verification:**
198
+ ```bash
199
+ python3 security_scanner.py https://your-site.com --checks headers
200
+ # All headers should show as present
201
+ ```
202
+
203
+ ---
204
+
205
+ ## Weak TLS Configuration
206
+
207
+ **Vulnerable:** TLS 1.0/1.1 enabled, weak cipher suites, expired certificates.
208
+
209
+ **Fix (Nginx):**
210
+ ```nginx
211
+ ssl_protocols TLSv1.2 TLSv1.3;
212
+ ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
213
+ ssl_prefer_server_ciphers off;
214
+ ssl_session_timeout 1d;
215
+ ssl_session_cache shared:SSL:10m;
216
+ ssl_session_tickets off;
217
+ ```
218
+
219
+ **Fix (Apache):**
220
+ ```apache
221
+ SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
222
+ SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
223
+ SSLHonorCipherOrder off
224
+ ```
225
+
226
+ **Certificate renewal (Let's Encrypt):**
227
+ ```bash
228
+ # Install certbot
229
+ sudo certbot renew --dry-run
230
+
231
+ # Auto-renewal cron
232
+ 0 12 * * * /usr/bin/certbot renew --quiet
233
+ ```
234
+
235
+ **Verification:**
236
+ ```bash
237
+ python3 security_scanner.py https://your-site.com --checks ssl
238
+ # Check certificate expiry and protocol version
239
+ ```
240
+
241
+ ---
242
+
243
+ ## Vulnerable Dependencies
244
+
245
+ **Vulnerable:** Outdated packages with known CVEs.
246
+
247
+ **Fix (npm):**
248
+ ```bash
249
+ # View vulnerabilities
250
+ npm audit
251
+
252
+ # Auto-fix compatible updates
253
+ npm audit fix
254
+
255
+ # Force major version updates (review changes!)
256
+ npm audit fix --force
257
+
258
+ # Update specific package
259
+ npm install package-name@latest
260
+ ```
261
+
262
+ **Fix (Python/pip):**
263
+ ```bash
264
+ # Audit installed packages
265
+ pip-audit
266
+
267
+ # Update specific package
268
+ pip install --upgrade package-name
269
+
270
+ # Update all packages (use with caution)
271
+ pip list --outdated --format=json | python3 -c "
272
+ import json, sys
273
+ for pkg in json.load(sys.stdin):
274
+ print(pkg['name'])
275
+ " | xargs -n1 pip install --upgrade
276
+ ```
277
+
278
+ **Fix (Lock file hygiene):**
279
+ ```bash
280
+ # npm - regenerate lock file
281
+ rm package-lock.json && npm install
282
+
283
+ # pip - regenerate requirements
284
+ pip freeze > requirements.txt
285
+ ```
286
+
287
+ **Verification:**
288
+ ```bash
289
+ python3 dependency_auditor.py /path/to/project
290
+ # Should show no critical/high vulnerabilities
291
+ ```
292
+
293
+ ---
294
+
295
+ ## Command Injection
296
+
297
+ **Vulnerable pattern (Python):**
298
+ ```python
299
+ import os
300
+ os.system("ping " + user_host)
301
+
302
+ import subprocess
303
+ subprocess.run(f"grep {pattern} {filename}", shell=True)
304
+ ```
305
+
306
+ **Fix (Python):**
307
+ ```python
308
+ import subprocess
309
+ import shlex
310
+
311
+ # Use list arguments (no shell interpretation)
312
+ subprocess.run(["ping", "-c", "1", validated_host], shell=False, timeout=10)
313
+
314
+ # If shell is truly needed, use shlex.quote
315
+ subprocess.run(f"grep {shlex.quote(pattern)} {shlex.quote(filename)}",
316
+ shell=True, timeout=10)
317
+ ```
318
+
319
+ **Vulnerable pattern (Node.js):**
320
+ ```javascript
321
+ const { exec } = require("child_process");
322
+ exec(`ls ${userInput}`);
323
+ ```
324
+
325
+ **Fix (Node.js):**
326
+ ```javascript
327
+ const { execFile } = require("child_process");
328
+ // execFile does not invoke a shell
329
+ execFile("ls", [validatedPath], (error, stdout) => {
330
+ // ...
331
+ });
332
+ ```
333
+
334
+ **Verification:**
335
+ ```bash
336
+ python3 code_security_scanner.py /path/to/code --tools bandit,regex
337
+ # Check for command-injection category findings
338
+ ```
339
+
340
+ ---
341
+
342
+ ## Insecure Deserialization
343
+
344
+ **Vulnerable pattern (Python):**
345
+ ```python
346
+ import pickle
347
+ data = pickle.loads(request.data) # Arbitrary code execution
348
+
349
+ import yaml
350
+ config = yaml.load(user_input) # Arbitrary code execution
351
+ ```
352
+
353
+ **Fix (Python):**
354
+ ```python
355
+ # Use safe data formats
356
+ import json
357
+ data = json.loads(request.data)
358
+
359
+ # Use SafeLoader for YAML
360
+ import yaml
361
+ config = yaml.safe_load(user_input)
362
+
363
+ # If pickle is required (trusted data only), use hmac verification
364
+ import hmac
365
+ import hashlib
366
+
367
+ def verify_and_load(data, signature, secret_key):
368
+ expected = hmac.new(secret_key, data, hashlib.sha256).hexdigest()
369
+ if not hmac.compare_digest(signature, expected):
370
+ raise ValueError("Invalid signature")
371
+ return pickle.loads(data) # Only after verification
372
+ ```
373
+
374
+ **Verification:**
375
+ ```bash
376
+ python3 code_security_scanner.py /path/to/code --tools bandit,regex
377
+ # Check for insecure-deserialization category findings
378
+ ```
379
+
380
+ ---
381
+
382
+ ## CORS Misconfiguration
383
+
384
+ **Vulnerable:**
385
+ ```javascript
386
+ app.use(cors({ origin: "*", credentials: true }));
387
+ // Or reflecting any origin:
388
+ res.setHeader("Access-Control-Allow-Origin", req.headers.origin);
389
+ ```
390
+
391
+ **Fix (Express.js):**
392
+ ```javascript
393
+ const allowedOrigins = ["https://app.example.com", "https://admin.example.com"];
394
+
395
+ app.use(cors({
396
+ origin: (origin, callback) => {
397
+ if (!origin || allowedOrigins.includes(origin)) {
398
+ callback(null, true);
399
+ } else {
400
+ callback(new Error("Not allowed by CORS"));
401
+ }
402
+ },
403
+ credentials: true,
404
+ methods: ["GET", "POST", "PUT", "DELETE"],
405
+ allowedHeaders: ["Content-Type", "Authorization"],
406
+ }));
407
+ ```
408
+
409
+ **Fix (Django):**
410
+ ```python
411
+ # pip install django-cors-headers
412
+ CORS_ALLOWED_ORIGINS = [
413
+ "https://app.example.com",
414
+ "https://admin.example.com",
415
+ ]
416
+ CORS_ALLOW_CREDENTIALS = True
417
+ ```
418
+
419
+ **Verification:**
420
+ ```bash
421
+ python3 security_scanner.py https://your-api.com --checks cors
422
+ # Should not show wildcard or reflected origin with credentials
423
+ ```
424
+
425
+ ---
426
+
427
+ ## Checklist: Post-Remediation
428
+
429
+ After applying fixes, run the full scan suite to verify:
430
+
431
+ ```bash
432
+ # 1. Check security headers
433
+ python3 security_scanner.py https://your-site.com --checks headers,ssl,cors
434
+
435
+ # 2. Check dependencies
436
+ python3 dependency_auditor.py /path/to/project --min-severity high
437
+
438
+ # 3. Check code
439
+ python3 code_security_scanner.py /path/to/code --severity high
440
+
441
+ # 4. Verify no regressions
442
+ # Run your application's test suite
443
+ npm test # or pytest, etc.
444
+ ```
445
+
446
+ ---
447
+
448
+ ## Further Reading
449
+
450
+ - [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/)
451
+ - [CWE/SANS Top 25](https://cwe.mitre.org/top25/)
452
+ - [Mozilla Web Security Guidelines](https://infosec.mozilla.org/guidelines/web_security)