--- name: security-testing description: Identify security vulnerabilities through SAST, DAST, penetration testing, and dependency scanning. Use for security test, vulnerability scanning, OWASP, SQL injection, XSS, CSRF, and penetration testing. --- # Security Testing ## Overview Security testing identifies vulnerabilities, weaknesses, and threats in applications to ensure data protection, prevent unauthorized access, and maintain system integrity. It combines automated scanning (SAST, DAST) with manual penetration testing and code review. ## When to Use - Testing for OWASP Top 10 vulnerabilities - Scanning dependencies for known vulnerabilities - Testing authentication and authorization - Validating input sanitization - Testing API security - Checking for sensitive data exposure - Validating security headers - Testing session management ## Security Testing Types - **SAST**: Static Application Security Testing (code analysis) - **DAST**: Dynamic Application Security Testing (runtime) - **IAST**: Interactive Application Security Testing - **SCA**: Software Composition Analysis (dependencies) - **Penetration Testing**: Manual security testing - **Fuzz Testing**: Invalid/random input testing ## Instructions ### 1. **OWASP ZAP (DAST)** ```python # security_scan.py from zapv2 import ZAPv2 import time class SecurityScanner: def __init__(self, target_url, api_key=None): self.zap = ZAPv2(apikey=api_key, proxies={ 'http': 'http://localhost:8080', 'https': 'http://localhost:8080' }) self.target = target_url def scan(self): """Run full security scan.""" print(f"Scanning {self.target}...") # Spider the application print("Spidering...") scan_id = self.zap.spider.scan(self.target) while int(self.zap.spider.status(scan_id)) < 100: time.sleep(2) print(f"Spider progress: {self.zap.spider.status(scan_id)}%") # Active scan print("Running active scan...") scan_id = self.zap.ascan.scan(self.target) while int(self.zap.ascan.status(scan_id)) < 100: time.sleep(5) print(f"Scan progress: {self.zap.ascan.status(scan_id)}%") return self.get_results() def get_results(self): """Get scan results.""" alerts = self.zap.core.alerts(baseurl=self.target) # Group by risk level results = { 'high': [], 'medium': [], 'low': [], 'informational': [] } for alert in alerts: risk = alert['risk'].lower() results[risk].append({ 'name': alert['alert'], 'description': alert['description'], 'solution': alert['solution'], 'url': alert['url'], 'param': alert.get('param', ''), 'evidence': alert.get('evidence', '') }) return results def report(self, results): """Generate security report.""" print("\n" + "="*60) print("SECURITY SCAN RESULTS") print("="*60) for risk_level in ['high', 'medium', 'low', 'informational']: issues = results[risk_level] if issues: print(f"\n{risk_level.upper()} Risk Issues: {len(issues)}") for issue in issues[:5]: # Show first 5 print(f" - {issue['name']}") print(f" URL: {issue['url']}") if issue['param']: print(f" Parameter: {issue['param']}") # Fail if high risk found if results['high']: raise Exception(f"Found {len(results['high'])} HIGH risk vulnerabilities!") # Usage scanner = SecurityScanner('http://localhost:3000') results = scanner.scan() scanner.report(results) ``` ### 2. **SQL Injection Testing** ```typescript // tests/security/sql-injection.test.ts import { test, expect } from '@playwright/test'; import request from 'supertest'; import { app } from '../../src/app'; test.describe('SQL Injection Protection', () => { const sqlInjectionPayloads = [ "' OR '1'='1", "'; DROP TABLE users; --", "' UNION SELECT * FROM users --", "admin'--", "' OR 1=1--", "1' AND '1'='1", ]; test('login should prevent SQL injection', async () => { for (const payload of sqlInjectionPayloads) { const response = await request(app) .post('/api/auth/login') .send({ email: payload, password: payload, }); // Should return 400/401, not 500 (SQL error) expect([400, 401]).toContain(response.status); expect(response.body).not.toMatch(/SQL|syntax|error/i); } }); test('search should sanitize input', async () => { for (const payload of sqlInjectionPayloads) { const response = await request(app) .get('/api/products/search') .query({ q: payload }); // Should not cause SQL error expect(response.status).toBeLessThan(500); expect(response.body).not.toMatch(/SQL|syntax/i); } }); test('numeric parameters should be validated', async () => { const response = await request(app) .get('/api/users/abc') // Non-numeric ID .expect(400); expect(response.body.error).toBeTruthy(); }); }); ``` ### 3. **XSS Testing** ```javascript // tests/security/xss.test.js describe('XSS Protection', () => { const xssPayloads = [ '', '', '', 'javascript:alert("XSS")', '', ]; test('user input should be escaped', async () => { const { page } = await browser.newPage(); for (const payload of xssPayloads) { await page.goto('/'); // Submit comment with XSS payload await page.fill('[name="comment"]', payload); await page.click('[type="submit"]'); // Wait for comment to appear await page.waitForSelector('.comment'); // Check that script was not executed const dialogAppeared = await page.evaluate(() => { return window.xssDetected || false; }); expect(dialogAppeared).toBe(false); // Check HTML is escaped const commentHTML = await page.$eval('.comment', el => el.innerHTML); expect(commentHTML).not.toContain('