qa-skills 3.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.
- package/README.md +168 -0
- package/bin/cli.js +42 -0
- package/dist/agents/registry.d.ts +5 -0
- package/dist/agents/registry.d.ts.map +1 -0
- package/dist/agents/registry.js +101 -0
- package/dist/agents/registry.js.map +1 -0
- package/dist/agents/types.d.ts +9 -0
- package/dist/agents/types.d.ts.map +1 -0
- package/dist/agents/types.js +2 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/dependencies.d.ts +21 -0
- package/dist/dependencies.d.ts.map +1 -0
- package/dist/dependencies.js +125 -0
- package/dist/dependencies.js.map +1 -0
- package/dist/installer.d.ts +25 -0
- package/dist/installer.d.ts.map +1 -0
- package/dist/installer.js +437 -0
- package/dist/installer.js.map +1 -0
- package/dist/scaffold.d.ts +27 -0
- package/dist/scaffold.d.ts.map +1 -0
- package/dist/scaffold.js +182 -0
- package/dist/scaffold.js.map +1 -0
- package/package.json +40 -0
- package/skills/qa-accessibility-test-writer/SKILL.md +127 -0
- package/skills/qa-accessibility-test-writer/references/axe-core-patterns.md +349 -0
- package/skills/qa-accessibility-test-writer/references/best-practices.md +184 -0
- package/skills/qa-accessibility-test-writer/references/wcag-tests.md +331 -0
- package/skills/qa-api-contract-curator/SKILL.md +104 -0
- package/skills/qa-api-contract-curator/references/breaking-changes.md +363 -0
- package/skills/qa-api-contract-curator/references/openapi-structure.md +404 -0
- package/skills/qa-browser-data-collector/SKILL.md +132 -0
- package/skills/qa-browser-data-collector/references/data-collection-checklist.md +91 -0
- package/skills/qa-browser-data-collector/references/playwright-mcp-patterns.md +113 -0
- package/skills/qa-bug-ticket-creator/SKILL.md +148 -0
- package/skills/qa-bug-ticket-creator/references/bug-report-format.md +149 -0
- package/skills/qa-bug-ticket-creator/references/severity-guide.md +81 -0
- package/skills/qa-bug-ticket-creator/templates/bug-ticket-template.md +39 -0
- package/skills/qa-changelog-analyzer/SKILL.md +134 -0
- package/skills/qa-changelog-analyzer/references/git-analysis-patterns.md +138 -0
- package/skills/qa-changelog-analyzer/references/impact-mapping.md +120 -0
- package/skills/qa-clickup-integration/SKILL.md +166 -0
- package/skills/qa-clickup-integration/references/api-patterns.md +102 -0
- package/skills/qa-clickup-integration/references/field-mapping.md +71 -0
- package/skills/qa-codeceptjs-writer/SKILL.md +136 -0
- package/skills/qa-codeceptjs-writer/references/best-practices.md +207 -0
- package/skills/qa-codeceptjs-writer/references/config.md +255 -0
- package/skills/qa-codeceptjs-writer/references/patterns.md +285 -0
- package/skills/qa-coverage-analyzer/SKILL.md +166 -0
- package/skills/qa-coverage-analyzer/references/best-practices.md +142 -0
- package/skills/qa-coverage-analyzer/references/coverage-dimensions.md +155 -0
- package/skills/qa-coverage-analyzer/references/tools.md +204 -0
- package/skills/qa-cypress-writer/SKILL.md +134 -0
- package/skills/qa-cypress-writer/references/assertions.md +121 -0
- package/skills/qa-cypress-writer/references/best-practices.md +82 -0
- package/skills/qa-cypress-writer/references/config.md +121 -0
- package/skills/qa-cypress-writer/references/patterns.md +170 -0
- package/skills/qa-data-factory/SKILL.md +126 -0
- package/skills/qa-data-factory/references/factory-patterns.md +164 -0
- package/skills/qa-data-factory/references/faker-guide.md +131 -0
- package/skills/qa-diagram-generator/SKILL.md +125 -0
- package/skills/qa-diagram-generator/references/c4-model.md +53 -0
- package/skills/qa-diagram-generator/references/charts.md +58 -0
- package/skills/qa-diagram-generator/references/class-diagram.md +85 -0
- package/skills/qa-diagram-generator/references/er-diagram.md +69 -0
- package/skills/qa-diagram-generator/references/flowchart.md +92 -0
- package/skills/qa-diagram-generator/references/from-screenshot.md +45 -0
- package/skills/qa-diagram-generator/references/gantt.md +49 -0
- package/skills/qa-diagram-generator/references/journey.md +50 -0
- package/skills/qa-diagram-generator/references/mindmap.md +75 -0
- package/skills/qa-diagram-generator/references/sequence.md +69 -0
- package/skills/qa-diagram-generator/references/state-diagram.md +56 -0
- package/skills/qa-discovery-interview/SKILL.md +182 -0
- package/skills/qa-discovery-interview/references/completeness-checklist.md +53 -0
- package/skills/qa-discovery-interview/references/conflict-patterns.md +101 -0
- package/skills/qa-discovery-interview/references/qa-categories.md +147 -0
- package/skills/qa-discovery-interview/templates/qa-brief-template.md +168 -0
- package/skills/qa-environment-checker/SKILL.md +142 -0
- package/skills/qa-environment-checker/references/dependency-matrix.md +101 -0
- package/skills/qa-environment-checker/references/health-checks.md +209 -0
- package/skills/qa-environment-checker/templates/env-readiness-template.md +64 -0
- package/skills/qa-flaky-detector/SKILL.md +153 -0
- package/skills/qa-flaky-detector/references/ci-analysis.md +140 -0
- package/skills/qa-flaky-detector/references/flaky-patterns.md +247 -0
- package/skills/qa-github-issues-enhanced/SKILL.md +175 -0
- package/skills/qa-github-issues-enhanced/references/issue-templates.md +425 -0
- package/skills/qa-github-issues-enhanced/references/label-taxonomy.md +130 -0
- package/skills/qa-github-issues-enhanced/references/workflow-patterns.md +188 -0
- package/skills/qa-httpx-writer/SKILL.md +138 -0
- package/skills/qa-httpx-writer/references/assertions.md +195 -0
- package/skills/qa-httpx-writer/references/best-practices.md +140 -0
- package/skills/qa-httpx-writer/references/config.md +212 -0
- package/skills/qa-httpx-writer/references/patterns.md +262 -0
- package/skills/qa-jest-writer/SKILL.md +131 -0
- package/skills/qa-jest-writer/references/assertions.md +125 -0
- package/skills/qa-jest-writer/references/best-practices.md +136 -0
- package/skills/qa-jest-writer/references/config.md +134 -0
- package/skills/qa-jest-writer/references/patterns.md +172 -0
- package/skills/qa-jira-integration/SKILL.md +135 -0
- package/skills/qa-jira-integration/references/api-patterns.md +143 -0
- package/skills/qa-jira-integration/references/field-mapping.md +79 -0
- package/skills/qa-jira-integration/references/xray-integration.md +85 -0
- package/skills/qa-jmeter-writer/SKILL.md +171 -0
- package/skills/qa-jmeter-writer/references/best-practices.md +157 -0
- package/skills/qa-jmeter-writer/references/config.md +204 -0
- package/skills/qa-jmeter-writer/references/patterns.md +242 -0
- package/skills/qa-junit5-writer/SKILL.md +157 -0
- package/skills/qa-junit5-writer/references/assertions.md +118 -0
- package/skills/qa-junit5-writer/references/config.md +97 -0
- package/skills/qa-junit5-writer/references/patterns.md +162 -0
- package/skills/qa-k6-writer/SKILL.md +155 -0
- package/skills/qa-k6-writer/references/best-practices.md +236 -0
- package/skills/qa-k6-writer/references/config.md +219 -0
- package/skills/qa-k6-writer/references/patterns.md +304 -0
- package/skills/qa-linear-integration/SKILL.md +137 -0
- package/skills/qa-linear-integration/references/api-patterns.md +249 -0
- package/skills/qa-linear-integration/references/field-mapping.md +121 -0
- package/skills/qa-locust-writer/SKILL.md +151 -0
- package/skills/qa-locust-writer/references/best-practices.md +126 -0
- package/skills/qa-locust-writer/references/config.md +170 -0
- package/skills/qa-locust-writer/references/patterns.md +235 -0
- package/skills/qa-manual-test-designer/SKILL.md +145 -0
- package/skills/qa-manual-test-designer/references/exploratory-charters.md +138 -0
- package/skills/qa-manual-test-designer/references/personas.md +146 -0
- package/skills/qa-manual-test-designer/templates/exploratory-charter-template.md +47 -0
- package/skills/qa-manual-test-designer/templates/test-case-template.md +31 -0
- package/skills/qa-mobile-test-writer/SKILL.md +144 -0
- package/skills/qa-mobile-test-writer/references/best-practices.md +214 -0
- package/skills/qa-mobile-test-writer/references/config.md +309 -0
- package/skills/qa-mobile-test-writer/references/patterns.md +304 -0
- package/skills/qa-nfr-analyst/SKILL.md +177 -0
- package/skills/qa-nfr-analyst/references/iso-25010-model.md +159 -0
- package/skills/qa-nfr-analyst/references/owasp-wstg-baseline.md +202 -0
- package/skills/qa-nfr-analyst/references/wcag-checklist.md +184 -0
- package/skills/qa-nfr-analyst/templates/owasp-checklist-template.md +89 -0
- package/skills/qa-nfr-analyst/templates/wcag-checklist-template.md +48 -0
- package/skills/qa-orchestrator/SKILL.md +132 -0
- package/skills/qa-orchestrator/references/handoff-chains.md +105 -0
- package/skills/qa-orchestrator/references/pipeline-modes.md +115 -0
- package/skills/qa-orchestrator/references/scheduler-rules.md +84 -0
- package/skills/qa-pact-writer/SKILL.md +133 -0
- package/skills/qa-pact-writer/references/best-practices.md +100 -0
- package/skills/qa-pact-writer/references/config.md +135 -0
- package/skills/qa-pact-writer/references/patterns.md +161 -0
- package/skills/qa-plan-creator/SKILL.md +139 -0
- package/skills/qa-plan-creator/references/introduction-plan.md +43 -0
- package/skills/qa-plan-creator/references/migration-plan.md +44 -0
- package/skills/qa-plan-creator/references/onboarding-plan.md +46 -0
- package/skills/qa-plan-creator/references/performance-plan.md +44 -0
- package/skills/qa-plan-creator/references/regression-plan.md +45 -0
- package/skills/qa-plan-creator/references/release-plan.md +45 -0
- package/skills/qa-plan-creator/references/sprint-plan.md +44 -0
- package/skills/qa-plan-creator/references/test-plan.md +59 -0
- package/skills/qa-plan-creator/references/uat-plan.md +43 -0
- package/skills/qa-plan-creator/templates/checklist-template.md +36 -0
- package/skills/qa-plan-creator/templates/regression-checklist-template.md +49 -0
- package/skills/qa-plan-creator/templates/release-checklist-template.md +46 -0
- package/skills/qa-plan-creator/templates/test-plan-template.md +74 -0
- package/skills/qa-playwright-py-writer/SKILL.md +156 -0
- package/skills/qa-playwright-py-writer/references/best-practices.md +194 -0
- package/skills/qa-playwright-py-writer/references/config.md +195 -0
- package/skills/qa-playwright-py-writer/references/patterns.md +212 -0
- package/skills/qa-playwright-ts-writer/SKILL.md +151 -0
- package/skills/qa-playwright-ts-writer/references/assertions.md +109 -0
- package/skills/qa-playwright-ts-writer/references/best-practices.md +191 -0
- package/skills/qa-playwright-ts-writer/references/config.md +144 -0
- package/skills/qa-playwright-ts-writer/references/patterns.md +171 -0
- package/skills/qa-pytest-writer/SKILL.md +145 -0
- package/skills/qa-pytest-writer/references/assertions.md +149 -0
- package/skills/qa-pytest-writer/references/best-practices.md +97 -0
- package/skills/qa-pytest-writer/references/config.md +176 -0
- package/skills/qa-pytest-writer/references/patterns.md +251 -0
- package/skills/qa-qase-integration/SKILL.md +149 -0
- package/skills/qa-qase-integration/references/api-reference.md +354 -0
- package/skills/qa-qase-integration/references/ci-integration.md +196 -0
- package/skills/qa-qase-integration/references/field-mapping.md +157 -0
- package/skills/qa-requirements-generator/SKILL.md +152 -0
- package/skills/qa-requirements-generator/references/iso-29148-structure.md +153 -0
- package/skills/qa-requirements-generator/references/requirement-patterns.md +278 -0
- package/skills/qa-rest-assured-writer/SKILL.md +137 -0
- package/skills/qa-rest-assured-writer/references/best-practices.md +50 -0
- package/skills/qa-rest-assured-writer/references/config.md +124 -0
- package/skills/qa-rest-assured-writer/references/patterns.md +192 -0
- package/skills/qa-risk-analyzer/SKILL.md +158 -0
- package/skills/qa-risk-analyzer/references/impact-analysis.md +133 -0
- package/skills/qa-risk-analyzer/references/risk-factors.md +123 -0
- package/skills/qa-robot-framework-writer/SKILL.md +147 -0
- package/skills/qa-robot-framework-writer/references/best-practices.md +249 -0
- package/skills/qa-robot-framework-writer/references/config.md +204 -0
- package/skills/qa-robot-framework-writer/references/libraries.md +273 -0
- package/skills/qa-robot-framework-writer/references/patterns.md +216 -0
- package/skills/qa-security-test-writer/SKILL.md +123 -0
- package/skills/qa-security-test-writer/references/best-practices.md +155 -0
- package/skills/qa-security-test-writer/references/owasp-top10.md +331 -0
- package/skills/qa-security-test-writer/references/zap-config.md +258 -0
- package/skills/qa-selenium-java-writer/SKILL.md +143 -0
- package/skills/qa-selenium-java-writer/references/best-practices.md +59 -0
- package/skills/qa-selenium-java-writer/references/config.md +143 -0
- package/skills/qa-selenium-java-writer/references/patterns.md +170 -0
- package/skills/qa-selenium-py-writer/SKILL.md +150 -0
- package/skills/qa-selenium-py-writer/references/best-practices.md +175 -0
- package/skills/qa-selenium-py-writer/references/config.md +224 -0
- package/skills/qa-selenium-py-writer/references/patterns.md +255 -0
- package/skills/qa-shortcut-integration/SKILL.md +143 -0
- package/skills/qa-shortcut-integration/references/api-patterns.md +126 -0
- package/skills/qa-shortcut-integration/references/field-mapping.md +66 -0
- package/skills/qa-spec-auditor/SKILL.md +162 -0
- package/skills/qa-spec-auditor/references/audit-checklist.md +144 -0
- package/skills/qa-spec-auditor/references/drift-patterns.md +207 -0
- package/skills/qa-spec-writer/SKILL.md +143 -0
- package/skills/qa-spec-writer/references/gherkin-guide.md +253 -0
- package/skills/qa-spec-writer/references/specification-patterns.md +274 -0
- package/skills/qa-spring-test-writer/SKILL.md +170 -0
- package/skills/qa-spring-test-writer/references/best-practices.md +57 -0
- package/skills/qa-spring-test-writer/references/config.md +179 -0
- package/skills/qa-spring-test-writer/references/patterns.md +235 -0
- package/skills/qa-supertest-writer/SKILL.md +150 -0
- package/skills/qa-supertest-writer/references/assertions.md +192 -0
- package/skills/qa-supertest-writer/references/best-practices.md +102 -0
- package/skills/qa-supertest-writer/references/config.md +166 -0
- package/skills/qa-supertest-writer/references/patterns.md +242 -0
- package/skills/qa-task-creator/SKILL.md +142 -0
- package/skills/qa-task-creator/references/linking-patterns.md +127 -0
- package/skills/qa-task-creator/references/task-types.md +169 -0
- package/skills/qa-task-creator/templates/task-template.md +24 -0
- package/skills/qa-test-doc-compiler/SKILL.md +114 -0
- package/skills/qa-test-doc-compiler/references/agile-tailoring.md +220 -0
- package/skills/qa-test-doc-compiler/references/iso-29119-3-documents.md +302 -0
- package/skills/qa-test-healer/SKILL.md +101 -0
- package/skills/qa-test-healer/references/diagnosis-patterns.md +142 -0
- package/skills/qa-test-healer/references/fix-strategies.md +177 -0
- package/skills/qa-test-reporter/SKILL.md +130 -0
- package/skills/qa-test-reporter/references/best-practices.md +162 -0
- package/skills/qa-test-reporter/references/iso-29119-reports.md +236 -0
- package/skills/qa-test-reporter/references/report-formats.md +287 -0
- package/skills/qa-test-reviewer/SKILL.md +142 -0
- package/skills/qa-test-reviewer/references/anti-patterns.md +268 -0
- package/skills/qa-test-reviewer/references/review-checklist.md +93 -0
- package/skills/qa-test-strategy/SKILL.md +133 -0
- package/skills/qa-test-strategy/references/entry-exit-criteria.md +176 -0
- package/skills/qa-test-strategy/references/risk-matrix.md +102 -0
- package/skills/qa-test-strategy/references/testing-types.md +143 -0
- package/skills/qa-testcase-from-docs/SKILL.md +161 -0
- package/skills/qa-testcase-from-docs/references/test-case-format.md +196 -0
- package/skills/qa-testcase-from-docs/references/test-design-techniques.md +126 -0
- package/skills/qa-testcase-from-docs/templates/test-case-template.md +31 -0
- package/skills/qa-testcase-from-ui/SKILL.md +109 -0
- package/skills/qa-testcase-from-ui/references/ui-element-patterns.md +126 -0
- package/skills/qa-testcase-from-ui/references/visual-analysis-guide.md +146 -0
- package/skills/qa-testcase-from-ui/templates/test-case-template.md +31 -0
- package/skills/qa-visual-regression-writer/SKILL.md +175 -0
- package/skills/qa-visual-regression-writer/references/best-practices.md +154 -0
- package/skills/qa-visual-regression-writer/references/config.md +220 -0
- package/skills/qa-visual-regression-writer/references/patterns.md +213 -0
- package/skills/qa-vitest-writer/SKILL.md +141 -0
- package/skills/qa-vitest-writer/references/assertions.md +105 -0
- package/skills/qa-vitest-writer/references/best-practices.md +62 -0
- package/skills/qa-vitest-writer/references/config.md +127 -0
- package/skills/qa-vitest-writer/references/patterns.md +141 -0
- package/skills/qa-webdriverio-writer/SKILL.md +145 -0
- package/skills/qa-webdriverio-writer/references/best-practices.md +176 -0
- package/skills/qa-webdriverio-writer/references/config.md +240 -0
- package/skills/qa-webdriverio-writer/references/patterns.md +269 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qa-security-test-writer
|
|
3
|
+
description: Generate security tests based on OWASP Top 10 and WSTG covering injection, XSS, CSRF, authentication bypass, and DAST using ZAP and custom scripts.
|
|
4
|
+
output_dir: tests/security
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# QA Security Test Writer
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
Write security tests covering OWASP Top 10 vulnerabilities and OWASP WSTG scenarios. Transform NFR security requirements (from qa-nfr-analyst) and application context into executable security test scripts (TypeScript/Python), OWASP ZAP configurations, and vulnerability reports. Support both custom script-based testing and DAST (Dynamic Application Security Testing) via ZAP.
|
|
12
|
+
|
|
13
|
+
## Trigger Phrases
|
|
14
|
+
|
|
15
|
+
- "Write security tests for [app/API]"
|
|
16
|
+
- "Generate OWASP Top 10 tests"
|
|
17
|
+
- "Create ZAP configuration for [target]"
|
|
18
|
+
- "Security tests for SQL injection, XSS, CSRF"
|
|
19
|
+
- "DAST scan setup with OWASP ZAP"
|
|
20
|
+
- "Authentication bypass tests"
|
|
21
|
+
- "Security test scripts from NFR analysis"
|
|
22
|
+
- "OWASP WSTG test scenarios"
|
|
23
|
+
|
|
24
|
+
## OWASP Top 10 Coverage
|
|
25
|
+
|
|
26
|
+
| ID | Category | Test Focus |
|
|
27
|
+
|----|----------|------------|
|
|
28
|
+
| **A01** | Broken Access Control | IDOR, privilege escalation, path traversal, CORS |
|
|
29
|
+
| **A02** | Cryptographic Failures | TLS, weak hashing, sensitive data in transit/rest |
|
|
30
|
+
| **A03** | Injection | SQL, NoSQL, OS command, LDAP, XPath, SSTI |
|
|
31
|
+
| **A04** | Insecure Design | Business logic flaws, missing security controls |
|
|
32
|
+
| **A05** | Security Misconfiguration | Default creds, debug mode, verbose errors, headers |
|
|
33
|
+
| **A06** | Vulnerable Components | Dependency scanning, known CVEs |
|
|
34
|
+
| **A07** | Identification/Authentication Failures | Weak passwords, session fixation, credential stuffing |
|
|
35
|
+
| **A08** | Software/Data Integrity Failures | Unsigned updates, deserialization, CI/CD tampering |
|
|
36
|
+
| **A09** | Security Logging/Monitoring Failures | Missing audit logs, insufficient alerting |
|
|
37
|
+
| **A10** | Server-Side Request Forgery | SSRF to internal services, cloud metadata |
|
|
38
|
+
|
|
39
|
+
See `references/owasp-top10.md` for test scenarios and example code per category.
|
|
40
|
+
|
|
41
|
+
## Tools
|
|
42
|
+
|
|
43
|
+
| Tool | Purpose |
|
|
44
|
+
|------|---------|
|
|
45
|
+
| **OWASP ZAP** | DAST scanning, passive/active scan, API scan, authentication |
|
|
46
|
+
| **Custom TypeScript** | Supertest/httpx-style API security tests, Playwright for auth flows |
|
|
47
|
+
| **Custom Python** | httpx/requests API tests, pytest-based security checks |
|
|
48
|
+
| **Playwright** | Authentication bypass, session management, XSS verification |
|
|
49
|
+
|
|
50
|
+
## Workflow
|
|
51
|
+
|
|
52
|
+
1. **Read NFR analysis** — From qa-nfr-analyst; extract security criteria and OWASP WSTG baseline
|
|
53
|
+
2. **Map OWASP WSTG scenarios** — Align requirements to WSTG test IDs (see qa-nfr-analyst `references/owasp-wstg-baseline.md`)
|
|
54
|
+
3. **Generate security test scripts** — TypeScript (Supertest/Playwright) or Python (httpx/pytest)
|
|
55
|
+
4. **Configure ZAP** — Active/passive scan, auth, policies (see `references/zap-config.md`)
|
|
56
|
+
5. **Run DAST scan** — Execute ZAP; produce vulnerability report
|
|
57
|
+
|
|
58
|
+
## Test Categories
|
|
59
|
+
|
|
60
|
+
| Category | Techniques | Tools |
|
|
61
|
+
|----------|-------------|-------|
|
|
62
|
+
| **SQL Injection** | Union-based, error-based, blind, time-based | Custom scripts, ZAP |
|
|
63
|
+
| **XSS** | Reflected, stored, DOM-based | Custom scripts, Playwright, ZAP |
|
|
64
|
+
| **CSRF** | Missing token, token reuse, SameSite | Custom scripts, Playwright |
|
|
65
|
+
| **Authentication bypass** | Direct access, token manipulation, session fixation | Playwright, Supertest/httpx |
|
|
66
|
+
| **Session management** | Timeout, logout, cookie attributes | Custom scripts |
|
|
67
|
+
| **Header security** | HSTS, X-Frame-Options, CSP, X-Content-Type-Options | Custom scripts, ZAP |
|
|
68
|
+
| **CORS misconfiguration** | Wildcard origin, credential leakage | Custom scripts |
|
|
69
|
+
| **File upload** | Extension bypass, content-type spoofing, path traversal | Custom scripts |
|
|
70
|
+
|
|
71
|
+
## Output
|
|
72
|
+
|
|
73
|
+
- **Security test scripts** — `tests/security/` or `tests/security/` with TS/Python files
|
|
74
|
+
- **ZAP configuration** — `zap-config.yaml` or `.zap/config` for automation
|
|
75
|
+
- **Vulnerability report** — Summary of findings with severity, evidence, remediation
|
|
76
|
+
|
|
77
|
+
## References
|
|
78
|
+
|
|
79
|
+
- `references/owasp-top10.md` — OWASP Top 10 test scenarios with example test code
|
|
80
|
+
- `references/zap-config.md` — OWASP ZAP configuration (active/passive scan, API, auth, policies)
|
|
81
|
+
- `references/best-practices.md` — Safe testing, test environments, reporting, remediation
|
|
82
|
+
|
|
83
|
+
## Scope
|
|
84
|
+
|
|
85
|
+
**Can do (autonomous):**
|
|
86
|
+
- Generate security test scripts from NFR analysis or WSTG scenarios
|
|
87
|
+
- Create ZAP configuration for DAST
|
|
88
|
+
- Write custom TypeScript/Python tests for injection, XSS, CSRF, auth, headers
|
|
89
|
+
- Map OWASP Top 10 to test cases
|
|
90
|
+
- Call qa-nfr-analyst for security NFRs when needed
|
|
91
|
+
- Use qa-diagram-generator for threat/attack flow diagrams
|
|
92
|
+
|
|
93
|
+
**Cannot do (requires confirmation):**
|
|
94
|
+
- Run scans against production without explicit approval
|
|
95
|
+
- Add dependencies not in package.json/requirements.txt
|
|
96
|
+
- Override project security policy or scope
|
|
97
|
+
|
|
98
|
+
**Will not do (out of scope):**
|
|
99
|
+
- Execute ZAP or custom tests (user runs them)
|
|
100
|
+
- Perform penetration testing beyond automated checks
|
|
101
|
+
- Implement security fixes
|
|
102
|
+
|
|
103
|
+
## Quality Checklist
|
|
104
|
+
|
|
105
|
+
- [ ] Tests cover OWASP Top 10 categories relevant to the application
|
|
106
|
+
- [ ] No hardcoded credentials; use env vars or fixtures
|
|
107
|
+
- [ ] Payloads are safe (no destructive SQL/commands)
|
|
108
|
+
- [ ] ZAP config targets staging/test environment only
|
|
109
|
+
- [ ] Each test has clear assertion (pass = no vulnerability)
|
|
110
|
+
- [ ] File naming follows `test_*_security.ts` or `test_*_security.py`
|
|
111
|
+
- [ ] References to NFR IDs or WSTG IDs where applicable
|
|
112
|
+
- [ ] Vulnerability report includes severity and remediation guidance
|
|
113
|
+
|
|
114
|
+
## Troubleshooting
|
|
115
|
+
|
|
116
|
+
| Symptom | Likely Cause | Fix |
|
|
117
|
+
|---------|--------------|-----|
|
|
118
|
+
| ZAP scan finds nothing | Target not reachable, auth not configured | Verify base URL; configure ZAP authentication |
|
|
119
|
+
| Tests fail with 403 | WAF or rate limiting | Use test env; whitelist test IP; reduce concurrency |
|
|
120
|
+
| False positives in ZAP | Aggressive policy, app-specific behavior | Tune scan policy; add context/exclusions |
|
|
121
|
+
| XSS payload not reflected | Input sanitization, encoding | Try alternative payloads; check DOM sinks |
|
|
122
|
+
| CSRF test passes incorrectly | SameSite=Lax blocks cross-site POST | Use same-origin test or disable SameSite in test |
|
|
123
|
+
| Session tests flaky | Short timeout, shared state | Increase timeout; isolate session per test |
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# Security Testing Best Practices
|
|
2
|
+
|
|
3
|
+
Best practices for safe, effective security testing. Use with qa-security-test-writer when generating tests and configuring scans.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Safe Testing
|
|
8
|
+
|
|
9
|
+
### Payload Safety
|
|
10
|
+
|
|
11
|
+
| Do | Don't |
|
|
12
|
+
|----|-------|
|
|
13
|
+
| Use read-only or non-destructive payloads | Use `DROP TABLE`, `rm -rf`, or similar |
|
|
14
|
+
| Test in isolated test/staging environments | Run against production without approval |
|
|
15
|
+
| Use parameterized/safe SQL for comparison | Execute raw attacker payloads against real DB |
|
|
16
|
+
| Verify rejection/encoding, not exploitation | Attempt to actually exfiltrate data |
|
|
17
|
+
|
|
18
|
+
### Example: Safe SQL Injection Test
|
|
19
|
+
|
|
20
|
+
```python
|
|
21
|
+
# Good: Verify app rejects or sanitizes
|
|
22
|
+
def test_sqli_rejected(client):
|
|
23
|
+
r = client.get("/api/search", params={"q": "' OR '1'='1"})
|
|
24
|
+
assert r.status_code in (400, 403, 422)
|
|
25
|
+
# Do NOT actually expect to retrieve all rows
|
|
26
|
+
|
|
27
|
+
# Bad: Expecting to bypass and get data
|
|
28
|
+
def test_sqli_bad(client):
|
|
29
|
+
r = client.get("/api/search", params={"q": "' OR 1=1--"})
|
|
30
|
+
assert len(r.json()["results"]) > 0 # Never assert success of attack
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Credentials and Secrets
|
|
34
|
+
|
|
35
|
+
- Store test credentials in `.env` or CI secrets
|
|
36
|
+
- Never commit passwords, API keys, or tokens
|
|
37
|
+
- Use separate test accounts with minimal privileges
|
|
38
|
+
- Rotate test credentials periodically
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Test Environments
|
|
43
|
+
|
|
44
|
+
### Environment Isolation
|
|
45
|
+
|
|
46
|
+
| Environment | Use For | Scan Type |
|
|
47
|
+
|-------------|---------|-----------|
|
|
48
|
+
| **Local** | Unit/integration security tests | Custom scripts only |
|
|
49
|
+
| **Staging** | DAST, full security suite | ZAP, custom scripts |
|
|
50
|
+
| **Production** | Never for active security testing | Passive monitoring only (if approved) |
|
|
51
|
+
|
|
52
|
+
### Pre-Scan Checklist
|
|
53
|
+
|
|
54
|
+
- [ ] Target is staging/test, not production
|
|
55
|
+
- [ ] WAF/firewall allows test IP or is disabled in test env
|
|
56
|
+
- [ ] Test accounts exist and credentials are in env vars
|
|
57
|
+
- [ ] Destructive endpoints (delete, reset) are excluded
|
|
58
|
+
- [ ] Scan window communicated to team (if shared env)
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Reporting
|
|
63
|
+
|
|
64
|
+
### Vulnerability Report Structure
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
1. Executive Summary
|
|
68
|
+
- Scope, dates, high-level findings count
|
|
69
|
+
|
|
70
|
+
2. Findings by Severity
|
|
71
|
+
- Critical, High, Medium, Low, Informational
|
|
72
|
+
|
|
73
|
+
3. Per Finding
|
|
74
|
+
- Title, CWE, OWASP category
|
|
75
|
+
- Description, evidence (request/response snippets)
|
|
76
|
+
- Affected URL/parameter
|
|
77
|
+
- Remediation guidance
|
|
78
|
+
- References (CWE, OWASP, etc.)
|
|
79
|
+
|
|
80
|
+
4. Appendix
|
|
81
|
+
- Scan config, tools, versions
|
|
82
|
+
- Exclusions and scope
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Severity Mapping
|
|
86
|
+
|
|
87
|
+
| Severity | Typical Response |
|
|
88
|
+
|----------|------------------|
|
|
89
|
+
| Critical | Fix before release; block deployment |
|
|
90
|
+
| High | Fix in current sprint |
|
|
91
|
+
| Medium | Plan fix; accept risk if documented |
|
|
92
|
+
| Low | Backlog; fix when convenient |
|
|
93
|
+
| Informational | Review; no mandatory fix |
|
|
94
|
+
|
|
95
|
+
### False Positive Handling
|
|
96
|
+
|
|
97
|
+
- Document why a finding is a false positive
|
|
98
|
+
- Add exclusion in ZAP context or scan policy
|
|
99
|
+
- Re-verify after app changes
|
|
100
|
+
- Do not ignore without documentation
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Remediation Guidance
|
|
105
|
+
|
|
106
|
+
### Common Remediation Patterns
|
|
107
|
+
|
|
108
|
+
| Vulnerability | Remediation |
|
|
109
|
+
|---------------|-------------|
|
|
110
|
+
| **SQL Injection** | Parameterized queries, ORM, input validation |
|
|
111
|
+
| **XSS** | Output encoding, CSP, sanitization (DOMPurify, etc.) |
|
|
112
|
+
| **CSRF** | CSRF tokens, SameSite cookies, double-submit cookie |
|
|
113
|
+
| **Broken Access Control** | Authorization checks on every request, avoid IDOR |
|
|
114
|
+
| **Missing Headers** | Add HSTS, X-Frame-Options, X-Content-Type-Options, CSP |
|
|
115
|
+
| **Weak Auth** | Strong password policy, MFA, lockout, secure session |
|
|
116
|
+
| **Sensitive Data Exposure** | Encrypt at rest/transit, no PII in logs/errors |
|
|
117
|
+
|
|
118
|
+
### Reference Remediation Sources
|
|
119
|
+
|
|
120
|
+
- [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/)
|
|
121
|
+
- [CWE Top 25](https://cwe.mitre.org/top25/)
|
|
122
|
+
- [NIST Secure Coding](https://www.nist.gov/)
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Integration with QA Workflow
|
|
127
|
+
|
|
128
|
+
### CI/CD
|
|
129
|
+
|
|
130
|
+
- Run security tests in CI on every PR (custom scripts)
|
|
131
|
+
- Run ZAP baseline weekly or on release branches
|
|
132
|
+
- Fail pipeline on critical/high (configurable)
|
|
133
|
+
- Store reports as artifacts
|
|
134
|
+
|
|
135
|
+
### NFR Traceability
|
|
136
|
+
|
|
137
|
+
- Link security tests to NFR IDs (e.g., NFR-SEC-001)
|
|
138
|
+
- Link to OWASP WSTG IDs (e.g., WSTG-INPV-05)
|
|
139
|
+
- Trace findings back to requirements for coverage reporting
|
|
140
|
+
|
|
141
|
+
### Collaboration
|
|
142
|
+
|
|
143
|
+
- Share reports with dev and security teams
|
|
144
|
+
- Triage findings in sprint planning
|
|
145
|
+
- Track remediation in issue tracker
|
|
146
|
+
- Re-scan after fixes to verify
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## References
|
|
151
|
+
|
|
152
|
+
- [OWASP Testing Guide](https://owasp.org/www-project-web-security-testing-guide/)
|
|
153
|
+
- [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/)
|
|
154
|
+
- [PTES Technical Guidelines](http://www.pentest-standard.org/)
|
|
155
|
+
- [NIST SP 800-115](https://csrc.nist.gov/publications/detail/sp/800-115/final)
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
# OWASP Top 10 Test Scenarios and Example Code
|
|
2
|
+
|
|
3
|
+
Test scenarios and example test code for each OWASP Top 10 (2021) category. Use with qa-security-test-writer for generating security tests.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## A01: Broken Access Control
|
|
8
|
+
|
|
9
|
+
**Focus:** IDOR, privilege escalation, path traversal, CORS misconfiguration.
|
|
10
|
+
|
|
11
|
+
### IDOR (Insecure Direct Object Reference)
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
// TypeScript (Supertest)
|
|
15
|
+
describe('A01 - IDOR', () => {
|
|
16
|
+
it('should deny access to other user resources', async () => {
|
|
17
|
+
const userAToken = await getAuthToken('userA');
|
|
18
|
+
const userBResourceId = 'user-b-resource-id';
|
|
19
|
+
const res = await request(app)
|
|
20
|
+
.get(`/api/resources/${userBResourceId}`)
|
|
21
|
+
.set('Authorization', `Bearer ${userAToken}`)
|
|
22
|
+
.expect(403); // or 404 to avoid enumeration
|
|
23
|
+
expect(res.body).not.toHaveProperty('data');
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
# Python (httpx)
|
|
30
|
+
def test_idor_denies_cross_user_access(client, user_a_token, user_b_resource_id):
|
|
31
|
+
r = client.get(
|
|
32
|
+
f"/api/resources/{user_b_resource_id}",
|
|
33
|
+
headers={"Authorization": f"Bearer {user_a_token}"},
|
|
34
|
+
)
|
|
35
|
+
assert r.status_code in (403, 404)
|
|
36
|
+
assert "data" not in r.json()
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Path Traversal
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
def test_path_traversal_blocked(client):
|
|
43
|
+
payloads = ["../../../etc/passwd", "..%2F..%2F..%2Fetc%2Fpasswd"]
|
|
44
|
+
for payload in payloads:
|
|
45
|
+
r = client.get(f"/api/file?path={payload}")
|
|
46
|
+
assert r.status_code in (400, 403, 404)
|
|
47
|
+
assert "root:" not in r.text
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## A02: Cryptographic Failures
|
|
53
|
+
|
|
54
|
+
**Focus:** TLS, weak hashing, sensitive data over HTTP.
|
|
55
|
+
|
|
56
|
+
### TLS and Security Headers
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
describe('A02 - Cryptographic Failures', () => {
|
|
60
|
+
it('should serve over HTTPS only', async () => {
|
|
61
|
+
const res = await request('http://localhost:3000').get('/');
|
|
62
|
+
expect(res.status).toBe(301);
|
|
63
|
+
expect(res.headers.location).toMatch(/^https:\/\//);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('should set HSTS header', async () => {
|
|
67
|
+
const res = await request(app).get('/').expect(200);
|
|
68
|
+
expect(res.headers['strict-transport-security']).toBeDefined();
|
|
69
|
+
expect(res.headers['strict-transport-security']).toMatch(/max-age=\d+/);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
def test_no_sensitive_data_over_http(base_url_http):
|
|
76
|
+
r = httpx.get(f"{base_url_http}/api/login", follow_redirects=True)
|
|
77
|
+
assert r.url.scheme == "https"
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## A03: Injection
|
|
83
|
+
|
|
84
|
+
**Focus:** SQL, NoSQL, OS command, LDAP, XPath, SSTI.
|
|
85
|
+
|
|
86
|
+
### SQL Injection
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
describe('A03 - SQL Injection', () => {
|
|
90
|
+
const sqlPayloads = [
|
|
91
|
+
"' OR '1'='1",
|
|
92
|
+
"1; DROP TABLE users--",
|
|
93
|
+
"1' UNION SELECT null,null--",
|
|
94
|
+
"1' AND SLEEP(5)--",
|
|
95
|
+
];
|
|
96
|
+
|
|
97
|
+
sqlPayloads.forEach((payload) => {
|
|
98
|
+
it(`should reject SQLi payload: ${payload.substring(0, 20)}...`, async () => {
|
|
99
|
+
const res = await request(app)
|
|
100
|
+
.get(`/api/search?q=${encodeURIComponent(payload)}`)
|
|
101
|
+
.expect((status) => status >= 400 || status === 200);
|
|
102
|
+
// Should not return SQL error or unexpected data
|
|
103
|
+
expect(res.body).not.toMatch(/syntax error|mysql|postgresql|ora-/i);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
def test_sql_injection_blocked(client):
|
|
111
|
+
payloads = ["' OR '1'='1", "1; DROP TABLE users--"]
|
|
112
|
+
for p in payloads:
|
|
113
|
+
r = client.get(f"/api/search", params={"q": p})
|
|
114
|
+
assert r.status_code in (400, 403, 422)
|
|
115
|
+
assert "syntax" not in r.text.lower() and "mysql" not in r.text.lower()
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### XSS (Reflected)
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
def test_reflected_xss_blocked(client):
|
|
122
|
+
payload = "<script>alert(1)</script>"
|
|
123
|
+
r = client.get(f"/api/search", params={"q": payload})
|
|
124
|
+
assert payload not in r.text
|
|
125
|
+
assert "<script>" in r.text or "script" not in r.text
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## A04: Insecure Design
|
|
131
|
+
|
|
132
|
+
**Focus:** Business logic flaws, missing security controls.
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
describe('A04 - Insecure Design', () => {
|
|
136
|
+
it('should enforce workflow order (no step skipping)', async () => {
|
|
137
|
+
const token = await getAuthToken('user');
|
|
138
|
+
const res = await request(app)
|
|
139
|
+
.post('/api/checkout/confirm')
|
|
140
|
+
.set('Authorization', `Bearer ${token}`)
|
|
141
|
+
.send({ orderId: '123' })
|
|
142
|
+
.expect(400); // Should require prior steps
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## A05: Security Misconfiguration
|
|
150
|
+
|
|
151
|
+
**Focus:** Default credentials, debug mode, verbose errors, headers.
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
describe('A05 - Security Misconfiguration', () => {
|
|
155
|
+
it('should not expose stack traces', async () => {
|
|
156
|
+
const res = await request(app).get('/api/nonexistent').expect(404);
|
|
157
|
+
expect(res.body).not.toMatch(/at\s+\w+\.\w+|\.ts:\d+|\.js:\d+/);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('should set secure headers', async () => {
|
|
161
|
+
const res = await request(app).get('/').expect(200);
|
|
162
|
+
expect(res.headers['x-content-type-options']).toBe('nosniff');
|
|
163
|
+
expect(res.headers['x-frame-options']).toBeDefined();
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
def test_no_debug_info_in_errors(client):
|
|
170
|
+
r = client.get("/api/trigger-error")
|
|
171
|
+
assert "Traceback" not in r.text
|
|
172
|
+
assert "__file__" not in r.text
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## A06: Vulnerable Components
|
|
178
|
+
|
|
179
|
+
**Focus:** Dependency scanning, known CVEs. Typically handled by npm audit, pip-audit, Snyk, etc. Scripts can verify scan is run:
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
describe('A06 - Vulnerable Components', () => {
|
|
183
|
+
it('should have no high/critical vulnerabilities in lockfile', async () => {
|
|
184
|
+
const { stdout } = await exec('npm audit --audit-level=high');
|
|
185
|
+
expect(stdout).not.toMatch(/found \d+ high/);
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## A07: Identification and Authentication Failures
|
|
193
|
+
|
|
194
|
+
**Focus:** Weak passwords, session fixation, credential stuffing.
|
|
195
|
+
|
|
196
|
+
### Session Fixation
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
describe('A07 - Authentication Failures', () => {
|
|
200
|
+
it('should issue new session ID after login', async () => {
|
|
201
|
+
const { browser } = await playwright.chromium.launch();
|
|
202
|
+
const page = await browser.newPage();
|
|
203
|
+
const cookiesBefore = await page.context().cookies();
|
|
204
|
+
await page.goto('/login');
|
|
205
|
+
await page.fill('#username', 'test');
|
|
206
|
+
await page.fill('#password', 'Test123!');
|
|
207
|
+
await page.click('button[type=submit]');
|
|
208
|
+
const cookiesAfter = await page.context().cookies();
|
|
209
|
+
const sessionBefore = cookiesBefore.find((c) => c.name === 'sessionId');
|
|
210
|
+
const sessionAfter = cookiesAfter.find((c) => c.name === 'sessionId');
|
|
211
|
+
expect(sessionAfter?.value).not.toBe(sessionBefore?.value);
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Weak Password Policy
|
|
217
|
+
|
|
218
|
+
```python
|
|
219
|
+
def test_weak_password_rejected(client):
|
|
220
|
+
r = client.post("/api/register", json={
|
|
221
|
+
"email": "test@example.com",
|
|
222
|
+
"password": "123",
|
|
223
|
+
})
|
|
224
|
+
assert r.status_code == 400
|
|
225
|
+
assert "password" in r.json().get("errors", {}).get("password", "").lower()
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## A08: Software and Data Integrity Failures
|
|
231
|
+
|
|
232
|
+
**Focus:** Unsigned updates, deserialization, CI/CD tampering.
|
|
233
|
+
|
|
234
|
+
```python
|
|
235
|
+
def test_deserialization_safe(client):
|
|
236
|
+
# Send malicious pickle/serialized payload
|
|
237
|
+
r = client.post("/api/import", data=b"\x80\x04...", headers={"Content-Type": "application/octet-stream"})
|
|
238
|
+
assert r.status_code in (400, 415)
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## A09: Security Logging and Monitoring Failures
|
|
244
|
+
|
|
245
|
+
**Focus:** Missing audit logs, insufficient alerting. Often manual/ops; scripts can verify logging endpoints exist:
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
it('should log failed login attempts', async () => {
|
|
249
|
+
await request(app).post('/api/login').send({ user: 'x', pass: 'y' });
|
|
250
|
+
// Verify log sink received event (mock or integration)
|
|
251
|
+
expect(logSpy).toHaveBeenCalledWith(expect.objectContaining({ event: 'login_failed' }));
|
|
252
|
+
});
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## A10: Server-Side Request Forgery (SSRF)
|
|
258
|
+
|
|
259
|
+
**Focus:** SSRF to internal services, cloud metadata.
|
|
260
|
+
|
|
261
|
+
```python
|
|
262
|
+
def test_ssrf_blocked(client):
|
|
263
|
+
internal_urls = [
|
|
264
|
+
"http://localhost/admin",
|
|
265
|
+
"http://169.254.169.254/latest/meta-data/",
|
|
266
|
+
"http://127.0.0.1:6379/",
|
|
267
|
+
]
|
|
268
|
+
for url in internal_urls:
|
|
269
|
+
r = client.get("/api/fetch", params={"url": url})
|
|
270
|
+
assert r.status_code in (400, 403, 422)
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
describe('A10 - SSRF', () => {
|
|
275
|
+
it('should block internal URL fetch', async () => {
|
|
276
|
+
const res = await request(app)
|
|
277
|
+
.get('/api/proxy?url=' + encodeURIComponent('http://169.254.169.254/'))
|
|
278
|
+
.expect(400);
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## Cross-Cutting: XSS (Reflected, Stored, DOM)
|
|
286
|
+
|
|
287
|
+
### Stored XSS
|
|
288
|
+
|
|
289
|
+
```python
|
|
290
|
+
def test_stored_xss_blocked(client, auth_headers):
|
|
291
|
+
payload = "<img src=x onerror=alert(1)>"
|
|
292
|
+
r = client.post("/api/comments", json={"body": payload}, headers=auth_headers)
|
|
293
|
+
assert r.status_code in (200, 201)
|
|
294
|
+
r2 = client.get("/api/comments")
|
|
295
|
+
assert payload not in r2.text
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### DOM XSS (Playwright)
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
it('should not execute DOM XSS in hash', async () => {
|
|
302
|
+
const page = await browser.newPage();
|
|
303
|
+
const dialogSpy = page.waitForEvent('dialog');
|
|
304
|
+
await page.goto('/search#' + encodeURIComponent('<img src=x onerror=alert(1)>'));
|
|
305
|
+
await expect(dialogSpy).rejects.toThrow(/timeout/);
|
|
306
|
+
});
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## Cross-Cutting: CSRF
|
|
312
|
+
|
|
313
|
+
```typescript
|
|
314
|
+
describe('CSRF', () => {
|
|
315
|
+
it('should require CSRF token for state-changing requests', async () => {
|
|
316
|
+
const res = await request(app)
|
|
317
|
+
.post('/api/transfer')
|
|
318
|
+
.set('Origin', 'https://evil.com')
|
|
319
|
+
.send({ to: 'attacker', amount: 1000 });
|
|
320
|
+
expect(res.status).toBe(403);
|
|
321
|
+
});
|
|
322
|
+
});
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## References
|
|
328
|
+
|
|
329
|
+
- [OWASP Top 10 2021](https://owasp.org/Top10/)
|
|
330
|
+
- [OWASP WSTG](https://owasp.org/www-project-web-security-testing-guide/)
|
|
331
|
+
- [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/)
|