mustflow 2.116.1 → 2.116.2
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/package.json +1 -1
- package/templates/default/i18n.toml +72 -6
- package/templates/default/locales/en/.mustflow/skills/INDEX.md +37 -11
- package/templates/default/locales/en/.mustflow/skills/compiler-engineering-review/SKILL.md +477 -0
- package/templates/default/locales/en/.mustflow/skills/compiler-engineering-review/references/compiler-diagnostics-abi-linker-checklist.md +778 -0
- package/templates/default/locales/en/.mustflow/skills/compiler-engineering-review/references/compiler-generators-properties-checklist.md +501 -0
- package/templates/default/locales/en/.mustflow/skills/compiler-engineering-review/references/compiler-test-strategy-differential-checklist.md +498 -0
- package/templates/default/locales/en/.mustflow/skills/compiler-engineering-review/references/debug-symbol-symbolication-checklist.md +412 -0
- package/templates/default/locales/en/.mustflow/skills/compiler-engineering-review/references/ir-design-ssa-pass-pipeline-checklist.md +759 -0
- package/templates/default/locales/en/.mustflow/skills/compiler-engineering-review/references/miscompile-reduction-ir-checklist.md +434 -0
- package/templates/default/locales/en/.mustflow/skills/cross-platform-filesystem-safety/SKILL.md +55 -36
- package/templates/default/locales/en/.mustflow/skills/cross-platform-filesystem-safety/references/path-containment-handle-checklist.md +251 -0
- package/templates/default/locales/en/.mustflow/skills/file-upload-security-review/SKILL.md +133 -32
- package/templates/default/locales/en/.mustflow/skills/file-upload-security-review/references/file-upload-parser-ssrf-resource-checklist.md +306 -0
- package/templates/default/locales/en/.mustflow/skills/formal-verification-review/SKILL.md +310 -0
- package/templates/default/locales/en/.mustflow/skills/formal-verification-review/references/formal-concurrency-model-checking-smt-checklist.md +457 -0
- package/templates/default/locales/en/.mustflow/skills/formal-verification-review/references/formal-contracts-modeling-checklist.md +434 -0
- package/templates/default/locales/en/.mustflow/skills/formal-verification-review/references/formal-memory-bounds-ci-checklist.md +509 -0
- package/templates/default/locales/en/.mustflow/skills/fuzz-harness-review/SKILL.md +439 -0
- package/templates/default/locales/en/.mustflow/skills/fuzz-harness-review/references/fuzz-harness-campaign-checklist.md +379 -0
- package/templates/default/locales/en/.mustflow/skills/fuzz-harness-review/references/fuzz-oracle-triage-ci-checklist.md +307 -0
- package/templates/default/locales/en/.mustflow/skills/idempotency-integrity-review/SKILL.md +48 -28
- package/templates/default/locales/en/.mustflow/skills/idempotency-integrity-review/references/operation-ordering-stale-write-checklist.md +259 -0
- package/templates/default/locales/en/.mustflow/skills/input-boundary-validation-review/SKILL.md +329 -0
- package/templates/default/locales/en/.mustflow/skills/input-boundary-validation-review/references/input-boundary-security-checklist.md +319 -0
- package/templates/default/locales/en/.mustflow/skills/input-event-synchronization-review/SKILL.md +306 -0
- package/templates/default/locales/en/.mustflow/skills/input-event-synchronization-review/references/input-session-state-checklist.md +298 -0
- package/templates/default/locales/en/.mustflow/skills/input-event-synchronization-review/references/remote-input-transport-interaction-checklist.md +328 -0
- package/templates/default/locales/en/.mustflow/skills/interpreter-engineering-review/SKILL.md +353 -0
- package/templates/default/locales/en/.mustflow/skills/interpreter-engineering-review/references/interpreter-diagnostics-recovery-checklist.md +267 -0
- package/templates/default/locales/en/.mustflow/skills/interpreter-engineering-review/references/interpreter-execution-closure-performance-checklist.md +428 -0
- package/templates/default/locales/en/.mustflow/skills/interpreter-engineering-review/references/interpreter-gc-verification-checklist.md +457 -0
- package/templates/default/locales/en/.mustflow/skills/interpreter-engineering-review/references/interpreter-semantics-runtime-checklist.md +391 -0
- package/templates/default/locales/en/.mustflow/skills/modal-loop-reentrancy-review/SKILL.md +294 -0
- package/templates/default/locales/en/.mustflow/skills/modal-loop-reentrancy-review/references/modal-loop-reentrancy-checklist.md +290 -0
- package/templates/default/locales/en/.mustflow/skills/modal-loop-reentrancy-review/references/nested-modal-state-lifetime-checklist.md +297 -0
- package/templates/default/locales/en/.mustflow/skills/name-resolution-integrity-review/SKILL.md +252 -0
- package/templates/default/locales/en/.mustflow/skills/name-resolution-integrity-review/references/dns-network-resolution-checklist.md +394 -0
- package/templates/default/locales/en/.mustflow/skills/name-resolution-integrity-review/references/language-symbol-resolution-checklist.md +282 -0
- package/templates/default/locales/en/.mustflow/skills/name-resolution-integrity-review/references/module-package-loader-resolution-checklist.md +352 -0
- package/templates/default/locales/en/.mustflow/skills/parser-engineering-review/SKILL.md +103 -17
- package/templates/default/locales/en/.mustflow/skills/parser-engineering-review/references/cst-ast-lowering-checklist.md +260 -0
- package/templates/default/locales/en/.mustflow/skills/parser-engineering-review/references/lexer-tokenization-checklist.md +397 -0
- package/templates/default/locales/en/.mustflow/skills/parser-engineering-review/references/tree-serialization-compatibility-checklist.md +164 -0
- package/templates/default/locales/en/.mustflow/skills/parser-engineering-review/references/tree-traversal-rewrite-checklist.md +209 -0
- package/templates/default/locales/en/.mustflow/skills/race-condition-review/SKILL.md +68 -11
- package/templates/default/locales/en/.mustflow/skills/race-condition-review/references/race-reproduction-memory-model-checklist.md +268 -0
- package/templates/default/locales/en/.mustflow/skills/routes.toml +151 -0
- package/templates/default/locales/en/.mustflow/skills/session-handoff-integrity-review/SKILL.md +343 -0
- package/templates/default/locales/en/.mustflow/skills/session-handoff-integrity-review/references/session-auth-stream-resume-checklist.md +413 -0
- package/templates/default/locales/en/.mustflow/skills/session-handoff-integrity-review/references/session-handoff-protocol-checklist.md +485 -0
- package/templates/default/locales/en/.mustflow/skills/two-phase-transition-integrity-review/SKILL.md +267 -0
- package/templates/default/locales/en/.mustflow/skills/two-phase-transition-integrity-review/references/admission-decision-recovery-checklist.md +308 -0
- package/templates/default/locales/en/.mustflow/skills/two-phase-transition-integrity-review/references/two-phase-transition-checklist.md +229 -0
- package/templates/default/locales/en/.mustflow/skills/ui-dispatch-lifecycle-review/SKILL.md +300 -0
- package/templates/default/locales/en/.mustflow/skills/ui-dispatch-lifecycle-review/references/ui-affinity-event-loop-checklist.md +277 -0
- package/templates/default/locales/en/.mustflow/skills/ui-dispatch-lifecycle-review/references/ui-dispatch-lifecycle-checklist.md +292 -0
- package/templates/default/manifest.toml +115 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
mustflow_doc: skill.file-upload-security-review
|
|
3
3
|
locale: en
|
|
4
4
|
canonical: true
|
|
5
|
-
revision:
|
|
5
|
+
revision: 3
|
|
6
6
|
lifecycle: mustflow-owned
|
|
7
7
|
authority: procedure
|
|
8
8
|
name: file-upload-security-review
|
|
@@ -30,7 +30,9 @@ metadata:
|
|
|
30
30
|
<!-- mustflow-section: purpose -->
|
|
31
31
|
## Purpose
|
|
32
32
|
|
|
33
|
-
Review file upload security as a full lifecycle, not as an extension
|
|
33
|
+
Review file upload security as a full lifecycle, not as an extension, MIME-type, or request-size
|
|
34
|
+
checklist. Accepting a file also selects parsers, expansion work, storage authority, and a future
|
|
35
|
+
serving path under attacker influence.
|
|
34
36
|
|
|
35
37
|
The review question is not "does the upload route block `.exe`?" It is "what final bytes, filename,
|
|
36
38
|
storage key, parser, visibility state, authorization check, and response headers can this uploaded
|
|
@@ -80,6 +82,9 @@ file reach after it enters the system?"
|
|
|
80
82
|
- File identity ledger: original filename, normalized filename, final storage key, bucket or root,
|
|
81
83
|
database record id, tenant or owner, checksum, size, content type, detected type, extension,
|
|
82
84
|
visibility, status, and cleanup owner.
|
|
85
|
+
- Storage-access ledger: public opaque file id, tenant and object version used for authorization,
|
|
86
|
+
internal exact object key or root capability, original display name, storage adapter owning raw
|
|
87
|
+
path or key access, and every caller that can bypass that adapter.
|
|
83
88
|
- Validation ledger: extension allowlist, decoding and normalization, content-type trust, signature
|
|
84
89
|
checks, parser-based validation, image rewriting, metadata stripping, antivirus, CDR, size limits,
|
|
85
90
|
count limits, quota, rate limits, and failure behavior.
|
|
@@ -91,6 +96,17 @@ file reach after it enters the system?"
|
|
|
91
96
|
admin preview, email attachments, and public/private transition.
|
|
92
97
|
- Existing tests, abuse cases, security docs, storage policy docs, configured command intents, and
|
|
93
98
|
any unavailable cloud or scanner evidence.
|
|
99
|
+
- Byte-lineage ledger: quarantine object key and immutable version, received-byte digest, inspection
|
|
100
|
+
input digest, scanner and parser policy versions, approved object key and version, approved-byte
|
|
101
|
+
digest, and the operation that promoted or copied the approved bytes.
|
|
102
|
+
- Decoded-resource ledger: raster pixels and frames, document pages and layers, archive entries and
|
|
103
|
+
actual emitted bytes, parser CPU, memory, temporary disk, file descriptors, child processes,
|
|
104
|
+
elapsed time, output bytes, concurrency, retries, storage, and external-service cost.
|
|
105
|
+
- Remote-fetch ledger: original URL, canonical scheme and host, IDNA result, allowed port and method,
|
|
106
|
+
every resolved A and AAAA address, the address bound to the connection, TLS hostname, redirect
|
|
107
|
+
hops, egress decision, forwarded headers, and response limits.
|
|
108
|
+
- Read `references/file-upload-parser-ssrf-resource-checklist.md` when native or complex parsers,
|
|
109
|
+
archives, direct object-storage uploads, remote fetches, or resource-safety claims are in scope.
|
|
94
110
|
|
|
95
111
|
<!-- mustflow-section: preconditions -->
|
|
96
112
|
## Preconditions
|
|
@@ -126,6 +142,8 @@ file reach after it enters the system?"
|
|
|
126
142
|
store, record metadata, scan, transform, promote, preview, download, delete, and cleanup.
|
|
127
143
|
- Include admin preview, email attachment, export, CDN, search index, and worker paths when they
|
|
128
144
|
can read the uploaded bytes.
|
|
145
|
+
- Prove each accepted format and reachable parser is required by the product surface. Reject
|
|
146
|
+
unsupported containers or transformations instead of hardening an accidental feature.
|
|
129
147
|
2. Treat frontend restrictions as usability only.
|
|
130
148
|
- `<input accept>`, client-side size checks, mobile picker filters, and JavaScript extension
|
|
131
149
|
checks do not prove security.
|
|
@@ -139,13 +157,24 @@ file reach after it enters the system?"
|
|
|
139
157
|
- Blocklists for `.php`, `.jsp`, `.asp`, `.html`, `.svg`, config files, legacy plugin types, or
|
|
140
158
|
executable server extensions are not enough by themselves.
|
|
141
159
|
5. Validate the final storage name and key, not only the original filename.
|
|
142
|
-
-
|
|
160
|
+
- Prefer external APIs that accept an opaque file id rather than a path, folder, prefix, or
|
|
161
|
+
storage key. Resolve authorization from the trusted `(tenant, object_id, version)` tuple before
|
|
162
|
+
loading the internal storage locator.
|
|
163
|
+
- Treat the original filename as display metadata. Confirm the server generates the stored
|
|
164
|
+
basename, exact object key, upload id, and local relative path.
|
|
165
|
+
- Keep raw local paths and object-store keys private to one storage adapter. Expose typed
|
|
166
|
+
operations such as get-by-authorized-id, stream-put, and extract-to-staging rather than
|
|
167
|
+
allowing controllers, workers, previews, and admin tools to reconstruct locators independently.
|
|
143
168
|
- Treat `destination`, `folder`, `key`, `path`, `filename`, `bucket`, and callback-provided
|
|
144
169
|
storage locations as attacker-controlled unless derived on the server.
|
|
145
170
|
6. Prove path containment after normalization and symlink resolution.
|
|
146
|
-
- `path.join(uploadDir, userName)`
|
|
147
|
-
|
|
148
|
-
|
|
171
|
+
- `path.join(uploadDir, userName)`, `realpath`, and a prefix check are early filters, not proof
|
|
172
|
+
when an attacker can change the tree.
|
|
173
|
+
- For local files, apply `cross-platform-filesystem-safety`: open relative to a trusted root
|
|
174
|
+
descriptor, HANDLE, or verified runtime root capability and keep the same opened-object
|
|
175
|
+
identity through scanning, transformation, promotion, and deletion.
|
|
176
|
+
- For object storage, directories are not a security boundary. Use the exact server-resolved key
|
|
177
|
+
and immutable version; do not authorize with user-built prefixes or prefix matching.
|
|
149
178
|
7. Bound filenames and storage keys.
|
|
150
179
|
- Check filename length, full path length, database column length, object-storage key length, log
|
|
151
180
|
field length, CDN cache-key length, and error behavior for oversized or malformed names.
|
|
@@ -166,10 +195,11 @@ file reach after it enters the system?"
|
|
|
166
195
|
- Polyglot files, metadata payloads, trailing content, and container formats can pass simple
|
|
167
196
|
signature checks while still reaching dangerous parsers.
|
|
168
197
|
12. Re-encode images when possible.
|
|
169
|
-
- Decode and write a new image instead of storing user bytes directly when the product
|
|
170
|
-
needs raster images.
|
|
171
|
-
-
|
|
172
|
-
|
|
198
|
+
- Decode pixels and write a new image instead of storing user bytes directly when the product
|
|
199
|
+
only needs raster images.
|
|
200
|
+
- Apply orientation before size policy, choose a fixed output format and color space, and add
|
|
201
|
+
back only metadata the product explicitly needs. Do not copy arbitrary EXIF, comments,
|
|
202
|
+
thumbnails, profiles, or trailing bytes into the approved object.
|
|
173
203
|
13. Treat SVG and HTML as active content.
|
|
174
204
|
- Do not group SVG with ordinary raster images.
|
|
175
205
|
- If SVG is allowed, require sanitization or rasterization, separate origin or strict CSP,
|
|
@@ -178,36 +208,66 @@ file reach after it enters the system?"
|
|
|
178
208
|
- Check macros, embedded objects, JavaScript, external links, parser vulnerabilities, preview
|
|
179
209
|
isolation, antivirus or CDR, and whether downloads are safer than inline rendering.
|
|
180
210
|
15. Review archive extraction as the main feature.
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
211
|
+
- For ZIP, tar, and nested archives, parse the complete bounded entry set before the first write
|
|
212
|
+
when feasible. Build one destination graph for duplicate normalized names, case and Unicode
|
|
213
|
+
aliases, alternate separators, file-directory prefix conflicts, and order-dependent link
|
|
214
|
+
traversal, then carry the validated entry object into extraction.
|
|
215
|
+
- Reject symlinks, hardlinks, devices, FIFOs, absolute paths, duplicate normalized names, and
|
|
216
|
+
unsupported entry types unless a narrower policy proves them safe.
|
|
217
|
+
- Ignore archive owner, group, mode, setuid, setgid, sticky, ACL, xattr, capability, and timestamp
|
|
218
|
+
metadata unless explicitly required and allowlisted. Create regular files and directories with
|
|
219
|
+
service-owned permissions inside a new attacker-nonwritable staging directory.
|
|
220
|
+
- Count actual bytes emitted while streaming extraction; do not trust archive headers or only a
|
|
221
|
+
compression ratio. Bound declared and actual size, sparse logical size and allocated storage,
|
|
222
|
+
entry and directory count, per-entry and cumulative emitted bytes, name length, depth, nesting,
|
|
223
|
+
parser work, and time under one shared budget.
|
|
224
|
+
- Pin and review the runtime extraction API and security options. Library filtering or path
|
|
225
|
+
cleanup remains defense in depth and does not replace the application entry policy.
|
|
226
|
+
- Treat every extracted entry as a fresh hostile upload with its own type, parser, filename,
|
|
227
|
+
and publication decision. Nested archives consume the parent budget rather than resetting it.
|
|
185
228
|
16. Review CSV import and export for formula injection.
|
|
186
229
|
- If user-supplied cells may later be opened in spreadsheets, handle cells beginning with `=`,
|
|
187
230
|
`+`, `-`, `@`, tabs, carriage returns, line feeds, separators, quotes, and confusable
|
|
188
231
|
variants according to local policy.
|
|
189
232
|
17. Review remote URL import as SSRF plus upload.
|
|
190
|
-
-
|
|
191
|
-
|
|
192
|
-
|
|
233
|
+
- Prefer product-owned identifiers or provider integrations over arbitrary URLs. If URLs remain,
|
|
234
|
+
parse once and carry the same structured result into connection setup.
|
|
235
|
+
- Fix allowed schemes, ports, and methods; canonicalize IDNA hostnames; inspect every A and AAAA
|
|
236
|
+
result plus CNAME outcome; normalize IPv4, IPv6, mapped, loopback, private, link-local,
|
|
237
|
+
multicast, unspecified, and metadata ranges before connecting.
|
|
238
|
+
- Bind one validated address to the socket while preserving the canonical hostname for TLS and
|
|
239
|
+
HTTP host semantics. Revalidate every redirect as a new request and prevent DNS or proxy
|
|
240
|
+
layers from silently choosing a different address.
|
|
241
|
+
- Do not forward inbound authorization, cookies, proxy credentials, or arbitrary user headers.
|
|
242
|
+
Enforce egress policy, connect/read/total deadlines, response-byte and decoded-work limits,
|
|
243
|
+
then send the fetched response through the same quarantine and upload pipeline.
|
|
193
244
|
18. Keep scanner and conversion work behind a publication gate.
|
|
194
245
|
- A file that is pending scan, failed scan, pending conversion, or failed conversion should not
|
|
195
246
|
be public, previewable, downloadable, indexed, or emailed unless policy explicitly allows it.
|
|
247
|
+
- Bind inspection results to an immutable quarantine object version and digest. A database row
|
|
248
|
+
saying `clean` is not proof if the referenced object can be overwritten afterward.
|
|
196
249
|
19. Sandbox file parsers and scanners.
|
|
197
250
|
- ImageMagick, ffmpeg, LibreOffice, PDF parsers, OCR tools, unzip, antivirus, and CDR engines
|
|
198
|
-
need low privilege, no unnecessary network,
|
|
199
|
-
|
|
251
|
+
need low privilege, no unnecessary network, explicit coder or delegate allowlists, CPU,
|
|
252
|
+
memory, temporary disk, file descriptor, child-process, wall-time, and output limits,
|
|
253
|
+
temporary-directory isolation, and controlled input paths.
|
|
254
|
+
- Treat timeout, crash, partial output, unavailable scanner, and limit exhaustion as rejection or
|
|
255
|
+
quarantine, never as an implicit pass.
|
|
200
256
|
20. Validate direct-to-storage uploads in two phases.
|
|
201
257
|
- Before issuing a signed upload URL, authorize the target resource and fix method, bucket, key,
|
|
202
258
|
prefix, content type policy, checksum, size range, overwrite policy, and expiration.
|
|
203
|
-
- After upload completion,
|
|
259
|
+
- After upload completion, read and hash the exact immutable object version that scanners and
|
|
260
|
+
parsers will inspect. Promote or copy only that exact version, record the approved digest and
|
|
261
|
+
policy or tool versions, and prevent the client from overwriting the approved destination.
|
|
204
262
|
21. Treat presigned URLs as delegated authority.
|
|
205
263
|
- Check method, bucket, key, prefix, expiry, reuse, checksum, content-length range, content type,
|
|
206
264
|
ACL or public-read flags, revocation behavior, CDN caching, and whether the creator's
|
|
207
265
|
privileges are too broad.
|
|
208
266
|
22. Enforce tenant boundaries in storage keys and metadata.
|
|
209
|
-
|
|
210
|
-
|
|
267
|
+
- Authorize the `(tenant, object_id, version)` lookup before resolving the internal key. Knowing
|
|
268
|
+
or guessing a storage locator must not grant access.
|
|
269
|
+
- Server-generated keys should include trusted tenant, organization, project, or resource
|
|
270
|
+
context plus a random id when multi-tenant isolation matters.
|
|
211
271
|
- Reads, writes, deletes, overwrites, cleanup, and promotion must use the same boundary.
|
|
212
272
|
23. Recheck authorization at download and preview time.
|
|
213
273
|
- Upload permission is not download permission.
|
|
@@ -216,16 +276,29 @@ file reach after it enters the system?"
|
|
|
216
276
|
24. Set response headers deliberately.
|
|
217
277
|
- Use safe `Content-Type`; default ambiguous private downloads to `application/octet-stream`.
|
|
218
278
|
- Use `Content-Disposition: attachment` when inline rendering is not required.
|
|
219
|
-
|
|
220
|
-
|
|
279
|
+
- Add `X-Content-Type-Options: nosniff` and review CSP, origin isolation, and CDN header
|
|
280
|
+
preservation where browser execution risk exists.
|
|
281
|
+
- Treat `Content-Disposition` filenames as presentation only. Remove CR/LF and path segments,
|
|
282
|
+
generate a conservative ASCII `filename` fallback plus a correctly encoded UTF-8 `filename*`,
|
|
283
|
+
and never feed either value back into storage lookup or authorization.
|
|
284
|
+
- Serve static assets through an immutable build manifest. Keep SPA fallback fixed to one known
|
|
285
|
+
`index.html` after route classification instead of trying alternate extensions or arbitrary
|
|
286
|
+
filesystem candidates derived from the URL.
|
|
221
287
|
25. Treat filename display as an injection surface.
|
|
222
288
|
- Escape original filenames in HTML, email, admin tables, JSON-in-script, logs, and support
|
|
223
289
|
views.
|
|
224
|
-
|
|
290
|
+
- For `Content-Disposition`, remove CR/LF and encode filenames safely for header context.
|
|
291
|
+
- Escape control characters and line breaks before logging rejected names. Record a bounded
|
|
292
|
+
display value and stable policy code, not the raw attacker-controlled string.
|
|
225
293
|
26. Apply resource limits at every layer.
|
|
226
294
|
- Bound request body size, per-file size, file count, concurrent uploads, chunk count, multipart
|
|
227
295
|
sessions, user quota, tenant quota, daily quota, extracted size, transformed size, preview
|
|
228
296
|
time, and retry volume.
|
|
297
|
+
- Bound decoded pixels, cumulative animation frames, pages, layers, archive entries and actual
|
|
298
|
+
emitted bytes, parser CPU and memory, temporary disk, file descriptors, child processes,
|
|
299
|
+
output bytes, queue depth, concurrent conversions, storage growth, and paid external work.
|
|
300
|
+
- Put deadlines and cancellation around the whole operation; a per-read timeout does not cap a
|
|
301
|
+
peer that continuously dribbles bytes.
|
|
229
302
|
27. Revalidate chunked and multipart uploads at assembly time.
|
|
230
303
|
- Check final file size, content type, signature, chunk order, chunk count, checksum, session
|
|
231
304
|
expiration, stale partial cleanup, and final key ownership after assembly.
|
|
@@ -241,7 +314,23 @@ file reach after it enters the system?"
|
|
|
241
314
|
- Cover disallowed type, spoofed MIME, renamed extension, encoded extension, double extension,
|
|
242
315
|
oversize body, quota exceeded, path traversal, archive escape, zip bomb, SVG active content,
|
|
243
316
|
CSV formula, unauthorized upload target, unauthorized download, pending-scan download,
|
|
244
|
-
presigned overwrite, stale multipart session,
|
|
317
|
+
presigned overwrite, stale multipart session, type-detector disagreement, cumulative image
|
|
318
|
+
pixels or frames, archive special entries and actual emitted-byte overflow, parser timeout or
|
|
319
|
+
crash, quarantine-object replacement, DNS or redirect rebinding, forbidden egress, credential
|
|
320
|
+
forwarding, fetched-response revalidation, path-shaped public API input, prefix-authorized
|
|
321
|
+
object keys, file-directory archive conflicts, archive metadata restoration, sparse logical
|
|
322
|
+
size overflow, `Content-Disposition` CR/LF, static-extension fallback, and raw-name log
|
|
323
|
+
injection where relevant.
|
|
324
|
+
- Assert rejected, crashed, timed-out, or partially processed files never become public,
|
|
325
|
+
previewable, downloadable, indexed, emailed, or reusable as approved inputs.
|
|
326
|
+
- Classify each finding as publication-blocking, high-risk but contained, or defense-in-depth,
|
|
327
|
+
and name the exact missing invariant or evidence that would change the decision.
|
|
328
|
+
- Use publication-blocking when exact-byte identity, authorization, parser or expansion
|
|
329
|
+
bounds, remote-destination control, or fail-closed publication gating is missing.
|
|
330
|
+
- Use high-risk but contained only when an independent enforced control proves the risky
|
|
331
|
+
bytes or operation cannot reach a published, privileged, or cross-tenant path. Partial
|
|
332
|
+
hardening of the same vulnerable control is not containment.
|
|
333
|
+
- Use defense-in-depth only after the required lifecycle invariants are already proven.
|
|
245
334
|
|
|
246
335
|
<!-- mustflow-section: postconditions -->
|
|
247
336
|
## Postconditions
|
|
@@ -250,8 +339,14 @@ file reach after it enters the system?"
|
|
|
250
339
|
record, validation gates, processing tools, visibility state, serving path, and cleanup owner.
|
|
251
340
|
- Client-provided filenames, MIME labels, paths, keys, URLs, sizes, checksums, tenants, owners, and
|
|
252
341
|
visibility flags are either ignored, verified, or explicitly reported as risky.
|
|
342
|
+
- Public file identifiers, authorization tuples, display names, internal exact keys, immutable
|
|
343
|
+
versions, and local root capabilities are distinct; raw locators remain behind one storage adapter.
|
|
253
344
|
- File type validation is tied to normalized final names and actual bytes, not only extension or
|
|
254
345
|
request headers.
|
|
346
|
+
- Scanner and parser results are bound to the exact immutable object version and digest later
|
|
347
|
+
promoted or served, with tool or policy versions recorded where decisions depend on them.
|
|
348
|
+
- Decoded, expanded, parser, concurrency, output, storage, and external-cost budgets are explicit;
|
|
349
|
+
archive and remote-fetch paths cannot reset or bypass them.
|
|
255
350
|
- Upload, processing, promotion, preview, download, CDN, email, admin, and cleanup paths are checked
|
|
256
351
|
or explicitly scoped out.
|
|
257
352
|
- Denial-case tests or missing evidence are named from the attacker-controlled file lifecycle.
|
|
@@ -273,9 +368,10 @@ Use configured oneshot command intents when available:
|
|
|
273
368
|
- `mustflow_check`
|
|
274
369
|
|
|
275
370
|
Prefer the narrowest configured tests that prove file lifecycle denial behavior: disallowed type,
|
|
276
|
-
spoofed MIME, normalized extension bypass, path traversal, archive escape
|
|
277
|
-
|
|
278
|
-
|
|
371
|
+
spoofed MIME, normalized extension bypass, path traversal, archive escape or actual-byte overflow,
|
|
372
|
+
decoded-media and parser limits, immutable-object binding, unauthorized upload target, unauthorized
|
|
373
|
+
download, pending-scan access, presigned policy, DNS and redirect rebinding, and fetched-response
|
|
374
|
+
revalidation.
|
|
279
375
|
|
|
280
376
|
<!-- mustflow-section: failure-handling -->
|
|
281
377
|
## Failure Handling
|
|
@@ -295,10 +391,15 @@ URL rejection.
|
|
|
295
391
|
## Output Format
|
|
296
392
|
|
|
297
393
|
- File upload security reviewed
|
|
298
|
-
- Upload entrypoints,
|
|
299
|
-
|
|
300
|
-
|
|
394
|
+
- Upload entrypoints, byte lineage, immutable object versions and digests, storage, validation,
|
|
395
|
+
processing, serving, and cleanup map
|
|
396
|
+
- Filename, opaque identity, exact storage key, root capability, type, path, overwrite, web-root,
|
|
397
|
+
static-manifest serving, parser isolation, decoded-resource, archive metadata and sparse budgets, CSV,
|
|
398
|
+
remote-fetch resolution and redirect, scanner, signed URL, tenant, authorization, header, and
|
|
399
|
+
resource-limit findings
|
|
301
400
|
- Fixes made or recommendation
|
|
401
|
+
- Finding disposition: publication-blocking, high-risk but contained, or defense-in-depth, with the
|
|
402
|
+
enforcing control and missing invariant or evidence needed to change the decision
|
|
302
403
|
- Denial tests, fixtures, or invariant evidence
|
|
303
404
|
- Command intents run
|
|
304
405
|
- Skipped checks and reasons
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
# File Upload Parser, SSRF, and Resource Checklist
|
|
2
|
+
|
|
3
|
+
Use this reference when the short procedure needs concrete review ledgers for complex parsers,
|
|
4
|
+
archive extraction, direct object-storage uploads, remote imports, or resource-exhaustion claims.
|
|
5
|
+
It is a review aid, not a universal numeric policy. Record repository-specific limits and evidence.
|
|
6
|
+
|
|
7
|
+
## Contents
|
|
8
|
+
|
|
9
|
+
1. [Lifecycle and publication states](#1-lifecycle-and-publication-states)
|
|
10
|
+
2. [Byte lineage and immutable objects](#2-byte-lineage-and-immutable-objects)
|
|
11
|
+
3. [Type and parser decision matrix](#3-type-and-parser-decision-matrix)
|
|
12
|
+
4. [Decoded media and document budgets](#4-decoded-media-and-document-budgets)
|
|
13
|
+
5. [Archive extraction ledger](#5-archive-extraction-ledger)
|
|
14
|
+
6. [Remote-fetch SSRF ledger](#6-remote-fetch-ssrf-ledger)
|
|
15
|
+
7. [Parser sandbox and capability matrix](#7-parser-sandbox-and-capability-matrix)
|
|
16
|
+
8. [Resource, concurrency, and cost budget](#8-resource-concurrency-and-cost-budget)
|
|
17
|
+
9. [Layer responsibility handoff](#9-layer-responsibility-handoff)
|
|
18
|
+
10. [Denial and differential test matrix](#10-denial-and-differential-test-matrix)
|
|
19
|
+
11. [Primary reference anchors](#11-primary-reference-anchors)
|
|
20
|
+
|
|
21
|
+
## 1. Lifecycle and publication states
|
|
22
|
+
|
|
23
|
+
Model visibility as an explicit state machine. A useful minimum is:
|
|
24
|
+
|
|
25
|
+
`receiving -> quarantined -> inspecting -> approved -> published`
|
|
26
|
+
|
|
27
|
+
Terminal or side states include `rejected`, `processing_failed`, `expired`, and `deleted`.
|
|
28
|
+
|
|
29
|
+
For every state, record:
|
|
30
|
+
|
|
31
|
+
| Question | Evidence |
|
|
32
|
+
| --- | --- |
|
|
33
|
+
| Who may write or replace bytes? | Storage policy and application authorization |
|
|
34
|
+
| Who may read bytes? | Download, preview, worker, admin, and support paths |
|
|
35
|
+
| Which parser may run? | Tool and policy version |
|
|
36
|
+
| Can a CDN, indexer, emailer, or previewer observe it? | Publication gate |
|
|
37
|
+
| What advances the state? | Atomic condition and authenticated actor |
|
|
38
|
+
| What happens on timeout, crash, or unavailable scanner? | Fail-closed transition |
|
|
39
|
+
|
|
40
|
+
Do not treat a `clean = true` column as the state machine. The decision must identify the exact
|
|
41
|
+
bytes inspected and the exact bytes made visible.
|
|
42
|
+
|
|
43
|
+
## 2. Byte lineage and immutable objects
|
|
44
|
+
|
|
45
|
+
Maintain this ledger across receive, inspect, transform, promote, and serve:
|
|
46
|
+
|
|
47
|
+
| Field | Required meaning |
|
|
48
|
+
| --- | --- |
|
|
49
|
+
| `upload_id` | Server-issued lifecycle identifier |
|
|
50
|
+
| `quarantine_key` | Server-generated private location |
|
|
51
|
+
| `quarantine_version` | Immutable object version or equivalent generation id |
|
|
52
|
+
| `received_digest` | Digest computed from bytes actually received |
|
|
53
|
+
| `inspected_digest` | Digest of exact scanner/parser input |
|
|
54
|
+
| `inspection_policy_version` | Allowlist, parser, scanner, and budget policy identity |
|
|
55
|
+
| `derived_digest` | Digest of rewritten or converted output when applicable |
|
|
56
|
+
| `approved_key` and `approved_version` | Exact immutable object selected for serving |
|
|
57
|
+
| `approved_digest` | Digest verified during promotion or copy |
|
|
58
|
+
| `publication_event` | Atomic operation that made the object visible |
|
|
59
|
+
|
|
60
|
+
Reject these broken chains:
|
|
61
|
+
|
|
62
|
+
- the client can overwrite a quarantined object after inspection;
|
|
63
|
+
- the scanner reads `key` without an immutable version while the uploader can replace `key`;
|
|
64
|
+
- metadata is approved but a later download resolves a different object generation;
|
|
65
|
+
- transformation output is public before its own type and resource checks finish;
|
|
66
|
+
- promotion copies the latest object instead of the inspected object;
|
|
67
|
+
- retries overwrite a prior approved destination without an explicit replacement policy.
|
|
68
|
+
|
|
69
|
+
Keep these identities separate:
|
|
70
|
+
|
|
71
|
+
| Identity | Security role |
|
|
72
|
+
| --- | --- |
|
|
73
|
+
| Public `file_id` | Opaque request identifier with no path meaning. |
|
|
74
|
+
| `(tenant, object_id, version)` | Authorization lookup tuple resolved before any storage locator is used. |
|
|
75
|
+
| Original filename | Display metadata only; never a storage key or authorization fact. |
|
|
76
|
+
| Exact object key and immutable version | Server-owned object-store locator returned by the authorized record. Prefix agreement is not authorization. |
|
|
77
|
+
| Local root capability and validated relative entry | Filesystem adapter authority; never exposed as a controller or queue string. |
|
|
78
|
+
|
|
79
|
+
Require one storage adapter to own raw path and object-key APIs. Controllers, workers, thumbnailers,
|
|
80
|
+
archive tools, admin surfaces, and serving code should consume typed file identities or opened streams
|
|
81
|
+
rather than reconstructing paths or prefixes independently.
|
|
82
|
+
|
|
83
|
+
## 3. Type and parser decision matrix
|
|
84
|
+
|
|
85
|
+
Do not ask whether one detector is authoritative. Ask which parser the product needs and which
|
|
86
|
+
evidence is sufficient to select it.
|
|
87
|
+
|
|
88
|
+
| Signal | Use | Never proves alone |
|
|
89
|
+
| --- | --- | --- |
|
|
90
|
+
| Normalized extension | Product allowlist and UX | Actual byte format |
|
|
91
|
+
| Request `Content-Type` | Logging and disagreement detection | Safe parser choice |
|
|
92
|
+
| Signature or magic | Candidate family | Entire container safety |
|
|
93
|
+
| Structural parser | Format conformance | Safe active content or bounded cost |
|
|
94
|
+
| Rewrite/conversion | Produces controlled derivative | Safety if parser is unbounded |
|
|
95
|
+
|
|
96
|
+
Record disagreement policy. An allowed extension with a mismatched signature or parser result
|
|
97
|
+
should not silently choose whichever interpretation is most permissive.
|
|
98
|
+
|
|
99
|
+
For raster-only products, prefer decode-to-pixels and deterministic rewrite. Apply orientation,
|
|
100
|
+
then enforce dimensions, select a fixed output format and color space, and add back only required
|
|
101
|
+
metadata. Do not preserve arbitrary original chunks or trailing bytes.
|
|
102
|
+
|
|
103
|
+
Treat SVG, HTML, PDF, Office, media containers, fonts, and archives as parser-bearing formats with
|
|
104
|
+
their own active-content and resource policies.
|
|
105
|
+
|
|
106
|
+
## 4. Decoded media and document budgets
|
|
107
|
+
|
|
108
|
+
Compressed bytes are only the wire envelope. Record limits on decoded work:
|
|
109
|
+
|
|
110
|
+
| Format family | Minimum budget dimensions |
|
|
111
|
+
| --- | --- |
|
|
112
|
+
| Raster image | Width, height, total pixels, channels, bit depth, output bytes |
|
|
113
|
+
| Animated image | Per-frame pixels, cumulative frame pixels, frame count, duration |
|
|
114
|
+
| Layered image | Layers, cumulative layer pixels, memory, temporary disk |
|
|
115
|
+
| PDF | Pages, objects, recursion, embedded files, render pixels, output bytes |
|
|
116
|
+
| Office document | Entries, XML nodes, relationships, embedded objects, pages or slides |
|
|
117
|
+
| Audio/video | Duration, tracks, dimensions, frames, decoded bytes, transcode time |
|
|
118
|
+
| OCR | Input pixels or pages, languages, CPU, elapsed time, output text bytes |
|
|
119
|
+
|
|
120
|
+
Limits must apply before or during allocation. A check performed only after a decoder has allocated
|
|
121
|
+
the full image or document does not protect the process.
|
|
122
|
+
|
|
123
|
+
For multi-item containers, track both per-item and cumulative budgets. An animation with many small
|
|
124
|
+
frames or a PDF with many modest pages can exhaust resources while each item passes alone.
|
|
125
|
+
|
|
126
|
+
## 5. Archive extraction ledger
|
|
127
|
+
|
|
128
|
+
Before extraction, define allowed archive families and allowed entry types. During extraction,
|
|
129
|
+
record and enforce:
|
|
130
|
+
|
|
131
|
+
| Budget or invariant | Enforcement point |
|
|
132
|
+
| --- | --- |
|
|
133
|
+
| Complete bounded entry inventory | Before the first filesystem write when the format permits it |
|
|
134
|
+
| File-directory prefix graph | Before accepting both `a` and `a/b` or another order-dependent topology |
|
|
135
|
+
| Normalized contained path | Before creating each entry |
|
|
136
|
+
| Duplicate normalized name | Before overwrite or allocation |
|
|
137
|
+
| Entry type | Before filesystem operation |
|
|
138
|
+
| Metadata allowlist | Before applying owner, group, mode, timestamp, ACL, xattr, or capability fields |
|
|
139
|
+
| Per-entry emitted bytes | While streaming output |
|
|
140
|
+
| Logical size and sparse extents | Before and during allocation |
|
|
141
|
+
| Cumulative emitted bytes | Shared counter across all entries |
|
|
142
|
+
| Entry count | Before accepting the next entry |
|
|
143
|
+
| Nesting depth | Before opening a nested container |
|
|
144
|
+
| Parser CPU and elapsed time | Whole extraction deadline |
|
|
145
|
+
| Temporary disk and files | Sandbox or quota boundary |
|
|
146
|
+
|
|
147
|
+
Reject symlinks, hardlinks, devices, FIFOs, absolute paths, traversal, alternate separators,
|
|
148
|
+
reserved names, and duplicate normalized destinations unless the product has a narrower explicit
|
|
149
|
+
contract. Do not trust declared uncompressed sizes; stop when actual emitted bytes exceed budget.
|
|
150
|
+
|
|
151
|
+
Reject case, Unicode, trailing-dot, trailing-space, short-name, and separator aliases under the
|
|
152
|
+
final consumer platform. Preserve the validated entry object through extraction so a second parser
|
|
153
|
+
cannot reinterpret the raw name. Accept regular files and directories only by default, use exclusive
|
|
154
|
+
creation below a root capability, and never merge into an existing or attacker-writable tree.
|
|
155
|
+
|
|
156
|
+
Do not restore archive uid, gid, owner names, original modes, setuid, setgid, sticky bits, ACLs,
|
|
157
|
+
xattrs, capabilities, or timestamps by default. Sparse entries require both logical-size and actual
|
|
158
|
+
storage budgets. Extract into a new private staging directory and publish only the verified tree.
|
|
159
|
+
|
|
160
|
+
Library path cleanup, extraction filters, or non-local-name warnings are versioned defense in depth.
|
|
161
|
+
Pin the runtime and API option, but keep the application entry, collision, metadata, capability,
|
|
162
|
+
and resource policies independent of the current library default.
|
|
163
|
+
|
|
164
|
+
Each extracted regular file re-enters filename, type, parser, authorization, and publication
|
|
165
|
+
checks. Nested containers consume the same parent budget. They do not get a fresh unlimited quota.
|
|
166
|
+
|
|
167
|
+
## 6. Remote-fetch SSRF ledger
|
|
168
|
+
|
|
169
|
+
Arbitrary URL import combines network authority with the upload pipeline. Prefer provider-owned ids
|
|
170
|
+
or preconfigured integrations. If arbitrary URLs are necessary, record every decision:
|
|
171
|
+
|
|
172
|
+
| Phase | Required evidence |
|
|
173
|
+
| --- | --- |
|
|
174
|
+
| Parse | One strict parser result; no validate-with-one, connect-with-another split |
|
|
175
|
+
| Scheme and method | Small fixed allowlist, normally `https` and `GET` |
|
|
176
|
+
| Host | Canonical host and IDNA result; reject ambiguous userinfo and fragments |
|
|
177
|
+
| Port | Fixed or narrow allowlist |
|
|
178
|
+
| Resolve | Every A and AAAA result plus relevant CNAME outcome |
|
|
179
|
+
| Address policy | Normalized IPv4, IPv6, and mapped-address classification |
|
|
180
|
+
| Connect | One validated address bound to the socket |
|
|
181
|
+
| TLS and HTTP | Canonical hostname retained for certificate and host semantics |
|
|
182
|
+
| Redirect | Every hop reparsed, resolved, classified, and budgeted |
|
|
183
|
+
| Headers | No inbound auth, cookies, proxy credentials, or arbitrary user headers |
|
|
184
|
+
| Egress | Network firewall or proxy independently blocks forbidden ranges |
|
|
185
|
+
| Response | Header, body, decoded-work, connect, read, and total deadline limits |
|
|
186
|
+
| Handoff | Response enters quarantine as a new hostile upload |
|
|
187
|
+
|
|
188
|
+
Reject loopback, private, link-local, multicast, unspecified, reserved, and infrastructure metadata
|
|
189
|
+
destinations according to deployment policy. Check both address families. A hostname with one public
|
|
190
|
+
and one forbidden result is not safely public just because the first answer looked acceptable.
|
|
191
|
+
|
|
192
|
+
Disable redirects by default. When enabled, cap hop count and treat each `Location` as fresh input.
|
|
193
|
+
Do not let a generic HTTP client silently re-resolve or follow a proxy path that bypasses the
|
|
194
|
+
validated address.
|
|
195
|
+
|
|
196
|
+
## 7. Parser sandbox and capability matrix
|
|
197
|
+
|
|
198
|
+
For each native tool, library, delegate, or subprocess, record:
|
|
199
|
+
|
|
200
|
+
| Capability | Policy question |
|
|
201
|
+
| --- | --- |
|
|
202
|
+
| Input formats | Which coders or parsers are enabled? |
|
|
203
|
+
| Delegates | Can input launch another interpreter or executable? |
|
|
204
|
+
| Filesystem read | Can it read outside the isolated input directory? |
|
|
205
|
+
| Filesystem write | Can it write outside bounded temporary and output directories? |
|
|
206
|
+
| Network | Is outbound access disabled by runtime policy? |
|
|
207
|
+
| Processes | Can it spawn children, and how many? |
|
|
208
|
+
| Privilege | Which user, group, namespace, or container runs it? |
|
|
209
|
+
| Resources | CPU, memory, map, disk, files, descriptors, threads, wall time, output |
|
|
210
|
+
| Failure | What happens on crash, timeout, truncation, or partial output? |
|
|
211
|
+
| Version | Which tool and security policy version made the decision? |
|
|
212
|
+
|
|
213
|
+
An application timeout without process termination is incomplete. Cancellation must stop child
|
|
214
|
+
work, close streams, prevent publication, and clean bounded temporary artifacts.
|
|
215
|
+
|
|
216
|
+
## 8. Resource, concurrency, and cost budget
|
|
217
|
+
|
|
218
|
+
Build one budget ledger from edge to worker instead of isolated `10MB` checks:
|
|
219
|
+
|
|
220
|
+
- wire bytes: request body, file, multipart overhead, chunks, remote response;
|
|
221
|
+
- structure: files, archive entries, pages, frames, layers, tracks, nodes, relationships;
|
|
222
|
+
- decoded work: pixels, samples, decompressed bytes, parser tokens or objects;
|
|
223
|
+
- runtime: CPU, memory, temporary disk, descriptors, processes, threads, elapsed time;
|
|
224
|
+
- outputs: thumbnails, previews, rewritten objects, extracted files, logs, metadata;
|
|
225
|
+
- concurrency: per-user, per-tenant, per-worker, global in-flight jobs, queue depth;
|
|
226
|
+
- retries and lifecycle: attempts, total age, stale partials, cleanup backlog;
|
|
227
|
+
- durable cost: storage bytes, CDN bytes, scanner calls, OCR pages, transcode minutes.
|
|
228
|
+
|
|
229
|
+
Define reservation and release points. A quota checked after expensive conversion or after object
|
|
230
|
+
storage has already grown is accounting, not prevention.
|
|
231
|
+
|
|
232
|
+
## 9. Layer responsibility handoff
|
|
233
|
+
|
|
234
|
+
Keep every layer honest about what it can prove:
|
|
235
|
+
|
|
236
|
+
| Layer | Owns | Does not prove |
|
|
237
|
+
| --- | --- | --- |
|
|
238
|
+
| Frontend | Early feedback, picker hints, progress | Security or final type |
|
|
239
|
+
| Edge/proxy | Wire envelope, coarse rate and timeout | Parser semantics |
|
|
240
|
+
| Upload API | Strict multipart syntax, auth, quarantine identity | Safe derived output |
|
|
241
|
+
| Domain service | Allowed use, owner, state transition, publication policy | Native parser isolation |
|
|
242
|
+
| Storage | Immutability, versioning, conditional writes, retention | Content safety |
|
|
243
|
+
| Worker | Exact-version parsing, budgets, derived output, result evidence | Download authorization |
|
|
244
|
+
| Database | Constraints and atomic state transitions | Object bytes by itself |
|
|
245
|
+
| Serving layer | Current authorization, headers, origin, exact approved object, immutable asset manifest | Prior client checks or path-prefix ownership |
|
|
246
|
+
|
|
247
|
+
Queue consumers must revalidate durable facts. A queued message carrying `approved = true` is not a
|
|
248
|
+
substitute for loading current state and the immutable object identity.
|
|
249
|
+
|
|
250
|
+
For downloads, resolve authorization before the exact object key, treat `Content-Disposition`
|
|
251
|
+
filenames as presentation, remove CR/LF and path components, and generate a conservative ASCII
|
|
252
|
+
`filename` fallback plus a correctly encoded UTF-8 `filename*`. Never reuse either header value as a
|
|
253
|
+
storage locator. Serve built assets through an immutable URL-to-asset manifest; a SPA fallback should
|
|
254
|
+
return one fixed `index.html` only after route classification, not probe alternate filesystem names.
|
|
255
|
+
|
|
256
|
+
Escape control characters in rejected filenames before logging. Store a bounded display value and a
|
|
257
|
+
stable policy code rather than allowing raw names to forge log lines.
|
|
258
|
+
|
|
259
|
+
## 10. Denial and differential test matrix
|
|
260
|
+
|
|
261
|
+
Use safe synthetic fixtures. Cover at least the paths present in the product:
|
|
262
|
+
|
|
263
|
+
- extension, request MIME, signature, and structural parser disagree;
|
|
264
|
+
- image dimensions, frames, layers, or metadata exceed cumulative budgets;
|
|
265
|
+
- document page or object counts exceed policy before unbounded rendering;
|
|
266
|
+
- archive traversal, absolute path, alternate separator, duplicate normalized name, symlink,
|
|
267
|
+
hardlink, device, FIFO, file-directory prefix conflict, order-dependent link, metadata restore,
|
|
268
|
+
sparse logical-size overflow, false size header, nested-budget exhaustion;
|
|
269
|
+
- parser timeout, crash, partial output, unavailable scanner, and cancellation;
|
|
270
|
+
- quarantine object replaced between upload and inspection or inspection and promotion;
|
|
271
|
+
- promotion reads latest generation instead of the recorded immutable version;
|
|
272
|
+
- hostname resolves to mixed public and forbidden addresses;
|
|
273
|
+
- redirect changes scheme, port, host, address class, or exhausts the total budget;
|
|
274
|
+
- DNS re-resolution or proxy routing chooses a different address than the validated one;
|
|
275
|
+
- inbound credentials or cookies would be forwarded to a remote target;
|
|
276
|
+
- remote response passes network policy but fails ordinary upload type or parser policy;
|
|
277
|
+
- rejected or failed files remain unavailable through download, preview, CDN, email, admin, search,
|
|
278
|
+
and derived-object paths.
|
|
279
|
+
- public path or prefix input cannot bypass opaque-id authorization and exact-version lookup;
|
|
280
|
+
- `Content-Disposition` CR/LF and path fragments cannot alter headers or storage lookup;
|
|
281
|
+
- static extension probing and raw-name log injection are rejected.
|
|
282
|
+
|
|
283
|
+
Where two detectors or parsers exist, add differential fixtures so disagreement is an explicit
|
|
284
|
+
failure or policy branch rather than an accidental first-match winner.
|
|
285
|
+
|
|
286
|
+
## 11. Primary reference anchors
|
|
287
|
+
|
|
288
|
+
Use current primary documentation when refreshing claims:
|
|
289
|
+
|
|
290
|
+
- OWASP File Upload Cheat Sheet for defense-in-depth upload controls, generated names, storage
|
|
291
|
+
placement, type signals, size limits, scanning, CDR, and archive expansion limits.
|
|
292
|
+
- OWASP SSRF Prevention Cheat Sheet for URL allowlisting limits, redirect control, scheme policy,
|
|
293
|
+
DNS pinning checks, and A/AAAA review.
|
|
294
|
+
- OWASP API Security API4 for memory, CPU, file descriptor, process, upload, operation-count, page,
|
|
295
|
+
and third-party spending limits.
|
|
296
|
+
- ImageMagick security policy documentation for coder, delegate, path, memory, map, disk, file,
|
|
297
|
+
thread, time, width, height, and list-length controls when ImageMagick is in the parser path.
|
|
298
|
+
- Go `os.Root` and Java `SecureDirectoryStream` official documentation for root-relative runtime
|
|
299
|
+
capabilities and their platform or provider limits.
|
|
300
|
+
- Python `tarfile` and `zipfile`, plus Go `archive/zip`, for versioned extraction filters, caller-owned
|
|
301
|
+
path validation, special entry metadata, sparse members, and non-local-name diagnostics.
|
|
302
|
+
- RFC 6266 for treating response filenames as advisory presentation values and handling path
|
|
303
|
+
components, control characters, device names, `filename`, and `filename*` safely.
|
|
304
|
+
|
|
305
|
+
External guidance is a floor. The repository's concrete parser, object-storage, network, tenant,
|
|
306
|
+
and serving contracts decide the actual implementation and test evidence.
|