@gpzhang2001/sharpkit-skills 0.2.1
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 +201 -0
- package/README.md +12 -0
- package/THIRD_PARTY_NOTICES.md +48 -0
- package/lib/index.d.ts +2027 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +70 -0
- package/lib/index.js.map +1 -0
- package/package.json +46 -0
- package/skills/analysis/counterevidence.md +185 -0
- package/skills/analysis/fix_verification.md +129 -0
- package/skills/analysis/severity_calibration.md +130 -0
- package/skills/analysis/source_aware_discovery.md +211 -0
- package/skills/cloud/aws.md +231 -0
- package/skills/cloud/azure.md +262 -0
- package/skills/cloud/gcp.md +194 -0
- package/skills/cloud/kubernetes.md +223 -0
- package/skills/coordination/root_agent.md +105 -0
- package/skills/coordination/source_aware_whitebox.md +47 -0
- package/skills/custom/api_spec_testing.md +61 -0
- package/skills/custom/dependency_cve_scanning.md +341 -0
- package/skills/custom/npx_confusion.md +233 -0
- package/skills/custom/source_aware_sast.md +192 -0
- package/skills/frameworks/django.md +214 -0
- package/skills/frameworks/fastapi.md +191 -0
- package/skills/frameworks/nestjs.md +225 -0
- package/skills/frameworks/nextjs.md +228 -0
- package/skills/protocols/graphql.md +276 -0
- package/skills/protocols/oauth.md +185 -0
- package/skills/reconnaissance/asset_discovery.md +150 -0
- package/skills/reconnaissance/infrastructure_lifecycle.md +226 -0
- package/skills/scan_modes/deep.md +164 -0
- package/skills/scan_modes/diff.md +86 -0
- package/skills/scan_modes/quick.md +68 -0
- package/skills/scan_modes/standard.md +99 -0
- package/skills/technologies/active_directory.md +233 -0
- package/skills/technologies/auth0.md +188 -0
- package/skills/technologies/electron_desktop_apps.md +181 -0
- package/skills/technologies/firebase.md +263 -0
- package/skills/technologies/grafana_prometheus.md +189 -0
- package/skills/technologies/llm_applications.md +257 -0
- package/skills/technologies/supabase.md +268 -0
- package/skills/tooling/agent_browser.md +551 -0
- package/skills/tooling/ffuf.md +72 -0
- package/skills/tooling/httpx.md +82 -0
- package/skills/tooling/hurl.md +99 -0
- package/skills/tooling/hypothesis.md +100 -0
- package/skills/tooling/katana.md +102 -0
- package/skills/tooling/naabu.md +68 -0
- package/skills/tooling/nmap.md +66 -0
- package/skills/tooling/nuclei.md +67 -0
- package/skills/tooling/python.md +109 -0
- package/skills/tooling/semgrep.md +72 -0
- package/skills/tooling/sqlmap.md +67 -0
- package/skills/tooling/subfinder.md +66 -0
- package/skills/vulnerabilities/agentic_system_security.md +207 -0
- package/skills/vulnerabilities/argument_injection.md +157 -0
- package/skills/vulnerabilities/authentication_jwt.md +166 -0
- package/skills/vulnerabilities/broken_function_level_authorization.md +154 -0
- package/skills/vulnerabilities/browser_security.md +192 -0
- package/skills/vulnerabilities/business_logic.md +178 -0
- package/skills/vulnerabilities/csrf.md +198 -0
- package/skills/vulnerabilities/header_injection.md +216 -0
- package/skills/vulnerabilities/http_request_smuggling.md +255 -0
- package/skills/vulnerabilities/idor.md +217 -0
- package/skills/vulnerabilities/information_disclosure.md +187 -0
- package/skills/vulnerabilities/insecure_deserialization.md +210 -0
- package/skills/vulnerabilities/insecure_file_uploads.md +194 -0
- package/skills/vulnerabilities/llm_prompt_injection.md +187 -0
- package/skills/vulnerabilities/mass_assignment.md +153 -0
- package/skills/vulnerabilities/nosql_injection.md +288 -0
- package/skills/vulnerabilities/open_redirect.md +165 -0
- package/skills/vulnerabilities/path_traversal_lfi_rfi.md +218 -0
- package/skills/vulnerabilities/prototype_pollution.md +142 -0
- package/skills/vulnerabilities/race_conditions.md +181 -0
- package/skills/vulnerabilities/rce.md +250 -0
- package/skills/vulnerabilities/semantic_confusion.md +189 -0
- package/skills/vulnerabilities/sql_injection.md +190 -0
- package/skills/vulnerabilities/ssrf.md +186 -0
- package/skills/vulnerabilities/ssti.md +270 -0
- package/skills/vulnerabilities/subdomain_takeover.md +167 -0
- package/skills/vulnerabilities/weak_password_detection.md +200 -0
- package/skills/vulnerabilities/xss.md +206 -0
- package/skills/vulnerabilities/xxe.md +223 -0
- package/src/index.ts +89 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: source-aware-sast
|
|
3
|
+
description: Practical source-aware SAST and AST playbook for semgrep, ast-grep, gitleaks, and trivy fs
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Source-Aware SAST Playbook
|
|
7
|
+
|
|
8
|
+
Use this skill for source-heavy analysis where static and structural signals should guide dynamic testing.
|
|
9
|
+
|
|
10
|
+
## Fast Start
|
|
11
|
+
|
|
12
|
+
Run tools from repo root and store outputs in a dedicated artifact directory:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
mkdir -p /workspace/.source-aware
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Baseline Coverage Bundle (Recommended)
|
|
19
|
+
|
|
20
|
+
Run this baseline once per repository before deep narrowing:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
ART=/workspace/.source-aware
|
|
24
|
+
mkdir -p "$ART"
|
|
25
|
+
|
|
26
|
+
semgrep scan --config p/default --config p/golang --config p/secrets \
|
|
27
|
+
--metrics=off --json --output "$ART/semgrep.json" .
|
|
28
|
+
# Build deterministic AST targets from semgrep scope (no hardcoded path guessing)
|
|
29
|
+
python3 - <<'PY'
|
|
30
|
+
import json
|
|
31
|
+
from pathlib import Path
|
|
32
|
+
|
|
33
|
+
art = Path("/workspace/.source-aware")
|
|
34
|
+
semgrep_json = art / "semgrep.json"
|
|
35
|
+
targets_file = art / "sg-targets.txt"
|
|
36
|
+
|
|
37
|
+
try:
|
|
38
|
+
data = json.loads(semgrep_json.read_text(encoding="utf-8"))
|
|
39
|
+
except Exception:
|
|
40
|
+
targets_file.write_text("", encoding="utf-8")
|
|
41
|
+
raise
|
|
42
|
+
|
|
43
|
+
scanned = data.get("paths", {}).get("scanned") or []
|
|
44
|
+
if not scanned:
|
|
45
|
+
scanned = sorted(
|
|
46
|
+
{
|
|
47
|
+
r.get("path")
|
|
48
|
+
for r in data.get("results", [])
|
|
49
|
+
if isinstance(r, dict) and isinstance(r.get("path"), str) and r.get("path")
|
|
50
|
+
}
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
bounded = scanned[:4000]
|
|
54
|
+
targets_file.write_text("".join(f"{p}\n" for p in bounded), encoding="utf-8")
|
|
55
|
+
print(f"sg-targets: {len(bounded)}")
|
|
56
|
+
PY
|
|
57
|
+
xargs -r -n 200 sg run --pattern '$F($$$ARGS)' --json=stream < "$ART/sg-targets.txt" \
|
|
58
|
+
> "$ART/ast-grep.json" 2> "$ART/ast-grep.log" || true
|
|
59
|
+
gitleaks detect --source . --report-format json --report-path "$ART/gitleaks.json" || true
|
|
60
|
+
trufflehog filesystem --no-update --json --no-verification . > "$ART/trufflehog.json" || true
|
|
61
|
+
# Keep trivy focused on vuln/misconfig (secrets already covered above) and increase timeout for large repos
|
|
62
|
+
trivy fs --scanners vuln,misconfig --timeout 30m --offline-scan \
|
|
63
|
+
--format json --output "$ART/trivy-fs.json" . || true
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Semgrep First Pass
|
|
67
|
+
|
|
68
|
+
Use Semgrep as the default static triage pass:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# Preferred deterministic profile set (works with --metrics=off)
|
|
72
|
+
semgrep scan --config p/default --config p/golang --config p/secrets \
|
|
73
|
+
--metrics=off --json --output /workspace/.source-aware/semgrep.json .
|
|
74
|
+
|
|
75
|
+
# If you choose auto config, do not combine it with --metrics=off
|
|
76
|
+
semgrep scan --config auto --json --output /workspace/.source-aware/semgrep-auto.json .
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
If diff scope is active, restrict to changed files first, then expand only when needed.
|
|
80
|
+
|
|
81
|
+
## AST-Grep Structural Mapping
|
|
82
|
+
|
|
83
|
+
Use `sg` for structure-aware code hunting:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
# Ruleless structural pass over deterministic target list (no sgconfig.yml required)
|
|
87
|
+
xargs -r -n 200 sg run --pattern '$F($$$ARGS)' --json=stream \
|
|
88
|
+
< /workspace/.source-aware/sg-targets.txt \
|
|
89
|
+
> /workspace/.source-aware/ast-grep.json 2> /workspace/.source-aware/ast-grep.log || true
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Target high-value patterns such as:
|
|
93
|
+
- missing auth checks near route handlers
|
|
94
|
+
- dynamic command/query construction
|
|
95
|
+
- unsafe deserialization or template execution paths
|
|
96
|
+
- file and path operations influenced by user input
|
|
97
|
+
|
|
98
|
+
## Tree-Sitter Assisted Repo Mapping
|
|
99
|
+
|
|
100
|
+
Use tree-sitter CLI for syntax-aware parsing when grep-level mapping is noisy:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
tree-sitter parse -q <file>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Use outputs to improve route/symbol/sink maps for subsequent targeted scans.
|
|
107
|
+
|
|
108
|
+
## Cross-Component Semantic Mapping
|
|
109
|
+
|
|
110
|
+
Pattern scanners find local sinks but often miss a security decision in one component followed by a different interpretation in another. For complex middleware, proxies, frameworks, and plugin systems:
|
|
111
|
+
|
|
112
|
+
1. Identify shared request/context fields and every writer/reader.
|
|
113
|
+
2. Order the readers and writers by lifecycle phase: parse, route, authenticate, rewrite, authorize, dispatch, render.
|
|
114
|
+
3. Mark fields whose semantic type changes (URL/path, MIME/handler, alias/package, external/internal route).
|
|
115
|
+
4. Trace normal, error, retry, subrequest, and internal-redirect paths separately.
|
|
116
|
+
5. Compare the representation checked by security code with the representation consumed by the final sink.
|
|
117
|
+
|
|
118
|
+
Load `semantic_confusion` when this graph reveals overloaded fields, multiple parsers, normalization steps, or protocol translation.
|
|
119
|
+
|
|
120
|
+
## Resolution and Namespace Risks
|
|
121
|
+
|
|
122
|
+
In repositories with developer tooling, plugins, templates, or package runners, inspect lookup order rather than only dependency versions:
|
|
123
|
+
|
|
124
|
+
- command runners that fall back from local binaries or `PATH` to a public registry
|
|
125
|
+
- scoped/private package names exposing unscoped binary or alias names
|
|
126
|
+
- plugin, template, module, and autoload search paths writable by a lower-privileged actor
|
|
127
|
+
- CI/composite actions and devcontainer/bootstrap scripts that transitively execute package commands
|
|
128
|
+
- missing local artifacts that silently activate a remote or broader fallback
|
|
129
|
+
|
|
130
|
+
Record candidate names and verify ownership/existence without claiming or publishing them. A namespace gap is reportable only when the target actually resolves or executes the attacker-contestable name under realistic conditions.
|
|
131
|
+
|
|
132
|
+
For npm/JavaScript, distinguish the package name from the executable name and
|
|
133
|
+
model the actual working directory, dependency tree, global bin directory,
|
|
134
|
+
cache, and registry configuration. `load_skill(["npx_confusion"])` when a bare
|
|
135
|
+
`npx`/`npm exec` command may fall back from a missing executable to a public
|
|
136
|
+
package. Trivy cannot detect this class because no installed package version
|
|
137
|
+
needs to be vulnerable.
|
|
138
|
+
|
|
139
|
+
Load `infrastructure_lifecycle` when source, images, firmware, or history contain abandoned domains, provider resources, package namespaces, update URLs, mail identities, telemetry, or control endpoints. Use targeted string/dataflow analysis when this is the research question; the full baseline scanner bundle is not required merely to trace one endpoint consumer.
|
|
140
|
+
|
|
141
|
+
## Secret and Supply Chain Coverage
|
|
142
|
+
|
|
143
|
+
Detect hardcoded credentials:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
gitleaks detect --source . --report-format json --report-path /workspace/.source-aware/gitleaks.json
|
|
147
|
+
trufflehog filesystem --json . > /workspace/.source-aware/trufflehog.json
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Run repository-wide dependency and config checks:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
trivy fs --scanners vuln,misconfig --timeout 30m --offline-scan \
|
|
154
|
+
--format json --output /workspace/.source-aware/trivy-fs.json . || true
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Known-CVE dependency findings are the one exception to the "report only after
|
|
158
|
+
dynamic validation" rule below: report each one with `create_dependency_report`
|
|
159
|
+
(not `create_vulnerability_report`), setting `advisory_cvss` from the published
|
|
160
|
+
advisory. `load_skill(["dependency_cve_scanning"])` for the full SCA workflow.
|
|
161
|
+
|
|
162
|
+
## JavaScript-Side Coverage
|
|
163
|
+
|
|
164
|
+
For frontends and Node services, layer these on top of the language-agnostic
|
|
165
|
+
passes above:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
retire --path . --outputformat json --outputpath /workspace/.source-aware/retire.json || true
|
|
169
|
+
eslint --no-config-lookup --rule '{"no-eval":2,"no-implied-eval":2}' \
|
|
170
|
+
-f json -o /workspace/.source-aware/eslint.json . || true
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
When you hit a minified bundle, run `js-beautify <file>` for a readable
|
|
174
|
+
view before greppping — and use `jshint --reporter=unix <file>` as a
|
|
175
|
+
lighter syntax/anti-pattern check when ESLint is over-eager. The
|
|
176
|
+
`JS-Snooper` / `jsniper.sh` tools (in `katana.md`) are the right next
|
|
177
|
+
step to mine those bundles for endpoint candidates.
|
|
178
|
+
|
|
179
|
+
## Converting Static Signals Into Exploits
|
|
180
|
+
|
|
181
|
+
When source contains model-provider SDKs, prompt templates, retrieval/vector stores, tool/function calling, model loading, training/feedback pipelines, or token/agent-loop accounting, load `llm_applications`. Use its OWASP 2026 LLM01-LLM10 map to trace data provenance, model output, retrieval authorization, tool authority, and resource multipliers rather than treating the provider call as the sink.
|
|
182
|
+
|
|
183
|
+
1. Rank candidates by impact and exploitability.
|
|
184
|
+
2. Trace source-to-sink flow for top candidates.
|
|
185
|
+
3. Build dynamic PoCs that reproduce the suspected issue.
|
|
186
|
+
4. Report only after dynamic validation succeeds.
|
|
187
|
+
|
|
188
|
+
## Anti-Patterns
|
|
189
|
+
|
|
190
|
+
- Do not treat scanner output as final truth.
|
|
191
|
+
- Do not spend full cycles on low-signal pattern matches.
|
|
192
|
+
- Do not report source-only findings without validation evidence.
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: django
|
|
3
|
+
description: Security testing playbook for Django applications covering ORM injection, middleware gaps, auth/session flaws, and template issues
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Django
|
|
7
|
+
|
|
8
|
+
Security testing for Django web applications and Django REST Framework (DRF) APIs. Focus on ORM/raw query misuse, middleware ordering, permission class gaps, and session/auth configuration across views, admin, and channels.
|
|
9
|
+
|
|
10
|
+
## Attack Surface
|
|
11
|
+
|
|
12
|
+
**Core Components**
|
|
13
|
+
- URL routing (`urls.py`), class-based and function views, middleware stack
|
|
14
|
+
- ORM (QuerySet filters), raw SQL, `extra()`, `RawSQL`, annotations
|
|
15
|
+
- Templates (Django template language, Jinja2 if configured)
|
|
16
|
+
- Forms, ModelForms, serializers (DRF)
|
|
17
|
+
|
|
18
|
+
**Authentication**
|
|
19
|
+
- Session framework, `AuthenticationMiddleware`, `@login_required`, DRF `permission_classes`
|
|
20
|
+
- Token auth, JWT (djangorestframework-simplejwt), OAuth integrations
|
|
21
|
+
- Django admin (`/admin/`), staff/superuser flags
|
|
22
|
+
|
|
23
|
+
**Deployment**
|
|
24
|
+
- `DEBUG=True` exposure, `ALLOWED_HOSTS`, `SECRET_KEY` leakage
|
|
25
|
+
- Static/media serving, reverse proxies, ASGI (Channels, Daphne, Uvicorn)
|
|
26
|
+
|
|
27
|
+
## High-Value Targets
|
|
28
|
+
|
|
29
|
+
- `/admin/` — brute force, credential stuffing, IDOR on admin objects
|
|
30
|
+
- API endpoints with mixed permission classes across ViewSets
|
|
31
|
+
- File upload (`FileField`, `ImageField`), import/export (django-import-export)
|
|
32
|
+
- Search/filter endpoints using `filter()`, `Q` objects, or raw SQL
|
|
33
|
+
- Password reset, email verification, invitation tokens
|
|
34
|
+
- WebSocket consumers (Django Channels) with weaker auth than HTTP equivalents
|
|
35
|
+
- Celery task triggers accepting user IDs without ownership checks
|
|
36
|
+
|
|
37
|
+
## Reconnaissance
|
|
38
|
+
|
|
39
|
+
**Fingerprinting**
|
|
40
|
+
```
|
|
41
|
+
curl -I https://target/ -H "Cookie: sessionid=test"
|
|
42
|
+
# X-Frame-Options, Set-Cookie (sessionid, csrftoken), Server header
|
|
43
|
+
GET /admin/login/
|
|
44
|
+
GET /api/ /api/v1/ /swagger/ /api/schema/
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Settings Leakage (when DEBUG=True or misconfigured)**
|
|
48
|
+
- Yellow debug page exposes `SECRET_KEY`, database credentials, installed apps
|
|
49
|
+
- `/static/`, error pages with stack traces revealing paths and ORM queries
|
|
50
|
+
|
|
51
|
+
**OpenAPI / DRF**
|
|
52
|
+
```
|
|
53
|
+
GET /api/schema/
|
|
54
|
+
GET /swagger.json
|
|
55
|
+
```
|
|
56
|
+
Map endpoints, authentication classes, and permission classes per route.
|
|
57
|
+
|
|
58
|
+
## Key Vulnerabilities
|
|
59
|
+
|
|
60
|
+
### Authentication & Authorization
|
|
61
|
+
|
|
62
|
+
**Permission Class Gaps**
|
|
63
|
+
- ViewSet with `list` protected but `retrieve`/`update` missing `permission_classes`
|
|
64
|
+
- Custom permissions checking authentication but not object ownership (IDOR)
|
|
65
|
+
- `@api_view` without explicit permissions inheriting permissive defaults
|
|
66
|
+
- Admin actions or custom management commands without staff checks
|
|
67
|
+
|
|
68
|
+
**Session Issues**
|
|
69
|
+
- `SESSION_COOKIE_SECURE=False` on HTTPS sites; missing `HttpOnly`
|
|
70
|
+
- Session fixation if session key not rotated on login
|
|
71
|
+
- Weak or leaked `SECRET_KEY` → forge session cookies (`django.contrib.sessions.backends.signed_cookies`)
|
|
72
|
+
|
|
73
|
+
**JWT (simplejwt)**
|
|
74
|
+
- RS256→HS256 confusion if algorithm pinning is misconfigured
|
|
75
|
+
- Missing `user_id`/`token` blacklist on logout
|
|
76
|
+
- Refresh token rotation not enforced
|
|
77
|
+
|
|
78
|
+
### Injection
|
|
79
|
+
|
|
80
|
+
**ORM SQL Injection**
|
|
81
|
+
Vulnerable patterns (more common in legacy code):
|
|
82
|
+
```python
|
|
83
|
+
User.objects.raw(f"SELECT * FROM auth_user WHERE username = '{user_input}'")
|
|
84
|
+
User.objects.extra(where=[f"username = '{user_input}'"])
|
|
85
|
+
```
|
|
86
|
+
Test: `' OR 1=1 --`, time-based payloads, database-specific syntax.
|
|
87
|
+
|
|
88
|
+
**DRF Filter Backends**
|
|
89
|
+
- `django-filter` with unsafe field exposure: `?username__icontains=` on unintended columns
|
|
90
|
+
- Ordering injection via `?ordering=` if field whitelist missing
|
|
91
|
+
|
|
92
|
+
**Template Injection**
|
|
93
|
+
Django templates auto-escape by default; risk rises with:
|
|
94
|
+
```python
|
|
95
|
+
mark_safe(user_input)
|
|
96
|
+
|safe filter in templates
|
|
97
|
+
Template(user_input).render(...) # SSTI if user controls template source
|
|
98
|
+
```
|
|
99
|
+
Jinja2 backend without autoescape: `{{7*7}}`, RCE gadgets if sandbox misconfigured.
|
|
100
|
+
|
|
101
|
+
### CSRF
|
|
102
|
+
|
|
103
|
+
- `@csrf_exempt` on state-changing views
|
|
104
|
+
- DRF session authentication without CSRF enforcement on unsafe methods
|
|
105
|
+
- CSRF cookie not set (`CSRF_USE_SESSIONS`, trusted origins misconfiguration)
|
|
106
|
+
- `CSRF_TRUSTED_ORIGINS` too broad
|
|
107
|
+
|
|
108
|
+
**Test:** Cross-origin POST with victim session cookie; JSON endpoints with session auth.
|
|
109
|
+
|
|
110
|
+
### IDOR and Mass Assignment
|
|
111
|
+
|
|
112
|
+
**DRF Serializers**
|
|
113
|
+
- `fields = '__all__'` exposing `is_staff`, `is_superuser`, `role`, `balance`
|
|
114
|
+
- `read_only_fields` missing on sensitive ModelSerializer fields
|
|
115
|
+
- Nested writes updating foreign keys across tenants
|
|
116
|
+
|
|
117
|
+
**Object-Level Permissions**
|
|
118
|
+
- `get_object()` without filtering queryset by request.user
|
|
119
|
+
- Generic views with `queryset = Model.objects.all()` and weak permissions
|
|
120
|
+
|
|
121
|
+
### File Handling
|
|
122
|
+
|
|
123
|
+
- `MEDIA_ROOT` served directly in DEBUG or via misconfigured nginx
|
|
124
|
+
- Path traversal in custom file download views using user-supplied paths
|
|
125
|
+
- SVG/HTML uploads served with `Content-Type` that enables XSS
|
|
126
|
+
- Missing file size/type validation on uploads
|
|
127
|
+
|
|
128
|
+
### SSRF
|
|
129
|
+
|
|
130
|
+
- `requests.get(user_url)` in webhooks, preview, import features
|
|
131
|
+
- Celery tasks fetching user URLs server-side
|
|
132
|
+
- Test loopback, metadata IPs, redirect chains
|
|
133
|
+
|
|
134
|
+
### Host Header / Password Reset
|
|
135
|
+
|
|
136
|
+
- `ALLOWED_HOSTS = ['*']` or permissive subdomain patterns
|
|
137
|
+
- Password reset emails built from `Host` header → poisoned reset links
|
|
138
|
+
- Cache poisoning via unkeyed Host header on cached pages
|
|
139
|
+
|
|
140
|
+
### Django Admin
|
|
141
|
+
|
|
142
|
+
- Default `/admin/` path with weak credentials
|
|
143
|
+
- `has_add_permission` / `has_change_permission` overrides with logic bugs
|
|
144
|
+
- ModelAdmin exposing sensitive fields in list_display or export
|
|
145
|
+
|
|
146
|
+
### Channels / WebSocket
|
|
147
|
+
|
|
148
|
+
- Consumer accepts connection without session/auth parity to HTTP
|
|
149
|
+
- Group name derived from user input → subscribe to other users' channels
|
|
150
|
+
- Missing origin validation on WebSocket handshake
|
|
151
|
+
|
|
152
|
+
## Bypass Techniques
|
|
153
|
+
|
|
154
|
+
- Content negotiation: JSON vs form data hitting different parser/permission paths
|
|
155
|
+
- HTTP method override or trailing slash routing to alternate view
|
|
156
|
+
- Parameter pollution: duplicate `id` fields in query and body
|
|
157
|
+
- Race on state transitions (coupon redemption, inventory) via parallel requests
|
|
158
|
+
- Versioned API (`/api/v1/` vs `/api/v2/`) with weaker auth on older version
|
|
159
|
+
|
|
160
|
+
## Testing Methodology
|
|
161
|
+
|
|
162
|
+
1. **Map surface** — URLs, DRF schema, admin, static/media paths
|
|
163
|
+
2. **Auth matrix** — Unauthenticated/user/staff for each endpoint and method
|
|
164
|
+
3. **Object ownership** — Swap IDs across two user accounts on every CRUD route
|
|
165
|
+
4. **Serializer audit** — Identify writable sensitive fields and nested relations
|
|
166
|
+
5. **Middleware order** — Confirm auth runs before business logic; check CSRF on session APIs
|
|
167
|
+
6. **Channel parity** — Same authorization on WebSocket actions as REST equivalents
|
|
168
|
+
7. **Settings review (white-box)** — DEBUG, ALLOWED_HOSTS, SECRET_KEY, session/cookie flags
|
|
169
|
+
|
|
170
|
+
## Validation
|
|
171
|
+
|
|
172
|
+
1. Side-by-side requests proving unauthorized access (IDOR, privilege escalation)
|
|
173
|
+
2. CSRF PoC executing state change with victim session (for session-authenticated endpoints)
|
|
174
|
+
3. SQLi/template injection with deterministic oracle (error, timing, or `7*7` equivalent)
|
|
175
|
+
4. Document view/serializer/permission class where enforcement failed
|
|
176
|
+
5. Show admin or staff capability gained from regular user context if applicable
|
|
177
|
+
|
|
178
|
+
## False Positives
|
|
179
|
+
|
|
180
|
+
- `queryset.filter(user=request.user)` consistently applied including nested routes
|
|
181
|
+
- Object-level permission class correctly validates ownership on all actions
|
|
182
|
+
- DEBUG=False and generic error pages with no settings leakage confirmed
|
|
183
|
+
- Mark_safe used only on server-generated trusted content
|
|
184
|
+
- CSRF correctly enforced on all session-authenticated unsafe methods
|
|
185
|
+
|
|
186
|
+
## Impact
|
|
187
|
+
|
|
188
|
+
- Account takeover via session forgery or password reset poisoning
|
|
189
|
+
- Horizontal/vertical privilege escalation through IDOR and mass assignment
|
|
190
|
+
- Data breach via ORM/SQL injection or excessive serializer fields
|
|
191
|
+
- Server compromise via SSTI, pickle in cache (if used), or SSRF to internal services
|
|
192
|
+
|
|
193
|
+
## Pro Tips
|
|
194
|
+
|
|
195
|
+
1. DRF ViewSets often protect `list` but forget `destroy` or custom `@action` routes
|
|
196
|
+
2. Check `APIView` subclasses for missing `permission_classes` — common oversight
|
|
197
|
+
3. Test `?format=` and browsable API HTML responses for CSRF on session auth
|
|
198
|
+
4. `django.contrib.admin` uses separate auth — don't assume API auth covers admin
|
|
199
|
+
5. Compare ASGI WebSocket consumers against REST permissions for the same resource
|
|
200
|
+
|
|
201
|
+
## Tooling
|
|
202
|
+
|
|
203
|
+
Static analysis is the fastest way to reach the sinks above in white-box scope. The sandbox ships `python`/`pipx`, `semgrep`, `bandit`, `ast-grep`, and `ripgrep`.
|
|
204
|
+
|
|
205
|
+
- **bandit** (preinstalled) — Python security linter; flags `mark_safe`, `extra()`, `RawSQL`, `subprocess`, weak crypto, hardcoded secrets: `bandit -r . -ll`
|
|
206
|
+
- **semgrep** (preinstalled) with the Django ruleset — higher-signal than bandit for framework-specific bugs (`.extra()`, `RawSQL`, `|safe`, `csrf_exempt`, `ALLOWED_HOSTS=['*']`): `semgrep --config p/django .`
|
|
207
|
+
- **pip-audit** (PyPA) — dependency CVE scanner for known-vuln Django/DRF/simplejwt versions: `pipx install pip-audit && pip-audit -r requirements.txt`
|
|
208
|
+
- **ast-grep** (preinstalled) — quick structural grep for risky calls without a full SAST run: `ast-grep run -p 'mark_safe($X)' -l python`
|
|
209
|
+
|
|
210
|
+
For the `SECRET_KEY` → signed-cookie/reset-token forgery path noted under Session Issues, Django's own `django.core.signing` is the "tool": with a leaked key you can mint valid `signing.dumps()` values (session cookies, password-reset tokens, and `PickleSerializer`-backed session RCE).
|
|
211
|
+
|
|
212
|
+
## Summary
|
|
213
|
+
|
|
214
|
+
Django's defaults help (CSRF middleware, template auto-escape) but DRF, raw SQL, custom permissions, and deployment settings introduce frequent gaps. Test every endpoint with role-separated principals and verify object-level enforcement on querysets, not just authentication presence.
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fastapi
|
|
3
|
+
description: Security testing playbook for FastAPI applications covering ASGI, dependency injection, and API vulnerabilities
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# FastAPI
|
|
7
|
+
|
|
8
|
+
Security testing for FastAPI/Starlette applications. Focus on dependency injection flaws, middleware gaps, and authorization drift across routers and channels.
|
|
9
|
+
|
|
10
|
+
## Attack Surface
|
|
11
|
+
|
|
12
|
+
**Core Components**
|
|
13
|
+
- ASGI middlewares: CORS, TrustedHost, ProxyHeaders, Session, exception handlers, lifespan events
|
|
14
|
+
- Routers and sub-apps: APIRouter prefixes/tags, mounted apps (StaticFiles, admin), `include_router`, versioned paths
|
|
15
|
+
- Dependency injection: `Depends`, `Security`, `OAuth2PasswordBearer`, `HTTPBearer`, scopes
|
|
16
|
+
|
|
17
|
+
**Data Handling**
|
|
18
|
+
- Pydantic models: v1/v2, unions/Annotated, custom validators, extra fields policy, coercion
|
|
19
|
+
- File operations: UploadFile, File, FileResponse, StaticFiles mounts
|
|
20
|
+
- Templates: Jinja2Templates rendering
|
|
21
|
+
|
|
22
|
+
**Channels**
|
|
23
|
+
- HTTP (sync/async), WebSocket, SSE/StreamingResponse
|
|
24
|
+
- BackgroundTasks and task queues
|
|
25
|
+
|
|
26
|
+
**Deployment**
|
|
27
|
+
- Uvicorn/Gunicorn, reverse proxies/CDN, TLS termination, header trust
|
|
28
|
+
|
|
29
|
+
## High-Value Targets
|
|
30
|
+
|
|
31
|
+
- `/openapi.json`, `/docs`, `/redoc` in production (full attack surface map, securitySchemes, server URLs)
|
|
32
|
+
- Auth flows: token endpoints, session/cookie bridges, OAuth device/PKCE
|
|
33
|
+
- Admin/staff routers, feature-flagged routes, `include_in_schema=False` endpoints
|
|
34
|
+
- File upload/download, import/export/report endpoints, signed URL generators
|
|
35
|
+
- WebSocket endpoints (notifications, admin channels, commands)
|
|
36
|
+
- Background job endpoints (`/jobs/{id}`, `/tasks/{id}/result`)
|
|
37
|
+
- Mounted subapps (admin UI, storage browsers, metrics/health)
|
|
38
|
+
|
|
39
|
+
## Reconnaissance
|
|
40
|
+
|
|
41
|
+
**OpenAPI Mining**
|
|
42
|
+
```
|
|
43
|
+
GET /openapi.json
|
|
44
|
+
GET /docs
|
|
45
|
+
GET /redoc
|
|
46
|
+
GET /api/openapi.json
|
|
47
|
+
GET /internal/openapi.json
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Extract: paths, parameters, securitySchemes, scopes, servers. Endpoints with `include_in_schema=False` won't appear—fuzz based on discovered prefixes and common admin/debug names.
|
|
51
|
+
|
|
52
|
+
**Dependency Mapping**
|
|
53
|
+
|
|
54
|
+
For each route, identify:
|
|
55
|
+
- Router-level dependencies (applied to all routes)
|
|
56
|
+
- Route-level dependencies (per endpoint)
|
|
57
|
+
- Which dependencies enforce auth vs just parse input
|
|
58
|
+
|
|
59
|
+
## Key Vulnerabilities
|
|
60
|
+
|
|
61
|
+
### Authentication & Authorization
|
|
62
|
+
|
|
63
|
+
**Dependency Injection Gaps**
|
|
64
|
+
- Routes missing security dependencies present on other routes
|
|
65
|
+
- `Depends` used instead of `Security` (ignores scope enforcement)
|
|
66
|
+
- Token presence treated as authentication without signature verification
|
|
67
|
+
- `OAuth2PasswordBearer` only yields a token string—verify routes don't treat presence as auth
|
|
68
|
+
|
|
69
|
+
**JWT Misuse**
|
|
70
|
+
- Decode without verify: test unsigned tokens, attacker-signed tokens
|
|
71
|
+
- Algorithm confusion: HS256/RS256 cross-use if not pinned
|
|
72
|
+
- `kid` header injection for custom key lookup paths
|
|
73
|
+
- Missing issuer/audience validation, cross-service token reuse
|
|
74
|
+
|
|
75
|
+
**Session Weaknesses**
|
|
76
|
+
- SessionMiddleware with weak `secret_key`
|
|
77
|
+
- Session fixation via predictable signing
|
|
78
|
+
- Cookie-based auth without CSRF protection
|
|
79
|
+
|
|
80
|
+
**OAuth/OIDC**
|
|
81
|
+
- Device/PKCE flows: verify strict PKCE S256 and state/nonce enforcement
|
|
82
|
+
|
|
83
|
+
### Access Control
|
|
84
|
+
|
|
85
|
+
**IDOR via Dependencies**
|
|
86
|
+
- Object IDs in path/query not validated against caller
|
|
87
|
+
- Tenant headers trusted without binding to authenticated user
|
|
88
|
+
- BackgroundTasks acting on IDs without re-validating ownership at execution time
|
|
89
|
+
- Export/import pipelines with IDOR and cross-tenant leaks
|
|
90
|
+
|
|
91
|
+
**Scope Bypass**
|
|
92
|
+
- Minimal scope satisfaction (any valid token accepted)
|
|
93
|
+
- Router vs route scope enforcement inconsistency
|
|
94
|
+
|
|
95
|
+
### Input Handling
|
|
96
|
+
|
|
97
|
+
**Pydantic Exploitation**
|
|
98
|
+
- Type coercion: strings to ints/bools, empty strings to None, truthiness edge cases
|
|
99
|
+
- Extra fields: `extra = "allow"` permits injecting control fields (role, ownerId, scope)
|
|
100
|
+
- Union types and `Annotated`: craft shapes hitting unintended validation branches
|
|
101
|
+
|
|
102
|
+
**Content-Type Switching**
|
|
103
|
+
```
|
|
104
|
+
application/json ↔ application/x-www-form-urlencoded ↔ multipart/form-data
|
|
105
|
+
```
|
|
106
|
+
Different content types hit different validators or code paths (parser differentials).
|
|
107
|
+
|
|
108
|
+
**Parameter Manipulation**
|
|
109
|
+
- Case variations in header/cookie names
|
|
110
|
+
- Duplicate parameters exploiting DI precedence
|
|
111
|
+
- Method override via `X-HTTP-Method-Override` (upstream respects, app doesn't)
|
|
112
|
+
|
|
113
|
+
### CORS & CSRF
|
|
114
|
+
|
|
115
|
+
**CORS Misconfiguration**
|
|
116
|
+
- Overly broad `allow_origin_regex`
|
|
117
|
+
- Origin reflection without validation
|
|
118
|
+
- Credentialed requests with permissive origins
|
|
119
|
+
- Verify preflight vs actual request deltas
|
|
120
|
+
|
|
121
|
+
**CSRF Exposure**
|
|
122
|
+
- No built-in CSRF in FastAPI/Starlette
|
|
123
|
+
- Cookie-based auth without origin validation
|
|
124
|
+
- Missing SameSite attribute
|
|
125
|
+
|
|
126
|
+
### Proxy & Host Trust
|
|
127
|
+
|
|
128
|
+
**Header Spoofing**
|
|
129
|
+
- ProxyHeadersMiddleware without network boundary: spoof `X-Forwarded-For/Proto` to influence auth/IP gating
|
|
130
|
+
- Absent TrustedHostMiddleware: Host header poisoning in password reset links, absolute URL generation
|
|
131
|
+
- Cache key confusion: missing Vary on Authorization/Cookie/Tenant
|
|
132
|
+
|
|
133
|
+
### Server-Side Vulnerabilities
|
|
134
|
+
|
|
135
|
+
**Template Injection (Jinja2)**
|
|
136
|
+
```python
|
|
137
|
+
{{7*7}} # Arithmetic confirmation
|
|
138
|
+
{{cycler.__init__.__globals__['os'].popen('id').read()}} # RCE
|
|
139
|
+
```
|
|
140
|
+
Check autoescape settings and custom filters/globals.
|
|
141
|
+
|
|
142
|
+
**SSRF**
|
|
143
|
+
- User-supplied URLs in imports, previews, webhooks validation
|
|
144
|
+
- Test: loopback, RFC1918, IPv6, redirects, DNS rebinding, header control
|
|
145
|
+
- Library behavior (httpx/requests): redirect policy, header forwarding, protocol support
|
|
146
|
+
- Protocol smuggling: `file://`, `ftp://`, gopher-like shims if custom clients
|
|
147
|
+
|
|
148
|
+
**File Upload**
|
|
149
|
+
- Path traversal in `UploadFile.filename` with control characters
|
|
150
|
+
- Missing storage root enforcement, symlink following
|
|
151
|
+
- Vary filename encodings, dot segments, NUL-like bytes
|
|
152
|
+
- Verify storage paths and served URLs
|
|
153
|
+
|
|
154
|
+
### WebSocket Security
|
|
155
|
+
|
|
156
|
+
- Missing per-connection authentication
|
|
157
|
+
- Cross-origin WebSocket without origin validation
|
|
158
|
+
- Topic/channel IDOR (subscribing to other users' channels)
|
|
159
|
+
- Authorization only at handshake, not per-message
|
|
160
|
+
|
|
161
|
+
### Mounted Apps
|
|
162
|
+
|
|
163
|
+
Sub-apps at `/admin`, `/static`, `/metrics` may bypass global middlewares. Verify auth enforcement parity across all mounts.
|
|
164
|
+
|
|
165
|
+
### Alternative Stacks
|
|
166
|
+
|
|
167
|
+
- If GraphQL (Strawberry/Graphene) is mounted: validate resolver-level authorization, IDOR on node/global IDs
|
|
168
|
+
- If SQLModel/SQLAlchemy present: probe for raw query usage and row-level authorization gaps
|
|
169
|
+
|
|
170
|
+
## Bypass Techniques
|
|
171
|
+
|
|
172
|
+
- Content-type switching to traverse alternate validators
|
|
173
|
+
- Parameter duplication and case variants exploiting DI precedence
|
|
174
|
+
- Method confusion via proxies (`X-HTTP-Method-Override`)
|
|
175
|
+
- Race windows around dependency-validated state transitions (issue token then mutate with parallel requests)
|
|
176
|
+
|
|
177
|
+
## Testing Methodology
|
|
178
|
+
|
|
179
|
+
1. **Enumerate** - Fetch OpenAPI, diff with 404-fuzzing for hidden endpoints
|
|
180
|
+
2. **Matrix testing** - Test each route across: unauth/user/admin × HTTP/WebSocket × JSON/form/multipart
|
|
181
|
+
3. **Dependency analysis** - Map which dependencies enforce auth vs parse input
|
|
182
|
+
4. **Cross-environment** - Compare dev/stage/prod for middleware and docs exposure differences
|
|
183
|
+
5. **Channel consistency** - Verify same authorization on HTTP and WebSocket for equivalent operations
|
|
184
|
+
|
|
185
|
+
## Validation Requirements
|
|
186
|
+
|
|
187
|
+
- Side-by-side requests showing unauthorized access (owner vs non-owner, cross-tenant)
|
|
188
|
+
- Cross-channel proof (HTTP and WebSocket for same rule)
|
|
189
|
+
- Header/proxy manipulation showing altered outcomes (Host/XFF/CORS)
|
|
190
|
+
- Minimal payloads for template injection, SSRF, token misuse with safe/OAST oracles
|
|
191
|
+
- Document exact dependency paths (router-level, route-level) that missed enforcement
|