strix-agent 0.1.18__py3-none-any.whl → 0.1.19__py3-none-any.whl
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.
Potentially problematic release.
This version of strix-agent might be problematic. Click here for more details.
- strix/agents/StrixAgent/strix_agent.py +2 -1
- strix/agents/StrixAgent/system_prompt.jinja +8 -10
- strix/agents/base_agent.py +20 -0
- strix/agents/state.py +18 -1
- strix/cli/app.py +92 -15
- strix/cli/main.py +3 -2
- strix/cli/tool_components/base_renderer.py +2 -2
- strix/cli/tool_components/reporting_renderer.py +2 -1
- strix/prompts/README.md +64 -0
- strix/prompts/__init__.py +1 -1
- strix/prompts/cloud/.gitkeep +0 -0
- strix/prompts/custom/.gitkeep +0 -0
- strix/prompts/frameworks/fastapi.jinja +142 -0
- strix/prompts/frameworks/nextjs.jinja +126 -0
- strix/prompts/protocols/graphql.jinja +215 -0
- strix/prompts/reconnaissance/.gitkeep +0 -0
- strix/prompts/technologies/firebase_firestore.jinja +177 -0
- strix/prompts/technologies/supabase.jinja +189 -0
- strix/prompts/vulnerabilities/authentication_jwt.jinja +133 -115
- strix/prompts/vulnerabilities/broken_function_level_authorization.jinja +146 -0
- strix/prompts/vulnerabilities/business_logic.jinja +146 -118
- strix/prompts/vulnerabilities/csrf.jinja +137 -131
- strix/prompts/vulnerabilities/idor.jinja +149 -118
- strix/prompts/vulnerabilities/insecure_file_uploads.jinja +188 -0
- strix/prompts/vulnerabilities/mass_assignment.jinja +141 -0
- strix/prompts/vulnerabilities/path_traversal_lfi_rfi.jinja +142 -0
- strix/prompts/vulnerabilities/race_conditions.jinja +135 -165
- strix/prompts/vulnerabilities/rce.jinja +128 -180
- strix/prompts/vulnerabilities/sql_injection.jinja +128 -192
- strix/prompts/vulnerabilities/ssrf.jinja +118 -151
- strix/prompts/vulnerabilities/xss.jinja +144 -196
- strix/prompts/vulnerabilities/xxe.jinja +151 -243
- strix/tools/agents_graph/agents_graph_actions.py +4 -3
- strix/tools/agents_graph/agents_graph_actions_schema.xml +10 -14
- strix/tools/registry.py +1 -1
- {strix_agent-0.1.18.dist-info → strix_agent-0.1.19.dist-info}/METADATA +52 -13
- {strix_agent-0.1.18.dist-info → strix_agent-0.1.19.dist-info}/RECORD +40 -27
- {strix_agent-0.1.18.dist-info → strix_agent-0.1.19.dist-info}/LICENSE +0 -0
- {strix_agent-0.1.18.dist-info → strix_agent-0.1.19.dist-info}/WHEEL +0 -0
- {strix_agent-0.1.18.dist-info → strix_agent-0.1.19.dist-info}/entry_points.txt +0 -0
|
@@ -1,164 +1,195 @@
|
|
|
1
1
|
<idor_vulnerability_guide>
|
|
2
|
-
<title>INSECURE DIRECT OBJECT REFERENCE (IDOR)
|
|
2
|
+
<title>INSECURE DIRECT OBJECT REFERENCE (IDOR)</title>
|
|
3
3
|
|
|
4
|
-
<critical>
|
|
4
|
+
<critical>Object- and function-level authorization failures (BOLA/IDOR) routinely 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.</critical>
|
|
5
|
+
|
|
6
|
+
<scope>
|
|
7
|
+
- Horizontal access: access another subject's objects of the same type
|
|
8
|
+
- Vertical access: access privileged objects/actions (admin-only, staff-only)
|
|
9
|
+
- Cross-tenant access: break isolation boundaries in multi-tenant systems
|
|
10
|
+
- Cross-service access: token or context accepted by the wrong service
|
|
11
|
+
</scope>
|
|
12
|
+
|
|
13
|
+
<methodology>
|
|
14
|
+
1. Build a Subject × Object × Action matrix (who can do what to which resource).
|
|
15
|
+
2. For each resource type, obtain at least two principals: owner and non-owner (plus admin/staff if applicable). Capture at least one valid object ID per principal.
|
|
16
|
+
3. Exercise every action (R/W/D/Export) while swapping IDs, tokens, tenants, and channels (web, mobile, API, GraphQL, WebSocket, gRPC).
|
|
17
|
+
4. Track consistency: the same rule must hold regardless of transport, content-type, serialization, or gateway.
|
|
18
|
+
</methodology>
|
|
5
19
|
|
|
6
20
|
<discovery_techniques>
|
|
7
21
|
<parameter_analysis>
|
|
8
|
-
-
|
|
9
|
-
- UUID/
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
- Object references in: URLs, POST bodies, headers, cookies, JWT tokens
|
|
22
|
+
- Object references appear in: paths, query params, JSON bodies, form-data, headers, cookies, JWT claims, GraphQL arguments, WebSocket messages, gRPC messages
|
|
23
|
+
- Identifier forms: integers, UUID/ULID/CUID, Snowflake, slugs, composite keys (e.g., {orgId}:{userId}), opaque tokens, base64/hex-encoded blobs
|
|
24
|
+
- Relationship references: parentId, ownerId, accountId, tenantId, organization, teamId, projectId, subscriptionId
|
|
25
|
+
- Expansion/projection knobs: fields, include, expand, projection, with, select, populate (often bypass authorization in resolvers or serializers)
|
|
26
|
+
- Pagination/cursors: page[offset], page[limit], cursor, nextPageToken (often reveal or accept cross-tenant/state)
|
|
14
27
|
</parameter_analysis>
|
|
15
28
|
|
|
16
29
|
<advanced_enumeration>
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
30
|
+
- Alternate types: {% raw %}{"id":123}{% endraw} vs {% raw %}{"id":"123"}{% endraw}, arrays vs scalars, objects vs scalars, null/empty/0/-1/MAX_INT, scientific notation, overflows, unknown attributes retained by backend
|
|
31
|
+
- Duplicate keys/parameter pollution: id=1&id=2, JSON duplicate keys {% raw %}{"id":1,"id":2}{% endraw} (parser precedence differences)
|
|
32
|
+
- Case/aliasing: userId vs userid vs USER_ID; alt names like resourceId, targetId, account
|
|
33
|
+
- Path traversal-like in virtual file systems: /files/user_123/../../user_456/report.csv
|
|
34
|
+
- Directory/list endpoints as seeders: search/list/suggest/export often leak object IDs for secondary exploitation
|
|
22
35
|
</advanced_enumeration>
|
|
23
36
|
</discovery_techniques>
|
|
24
37
|
|
|
25
38
|
<high_value_targets>
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
- Backup files
|
|
35
|
-
- Debug information
|
|
39
|
+
- Exports/backups/reporting endpoints (CSV/PDF/ZIP)
|
|
40
|
+
- Messaging/mailbox/notifications, audit logs, activity feeds
|
|
41
|
+
- Billing: invoices, payment methods, transactions, credits
|
|
42
|
+
- Healthcare/education records, HR documents, PII/PHI/PCI
|
|
43
|
+
- Admin/staff tools, impersonation/session management
|
|
44
|
+
- File/object storage keys (S3/GCS signed URLs, share links)
|
|
45
|
+
- Background jobs: import/export job IDs, task results
|
|
46
|
+
- Multi-tenant resources: organizations, workspaces, projects
|
|
36
47
|
</high_value_targets>
|
|
37
48
|
|
|
38
49
|
<exploitation_techniques>
|
|
39
|
-
<
|
|
40
|
-
|
|
41
|
-
/
|
|
42
|
-
|
|
43
|
-
</direct_access>
|
|
44
|
-
|
|
45
|
-
<mass_enumeration>
|
|
46
|
-
Automate ID ranges:
|
|
47
|
-
for i in range(1, 10000):
|
|
48
|
-
/api/user/{i}/data
|
|
49
|
-
</mass_enumeration>
|
|
50
|
-
|
|
51
|
-
<type_confusion>
|
|
52
|
-
- String where int expected: "123" vs 123
|
|
53
|
-
- Array where single value expected: [123] vs 123
|
|
54
|
-
- Object injection: {% raw %}{"id": {"$ne": null}}{% endraw %}
|
|
55
|
-
</type_confusion>
|
|
56
|
-
</exploitation_techniques>
|
|
50
|
+
<horizontal_vertical>
|
|
51
|
+
- Swap object IDs between principals using the same token to probe horizontal access; then repeat with lower-privilege tokens to probe vertical access
|
|
52
|
+
- Target partial updates (PATCH, JSON Patch/JSON Merge Patch) for silent unauthorized modifications
|
|
53
|
+
</horizontal_vertical>
|
|
57
54
|
|
|
58
|
-
<
|
|
59
|
-
|
|
60
|
-
-
|
|
61
|
-
|
|
62
|
-
- Sequential UUID generation
|
|
63
|
-
</uuid_prediction>
|
|
64
|
-
|
|
65
|
-
<blind_idor>
|
|
66
|
-
- Side channel: response time, size differences
|
|
67
|
-
- Error message variations
|
|
68
|
-
- Boolean-based: exists vs not exists
|
|
69
|
-
</blind_idor>
|
|
55
|
+
<bulk_and_batch>
|
|
56
|
+
- Batch endpoints (bulk update/delete) often validate only the first element; include cross-tenant IDs mid-array
|
|
57
|
+
- CSV/JSON imports referencing foreign object IDs (ownerId, orgId) may bypass create-time checks
|
|
58
|
+
</bulk_and_batch>
|
|
70
59
|
|
|
71
60
|
<secondary_idor>
|
|
72
|
-
|
|
73
|
-
/
|
|
74
|
-
/api/user/789/private-data
|
|
61
|
+
- Use list/search endpoints, notifications, emails, webhooks, and client logs to collect valid IDs, then fetch or mutate those objects directly
|
|
62
|
+
- Pagination/cursor manipulation to skip filters and pull other users' pages
|
|
75
63
|
</secondary_idor>
|
|
64
|
+
|
|
65
|
+
<job_task_objects>
|
|
66
|
+
- Access job/task IDs from one user to retrieve results for another (export/{jobId}/download, reports/{taskId})
|
|
67
|
+
- Cancel/approve someone else's jobs by referencing their task IDs
|
|
68
|
+
</job_task_objects>
|
|
69
|
+
|
|
70
|
+
<file_object_storage>
|
|
71
|
+
- Direct object paths or weakly scoped signed URLs; attempt key prefix changes, content-disposition tricks, or stale signatures reused across tenants
|
|
72
|
+
- Replace share tokens with tokens from other tenants; try case/URL-encoding variations
|
|
73
|
+
</file_object_storage>
|
|
74
|
+
</exploitation_techniques>
|
|
75
|
+
|
|
76
|
+
<advanced_techniques>
|
|
77
|
+
<graphql>
|
|
78
|
+
- Enforce resolver-level checks: do not rely on a top-level gate. Verify field and edge resolvers bind the resource to the caller on every hop
|
|
79
|
+
- Abuse batching/aliases to retrieve multiple users' nodes in one request and compare responses
|
|
80
|
+
- Global node patterns (Relay): decode base64 IDs and swap raw IDs; test {% raw %}node(id: "...base64..."){...}{% endraw %}
|
|
81
|
+
- Overfetching via fragments on privileged types; verify hidden fields cannot be queried by unprivileged callers
|
|
82
|
+
- Example:
|
|
83
|
+
{% raw %}
|
|
84
|
+
query IDOR {
|
|
85
|
+
me { id }
|
|
86
|
+
u1: user(id: "VXNlcjo0NTY=") { email billing { last4 } }
|
|
87
|
+
u2: node(id: "VXNlcjo0NTc=") { ... on User { email } }
|
|
88
|
+
}
|
|
89
|
+
{% endraw %}
|
|
90
|
+
</graphql>
|
|
91
|
+
|
|
92
|
+
<microservices_gateways>
|
|
93
|
+
- Token confusion: a token scoped for Service A accepted by Service B due to shared JWT verification but missing audience/claims checks
|
|
94
|
+
- Trust on headers: reverse proxies or API gateways injecting/trusting headers like X-User-Id, X-Organization-Id; try overriding or removing them
|
|
95
|
+
- Context loss: async consumers (queues, workers) re-process requests without re-checking authorization
|
|
96
|
+
</microservices_gateways>
|
|
97
|
+
|
|
98
|
+
<multi_tenant>
|
|
99
|
+
- Probe tenant scoping through headers, subdomains, and path params (e.g., X-Tenant-ID, org slug). Try mixing org of token with resource from another org
|
|
100
|
+
- Test cross-tenant reports/analytics rollups and admin views which aggregate multiple tenants
|
|
101
|
+
</multi_tenant>
|
|
102
|
+
|
|
103
|
+
<uuid_and_opaque_ids>
|
|
104
|
+
- UUID/ULID are not authorization: acquire valid IDs from logs, exports, JS bundles, analytics endpoints, emails, or public activity, then test ownership binding
|
|
105
|
+
- Time-based IDs (UUIDv1, ULID) may be guessable within a window; combine with leakage sources for targeted access
|
|
106
|
+
</uuid_and_opaque_ids>
|
|
107
|
+
|
|
108
|
+
<blind_channels>
|
|
109
|
+
- Use differential responses (status, size, ETag, timing) to detect existence; error shape often differs for owned vs foreign objects
|
|
110
|
+
- HEAD/OPTIONS, conditional requests (If-None-Match/If-Modified-Since) can confirm existence without full content
|
|
111
|
+
</blind_channels>
|
|
76
112
|
</advanced_techniques>
|
|
77
113
|
|
|
78
114
|
<bypass_techniques>
|
|
115
|
+
<parser_and_transport>
|
|
116
|
+
- Content-type switching: application/json ↔ application/x-www-form-urlencoded ↔ multipart/form-data; some paths enforce checks per parser
|
|
117
|
+
- Method tunneling: X-HTTP-Method-Override, _method=PATCH; or using GET on endpoints incorrectly accepting state changes
|
|
118
|
+
- JSON duplicate keys/array injection to bypass naive validators
|
|
119
|
+
</parser_and_transport>
|
|
120
|
+
|
|
79
121
|
<parameter_pollution>
|
|
80
|
-
|
|
81
|
-
|
|
122
|
+
- Duplicate parameters in query/body to influence server-side precedence (id=123&id=456); try both orderings
|
|
123
|
+
- Mix case/alias param names so gateway and backend disagree (userId vs userid)
|
|
82
124
|
</parameter_pollution>
|
|
83
125
|
|
|
84
|
-
<
|
|
85
|
-
-
|
|
86
|
-
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
</case_variation>
|
|
93
|
-
|
|
94
|
-
<format_switching>
|
|
95
|
-
/api/user.json?id=123
|
|
96
|
-
/api/user.xml?id=123
|
|
97
|
-
/api/user/123.json vs /api/user/123
|
|
98
|
-
</format_switching>
|
|
126
|
+
<cache_and_gateway>
|
|
127
|
+
- CDN/proxy key confusion: responses keyed without Authorization or tenant headers expose cached objects to other users; manipulate Vary and Accept
|
|
128
|
+
- Redirect chains and 304/206 behaviors can leak content across tenants
|
|
129
|
+
</cache_and_gateway>
|
|
130
|
+
|
|
131
|
+
<race_windows>
|
|
132
|
+
- Time-of-check vs time-of-use: change the referenced ID between validation and execution using parallel requests
|
|
133
|
+
</race_windows>
|
|
99
134
|
</bypass_techniques>
|
|
100
135
|
|
|
101
136
|
<special_contexts>
|
|
102
|
-
<
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
</
|
|
106
|
-
|
|
107
|
-
<
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
</file_path_idor>
|
|
137
|
+
<websocket>
|
|
138
|
+
- Authorization per-subscription: ensure channel/topic names cannot be guessed (user_{id}, org_{id}); subscribe/publish checks must run server-side, not only at handshake
|
|
139
|
+
- Try sending messages with target user IDs after subscribing to own channels
|
|
140
|
+
</websocket>
|
|
141
|
+
|
|
142
|
+
<grpc>
|
|
143
|
+
- Direct protobuf fields (owner_id, tenant_id) often bypass HTTP-layer middleware; validate references via grpcurl with tokens from different principals
|
|
144
|
+
</grpc>
|
|
145
|
+
|
|
146
|
+
<integrations>
|
|
147
|
+
- Webhooks/callbacks referencing foreign objects (e.g., invoice_id) processed without verifying ownership
|
|
148
|
+
- Third-party importers syncing data into wrong tenant due to missing tenant binding
|
|
149
|
+
</integrations>
|
|
116
150
|
</special_contexts>
|
|
117
151
|
|
|
118
152
|
<chaining_attacks>
|
|
119
|
-
- IDOR +
|
|
120
|
-
- IDOR +
|
|
121
|
-
- IDOR +
|
|
153
|
+
- IDOR + CSRF: force victims to trigger unauthorized changes on objects you discovered
|
|
154
|
+
- IDOR + Stored XSS: pivot into other users' sessions through data you gained access to
|
|
155
|
+
- IDOR + SSRF: exfiltrate internal IDs, then access their corresponding resources
|
|
156
|
+
- IDOR + Race: bypass spot checks with simultaneous requests
|
|
122
157
|
</chaining_attacks>
|
|
123
158
|
|
|
124
159
|
<validation>
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
5. Document security impact
|
|
160
|
+
1. Demonstrate access to an object not owned by the caller (content or metadata).
|
|
161
|
+
2. Show the same request fails with appropriately enforced authorization when corrected.
|
|
162
|
+
3. Prove cross-channel consistency: same unauthorized access via at least two transports (e.g., REST and GraphQL).
|
|
163
|
+
4. Document tenant boundary violations (if applicable).
|
|
164
|
+
5. Provide reproducible steps and evidence (requests/responses for owner vs non-owner).
|
|
131
165
|
</validation>
|
|
132
166
|
|
|
133
167
|
<false_positives>
|
|
134
|
-
|
|
135
|
-
-
|
|
136
|
-
-
|
|
137
|
-
-
|
|
138
|
-
- Rate limiting prevents exploitation
|
|
139
|
-
- Data is sanitized/limited
|
|
168
|
+
- Public/anonymous resources by design
|
|
169
|
+
- Soft-privatized data where content is already public
|
|
170
|
+
- Idempotent metadata lookups that do not reveal sensitive content
|
|
171
|
+
- Correct row-level checks enforced across all channels
|
|
140
172
|
</false_positives>
|
|
141
173
|
|
|
142
174
|
<impact>
|
|
143
|
-
-
|
|
144
|
-
-
|
|
145
|
-
-
|
|
146
|
-
-
|
|
147
|
-
- Compliance violations (GDPR, HIPAA)
|
|
175
|
+
- Cross-account data exposure (PII/PHI/PCI)
|
|
176
|
+
- Unauthorized state changes (transfers, role changes, cancellations)
|
|
177
|
+
- Cross-tenant data leaks violating contractual and regulatory boundaries
|
|
178
|
+
- Regulatory risk (GDPR/HIPAA/PCI), fraud, reputational damage
|
|
148
179
|
</impact>
|
|
149
180
|
|
|
150
181
|
<pro_tips>
|
|
151
|
-
1.
|
|
152
|
-
2.
|
|
153
|
-
3.
|
|
154
|
-
4.
|
|
155
|
-
5.
|
|
156
|
-
6. Check
|
|
157
|
-
7.
|
|
158
|
-
8.
|
|
159
|
-
9.
|
|
160
|
-
10.
|
|
182
|
+
1. Always test list/search/export endpoints first; they are rich ID seeders.
|
|
183
|
+
2. Build a reusable ID corpus from logs, notifications, emails, and client bundles.
|
|
184
|
+
3. Toggle content-types and transports; authorization middleware often differs per stack.
|
|
185
|
+
4. In GraphQL, validate at resolver boundaries; never trust parent auth to cover children.
|
|
186
|
+
5. In multi-tenant apps, vary org headers, subdomains, and path params independently.
|
|
187
|
+
6. Check batch/bulk operations and background job endpoints; they frequently skip per-item checks.
|
|
188
|
+
7. Inspect gateways for header trust and cache key configuration.
|
|
189
|
+
8. Treat UUIDs as untrusted; obtain them via OSINT/leaks and test binding.
|
|
190
|
+
9. Use timing/size/ETag differentials for blind confirmation when content is masked.
|
|
191
|
+
10. Prove impact with precise before/after diffs and role-separated evidence.
|
|
161
192
|
</pro_tips>
|
|
162
193
|
|
|
163
|
-
<remember>
|
|
194
|
+
<remember>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.</remember>
|
|
164
195
|
</idor_vulnerability_guide>
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
<insecure_file_uploads_guide>
|
|
2
|
+
<title>INSECURE FILE UPLOADS</title>
|
|
3
|
+
|
|
4
|
+
<critical>Upload surfaces are high risk: server-side execution (RCE), stored XSS, malware distribution, storage takeover, and DoS. Modern stacks mix direct-to-cloud uploads, background processors, and CDNs—authorization and validation must hold across every step.</critical>
|
|
5
|
+
|
|
6
|
+
<scope>
|
|
7
|
+
- Web/mobile/API uploads, direct-to-cloud (S3/GCS/Azure) presigned flows, resumable/multipart protocols (tus, S3 MPU)
|
|
8
|
+
- Image/document/media pipelines (ImageMagick/GraphicsMagick, Ghostscript, ExifTool, PDF engines, office converters)
|
|
9
|
+
- Admin/bulk importers, archive uploads (zip/tar), report/template uploads, rich text with attachments
|
|
10
|
+
- Serving paths: app directly, object storage, CDN, email attachments, previews/thumbnails
|
|
11
|
+
</scope>
|
|
12
|
+
|
|
13
|
+
<methodology>
|
|
14
|
+
1. Map the pipeline: client → ingress (edge/app/gateway) → storage → processors (thumb, OCR, AV, CDR) → serving (app/storage/CDN). Note where validation and auth occur.
|
|
15
|
+
2. Identify allowed types, size limits, filename rules, storage keys, and who serves the content. Collect baseline uploads per type and capture resulting URLs and headers.
|
|
16
|
+
3. Exercise bypass families systematically: extension games, MIME/content-type, magic bytes, polyglots, metadata payloads, archive structure, chunk/finalize differentials.
|
|
17
|
+
4. Validate execution and rendering: can uploaded content execute on server or client? Confirm with minimal PoCs and headers analysis.
|
|
18
|
+
</methodology>
|
|
19
|
+
|
|
20
|
+
<discovery_techniques>
|
|
21
|
+
<surface_map>
|
|
22
|
+
- Endpoints/fields: upload, file, avatar, image, attachment, import, media, document, template
|
|
23
|
+
- Direct-to-cloud params: key, bucket, acl, Content-Type, Content-Disposition, x-amz-meta-*, cache-control
|
|
24
|
+
- Resumable APIs: create/init → upload/chunk → complete/finalize; check if metadata/headers can be altered late
|
|
25
|
+
- Background processors: thumbnails, PDF→image, virus scan queues; identify timing and status transitions
|
|
26
|
+
</surface_map>
|
|
27
|
+
|
|
28
|
+
<capability_probes>
|
|
29
|
+
- Small probe files of each claimed type; diff resulting Content-Type, Content-Disposition, and X-Content-Type-Options on download
|
|
30
|
+
- Magic bytes vs extension: JPEG/GIF/PNG headers; mismatches reveal reliance on extension or MIME sniffing
|
|
31
|
+
- SVG/HTML probe: do they render inline (text/html or image/svg+xml) or download (attachment)?
|
|
32
|
+
- Archive probe: simple zip with nested path traversal entries and symlinks to detect extraction rules
|
|
33
|
+
</capability_probes>
|
|
34
|
+
</discovery_techniques>
|
|
35
|
+
|
|
36
|
+
<detection_channels>
|
|
37
|
+
<server_execution>
|
|
38
|
+
- Web shell execution (language dependent), config/handler uploads (.htaccess, .user.ini, web.config) enabling execution
|
|
39
|
+
- Interpreter-side template/script evaluation during conversion (ImageMagick/Ghostscript/ExifTool)
|
|
40
|
+
</server_execution>
|
|
41
|
+
|
|
42
|
+
<client_execution>
|
|
43
|
+
- Stored XSS via SVG/HTML/JS if served inline without correct headers; PDF JavaScript; office macros in previewers
|
|
44
|
+
</client_execution>
|
|
45
|
+
|
|
46
|
+
<header_and_render>
|
|
47
|
+
- Missing X-Content-Type-Options: nosniff enabling browser sniff to script
|
|
48
|
+
- Content-Type reflection from upload vs server-set; Content-Disposition: inline vs attachment
|
|
49
|
+
</header_and_render>
|
|
50
|
+
|
|
51
|
+
<process_side_effects>
|
|
52
|
+
- AV/CDR race or absence; background job status allows access before scan completes; password-protected archives bypass scanning
|
|
53
|
+
</process_side_effects>
|
|
54
|
+
</detection_channels>
|
|
55
|
+
|
|
56
|
+
<core_payloads>
|
|
57
|
+
<web_shells_and_configs>
|
|
58
|
+
- PHP: GIF polyglot (starts with GIF89a) followed by <?php echo 1; ?>; place where PHP is executed
|
|
59
|
+
- .htaccess to map extensions to code (AddType/AddHandler); .user.ini (auto_prepend/append_file) for PHP-FPM
|
|
60
|
+
- ASP/JSP equivalents where supported; IIS web.config to enable script execution
|
|
61
|
+
</web_shells_and_configs>
|
|
62
|
+
|
|
63
|
+
<stored_xss>
|
|
64
|
+
- SVG with onload/onerror handlers served as image/svg+xml or text/html
|
|
65
|
+
- HTML file with script when served as text/html or sniffed due to missing nosniff
|
|
66
|
+
</stored_xss>
|
|
67
|
+
|
|
68
|
+
<mime_magic_polyglots>
|
|
69
|
+
- Double extensions: avatar.jpg.php, report.pdf.html; mixed casing: .pHp, .PhAr
|
|
70
|
+
- Magic-byte spoofing: valid JPEG header then embedded script; verify server uses content inspection, not extensions alone
|
|
71
|
+
</mime_magic_polyglots>
|
|
72
|
+
|
|
73
|
+
<archive_attacks>
|
|
74
|
+
- Zip Slip: entries with ../../ to escape extraction dir; symlink-in-zip pointing outside target; nested zips
|
|
75
|
+
- Zip bomb: extreme compression ratios (e.g., 42.zip) to exhaust resources in processors
|
|
76
|
+
</archive_attacks>
|
|
77
|
+
|
|
78
|
+
<toolchain_exploits>
|
|
79
|
+
- ImageMagick/GraphicsMagick legacy vectors (policy.xml may mitigate): crafted SVG/PS/EPS invoking external commands or reading files
|
|
80
|
+
- Ghostscript in PDF/PS with file operators (%pipe%)
|
|
81
|
+
- ExifTool metadata parsing bugs; overly large or crafted EXIF/IPTC/XMP fields
|
|
82
|
+
</toolchain_exploits>
|
|
83
|
+
|
|
84
|
+
<cloud_storage_vectors>
|
|
85
|
+
- S3/GCS presigned uploads: attacker controls Content-Type/Disposition; set text/html or image/svg+xml and inline rendering
|
|
86
|
+
- Public-read ACL or permissive bucket policies expose uploads broadly; object key injection via user-controlled path prefixes
|
|
87
|
+
- Signed URL reuse and stale URLs; serving directly from bucket without attachment + nosniff headers
|
|
88
|
+
</cloud_storage_vectors>
|
|
89
|
+
</core_payloads>
|
|
90
|
+
|
|
91
|
+
<advanced_techniques>
|
|
92
|
+
<resumable_multipart>
|
|
93
|
+
- Change metadata between init and complete (e.g., swap Content-Type/Disposition at finalize)
|
|
94
|
+
- Upload benign chunks, then swap last chunk or complete with different source if server trusts client-side digests only
|
|
95
|
+
</resumable_multipart>
|
|
96
|
+
|
|
97
|
+
<filename_and_path>
|
|
98
|
+
- Unicode homoglyphs, trailing dots/spaces, device names, reserved characters to bypass validators and filesystem rules
|
|
99
|
+
- Null-byte truncation on legacy stacks; overlong paths; case-insensitive collisions overwriting existing files
|
|
100
|
+
</filename_and_path>
|
|
101
|
+
|
|
102
|
+
<processing_races>
|
|
103
|
+
- Request file immediately after upload but before AV/CDR completes; or during derivative creation to get unprocessed content
|
|
104
|
+
- Trigger heavy conversions (large images, deep PDFs) to widen race windows
|
|
105
|
+
</processing_races>
|
|
106
|
+
|
|
107
|
+
<metadata_abuse>
|
|
108
|
+
- Oversized EXIF/XMP/IPTC blocks to trigger parser flaws; payloads in document properties of Office/PDF rendered by previewers
|
|
109
|
+
</metadata_abuse>
|
|
110
|
+
|
|
111
|
+
<header_manipulation>
|
|
112
|
+
- Force inline rendering with Content-Type + inline Content-Disposition; test browsers with and without nosniff
|
|
113
|
+
- Cache poisoning via CDN with keys missing Vary on Content-Type/Disposition
|
|
114
|
+
</header_manipulation>
|
|
115
|
+
</advanced_techniques>
|
|
116
|
+
|
|
117
|
+
<filter_bypasses>
|
|
118
|
+
<validation_gaps>
|
|
119
|
+
- Client-side only checks; relying on JS/MIME provided by browser; trusting multipart boundary part headers blindly
|
|
120
|
+
- Extension allowlists without server-side content inspection; magic-bytes only without full parsing
|
|
121
|
+
</validation_gaps>
|
|
122
|
+
|
|
123
|
+
<evasion_tricks>
|
|
124
|
+
- Double extensions, mixed case, hidden dotfiles, extra dots (file..png), long paths with allowed suffix
|
|
125
|
+
- Multipart name vs filename vs path discrepancies; duplicate parameters and late parameter precedence
|
|
126
|
+
</evasion_tricks>
|
|
127
|
+
</filter_bypasses>
|
|
128
|
+
|
|
129
|
+
<special_contexts>
|
|
130
|
+
<rich_text_editors>
|
|
131
|
+
- RTEs allow image/attachment uploads and embed links; verify sanitization and serving headers for embedded content
|
|
132
|
+
</rich_text_editors>
|
|
133
|
+
|
|
134
|
+
<mobile_clients>
|
|
135
|
+
- Mobile SDKs may send nonstandard MIME or metadata; servers sometimes trust client-side transformations or EXIF orientation
|
|
136
|
+
</mobile_clients>
|
|
137
|
+
|
|
138
|
+
<serverless_and_cdn>
|
|
139
|
+
- Direct-to-bucket uploads with Lambda/Workers post-processing; verify that security decisions are not delegated to frontends
|
|
140
|
+
- CDN caching of uploaded content; ensure correct cache keys and headers (attachment, nosniff)
|
|
141
|
+
</serverless_and_cdn>
|
|
142
|
+
</special_contexts>
|
|
143
|
+
|
|
144
|
+
<parser_hardening>
|
|
145
|
+
- Validate on server: strict allowlist by true type (parse enough to confirm), size caps, and structural checks (dimensions, page count)
|
|
146
|
+
- Strip active content: convert SVG→PNG; remove scripts/JS from PDF; disable macros; normalize EXIF; consider CDR for risky types
|
|
147
|
+
- Store outside web root; serve via application or signed, time-limited URLs with Content-Disposition: attachment and X-Content-Type-Options: nosniff
|
|
148
|
+
- For cloud: private buckets, per-request signed GET, enforce Content-Type/Disposition on GET responses from your app/gateway
|
|
149
|
+
- Disable execution in upload paths; ignore .htaccess/.user.ini; sanitize keys to prevent path injections; randomize filenames
|
|
150
|
+
- AV + CDR: scan synchronously when possible; quarantine until verdict; block password-protected archives or process in sandbox
|
|
151
|
+
</parser_hardening>
|
|
152
|
+
|
|
153
|
+
<validation>
|
|
154
|
+
1. Demonstrate execution or rendering of active content: web shell reachable, or SVG/HTML executing JS when viewed.
|
|
155
|
+
2. Show filter bypass: upload accepted despite restrictions (extension/MIME/magic mismatch) with evidence on retrieval.
|
|
156
|
+
3. Prove header weaknesses: inline rendering without nosniff or missing attachment; present exact response headers.
|
|
157
|
+
4. Show race or pipeline gap: access before AV/CDR; extraction outside intended directory; derivative creation from malicious input.
|
|
158
|
+
5. Provide reproducible steps: request/response for upload and subsequent access, with minimal PoCs.
|
|
159
|
+
</validation>
|
|
160
|
+
|
|
161
|
+
<false_positives>
|
|
162
|
+
- Upload stored but never served back; or always served as attachment with strict nosniff
|
|
163
|
+
- Converters run in locked-down sandboxes with no external IO and no script engines; no path traversal on archive extraction
|
|
164
|
+
- AV/CDR blocks the payload and quarantines; access before scan is impossible by design
|
|
165
|
+
</false_positives>
|
|
166
|
+
|
|
167
|
+
<impact>
|
|
168
|
+
- Remote code execution on application stack or media toolchain host
|
|
169
|
+
- Persistent cross-site scripting and session/token exfiltration via served uploads
|
|
170
|
+
- Malware distribution via public storage/CDN; brand/reputation damage
|
|
171
|
+
- Data loss or corruption via overwrite/zip slip; service degradation via zip bombs or oversized assets
|
|
172
|
+
</impact>
|
|
173
|
+
|
|
174
|
+
<pro_tips>
|
|
175
|
+
1. Keep PoCs minimal: tiny SVG/HTML for XSS, a single-line PHP/ASP where relevant, and benign magic-byte polyglots.
|
|
176
|
+
2. Always capture download response headers and final MIME from the server/CDN; that decides browser behavior.
|
|
177
|
+
3. Prefer transforming risky formats to safe renderings (SVG→PNG) rather than attempting complex sanitization.
|
|
178
|
+
4. In presigned flows, constrain all headers and object keys server-side; ignore client-supplied ACL and metadata.
|
|
179
|
+
5. For archives, extract in a chroot/jail with explicit allowlist; drop symlinks and reject traversal.
|
|
180
|
+
6. Test finalize/complete steps in resumable flows; many validations only run on init, not at completion.
|
|
181
|
+
7. Verify background processors with EICAR and tiny polyglots; ensure quarantine gates access until safe.
|
|
182
|
+
8. When you cannot get execution, aim for stored XSS or header-driven script execution; both are impactful.
|
|
183
|
+
9. Validate that CDNs honor attachment/nosniff and do not override Content-Type/Disposition.
|
|
184
|
+
10. Document full pipeline behavior per asset type; defenses must match actual processors and serving paths.
|
|
185
|
+
</pro_tips>
|
|
186
|
+
|
|
187
|
+
<remember>Secure uploads are a pipeline property. Enforce strict type, size, and header controls; transform or strip active content; never execute or inline-render untrusted uploads; and keep storage private with controlled, signed access.</remember>
|
|
188
|
+
</insecure_file_uploads_guide>
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
<mass_assignment_guide>
|
|
2
|
+
<title>MASS ASSIGNMENT</title>
|
|
3
|
+
|
|
4
|
+
<critical>Mass assignment binds client-supplied fields directly into models/DTOs without field-level allowlists. It commonly leads to privilege escalation, ownership changes, and unauthorized state transitions in modern APIs and GraphQL.</critical>
|
|
5
|
+
|
|
6
|
+
<scope>
|
|
7
|
+
- REST/JSON, GraphQL inputs, form-encoded and multipart bodies
|
|
8
|
+
- Model binding in controllers/resolvers; ORM create/update helpers
|
|
9
|
+
- Writable nested relations, sparse/patch updates, bulk endpoints
|
|
10
|
+
</scope>
|
|
11
|
+
|
|
12
|
+
<methodology>
|
|
13
|
+
1. Identify create/update endpoints and GraphQL mutations. Capture full server responses to observe returned fields.
|
|
14
|
+
2. Build a candidate list of sensitive attributes per resource: role/isAdmin/permissions, ownerId/accountId/tenantId, status/state, plan/price, limits/quotas, feature flags, verification flags, balance/credits.
|
|
15
|
+
3. Inject candidates alongside legitimate updates across transports and encodings; compare before/after state and diffs across roles.
|
|
16
|
+
4. Repeat with nested objects, arrays, and alternative shapes (dot/bracket notation, duplicate keys) and in batch operations.
|
|
17
|
+
</methodology>
|
|
18
|
+
|
|
19
|
+
<discovery_techniques>
|
|
20
|
+
<surface_map>
|
|
21
|
+
- Controllers with automatic binding (e.g., request.json → model); GraphQL input types mirroring models; admin/staff tools exposed via API
|
|
22
|
+
- OpenAPI/GraphQL schemas: uncover hidden fields or enums; SDKs often reveal writable fields
|
|
23
|
+
- Client bundles and mobile apps: inspect forms and mutation payloads for field names
|
|
24
|
+
</surface_map>
|
|
25
|
+
|
|
26
|
+
<parameter_strategies>
|
|
27
|
+
- Flat fields: isAdmin, role, roles[], permissions[], status, plan, tier, premium, verified, emailVerified
|
|
28
|
+
- Ownership/tenancy: userId, ownerId, accountId, organizationId, tenantId, workspaceId
|
|
29
|
+
- Limits/quotas: usageLimit, seatCount, maxProjects, creditBalance
|
|
30
|
+
- Feature flags/gates: features, flags, betaAccess, allowImpersonation
|
|
31
|
+
- Billing: price, amount, currency, prorate, nextInvoice, trialEnd
|
|
32
|
+
</parameter_strategies>
|
|
33
|
+
|
|
34
|
+
<shape_variants>
|
|
35
|
+
- Alternate shapes: arrays vs scalars; nested JSON; objects under unexpected keys
|
|
36
|
+
- Dot/bracket paths: profile.role, profile[role], settings[roles][]
|
|
37
|
+
- Duplicate keys and precedence: {"role":"user","role":"admin"}
|
|
38
|
+
- Sparse/patch formats: JSON Patch/JSON Merge Patch; try adding forbidden paths or replacing protected fields
|
|
39
|
+
</shape_variants>
|
|
40
|
+
|
|
41
|
+
<encodings_and_channels>
|
|
42
|
+
- Content-types: application/json, application/x-www-form-urlencoded, multipart/form-data, text/plain (JSON via server coercion)
|
|
43
|
+
- GraphQL: add suspicious fields to input objects; overfetch response to detect changes
|
|
44
|
+
- Batch/bulk: arrays of objects; verify per-item allowlists not skipped
|
|
45
|
+
</encodings_and_channels>
|
|
46
|
+
|
|
47
|
+
<exploitation_techniques>
|
|
48
|
+
<privilege_escalation>
|
|
49
|
+
- Set role/isAdmin/permissions during signup/profile update; toggle admin/staff flags where exposed
|
|
50
|
+
</privilege_escalation>
|
|
51
|
+
|
|
52
|
+
<ownership_takeover>
|
|
53
|
+
- Change ownerId/accountId/tenantId to seize resources; move objects across users/tenants
|
|
54
|
+
</ownership_takeover>
|
|
55
|
+
|
|
56
|
+
<feature_gate_bypass>
|
|
57
|
+
- Enable premium/beta/feature flags via flags/features fields; raise limits/seatCount/quotas
|
|
58
|
+
</feature_gate_bypass>
|
|
59
|
+
|
|
60
|
+
<billing_and_entitlements>
|
|
61
|
+
- Modify plan/price/prorate/trialEnd or creditBalance; bypass server recomputation
|
|
62
|
+
</billing_and_entitlements>
|
|
63
|
+
|
|
64
|
+
<nested_and_relation_writes>
|
|
65
|
+
- Writable nested serializers or ORM relations allow creating or linking related objects beyond caller’s scope (e.g., attach to another user’s org)
|
|
66
|
+
</nested_and_relation_writes>
|
|
67
|
+
|
|
68
|
+
<advanced_techniques>
|
|
69
|
+
<graphQL_specific>
|
|
70
|
+
- Field-level authz missing on input types: attempt forbidden fields in mutation inputs; combine with aliasing/batching to compare effects
|
|
71
|
+
- Use fragments to overfetch changed fields immediately after mutation
|
|
72
|
+
</graphQL_specific>
|
|
73
|
+
|
|
74
|
+
<orm_framework_edges>
|
|
75
|
+
- Rails: strong parameters misconfig or deep nesting via accepts_nested_attributes_for
|
|
76
|
+
- Laravel: $fillable/$guarded misuses; guarded=[] opens all; casts mutating hidden fields
|
|
77
|
+
- Django REST Framework: writable nested serializer, read_only/extra_kwargs gaps, partial updates
|
|
78
|
+
- Mongoose/Prisma: schema paths not filtered; select:false doesn’t prevent writes; upsert defaults
|
|
79
|
+
</orm_framework_edges>
|
|
80
|
+
|
|
81
|
+
<parser_and_validator_gaps>
|
|
82
|
+
- Validators run post-bind and do not cover extra fields; unknown fields silently dropped in response but persisted underneath
|
|
83
|
+
- Inconsistent allowlists between mobile/web/gateway; alt encodings bypass validation pipeline
|
|
84
|
+
</parser_and_validator_gaps>
|
|
85
|
+
|
|
86
|
+
<bypass_techniques>
|
|
87
|
+
<content_type_switching>
|
|
88
|
+
- Switch JSON ↔ form-encoded ↔ multipart ↔ text/plain; some code paths only validate one
|
|
89
|
+
</content_type_switching>
|
|
90
|
+
|
|
91
|
+
<key_path_variants>
|
|
92
|
+
- Dot/bracket/object re-shaping to reach nested fields through different binders
|
|
93
|
+
</key_path_variants>
|
|
94
|
+
|
|
95
|
+
<batch_paths>
|
|
96
|
+
- Per-item checks skipped in bulk operations; insert a single malicious object within a large batch
|
|
97
|
+
</batch_paths>
|
|
98
|
+
|
|
99
|
+
<race_and_reorder>
|
|
100
|
+
- Race two updates: first sets forbidden field, second normalizes; final state may retain forbidden change
|
|
101
|
+
</race_and_reorder>
|
|
102
|
+
|
|
103
|
+
<validation>
|
|
104
|
+
1. Show a minimal request where adding a sensitive field changes persisted state for a non-privileged caller.
|
|
105
|
+
2. Provide before/after evidence (response body, subsequent GET, or GraphQL query) proving the forbidden attribute value.
|
|
106
|
+
3. Demonstrate consistency across at least two encodings or channels.
|
|
107
|
+
4. For nested/bulk, show that protected fields are written within child objects or array elements.
|
|
108
|
+
5. Quantify impact (e.g., role flip, cross-tenant move, quota increase) and reproducibility.
|
|
109
|
+
</validation>
|
|
110
|
+
|
|
111
|
+
<false_positives>
|
|
112
|
+
- Server recomputes derived fields (plan/price/role) ignoring client input
|
|
113
|
+
- Fields marked read-only and enforced consistently across encodings
|
|
114
|
+
- Only UI-side changes with no persisted effect
|
|
115
|
+
</false_positives>
|
|
116
|
+
|
|
117
|
+
<impact>
|
|
118
|
+
- Privilege escalation and admin feature access
|
|
119
|
+
- Cross-tenant or cross-account resource takeover
|
|
120
|
+
- Financial/billing manipulation and quota abuse
|
|
121
|
+
- Policy/approval bypass by toggling verification or status flags
|
|
122
|
+
</impact>
|
|
123
|
+
|
|
124
|
+
<pro_tips>
|
|
125
|
+
1. Build a sensitive-field dictionary per resource and fuzz systematically.
|
|
126
|
+
2. Always try alternate shapes and encodings; many validators are shape/CT-specific.
|
|
127
|
+
3. For GraphQL, diff the resource immediately after mutation; effects are often visible even if the mutation returns filtered fields.
|
|
128
|
+
4. Inspect SDKs/mobile apps for hidden field names and nested write examples.
|
|
129
|
+
5. Prefer minimal PoCs that prove durable state changes; avoid UI-only effects.
|
|
130
|
+
</pro_tips>
|
|
131
|
+
|
|
132
|
+
<mitigations>
|
|
133
|
+
- Enforce server-side allowlists per operation and role; deny unknown fields by default
|
|
134
|
+
- Separate input DTOs from domain models; map explicitly
|
|
135
|
+
- Recompute derived fields (role/plan/owner) from trusted context; ignore client values
|
|
136
|
+
- Lock nested writes to owned resources; validate foreign keys against caller scope
|
|
137
|
+
- For GraphQL, use input types that expose only permitted fields and enforce resolver-level checks
|
|
138
|
+
</mitigations>
|
|
139
|
+
|
|
140
|
+
<remember>Mass assignment is eliminated by explicit mapping and per-field authorization. Treat every client-supplied attribute—especially nested or batch inputs—as untrusted until validated against an allowlist and caller scope.</remember>
|
|
141
|
+
</mass_assignment_guide>
|