reference image upload validation: inspect bytes before issuing a read URL
A filename ending in .png does not prove that an upload is a valid image. Browser-supplied MIME metadata is useful input but is not independent evidence about the bytes. Before issuing a reference URL, make your application’s upload pipeline verify size, supported format, successful decoding, and ownership under a clear resource budget.
Treat validation as a pipeline
Authenticate the uploader, enforce an incoming byte limit, place the file in private staging, inspect its signature, and decode it with a maintained image library under bounded resources. Verify dimensions and pixel count against your product’s policy. A small compressed file can still expand into a costly decode.
authenticated upload
-> bounded private staging
-> allowed signature and decoder format
-> bounded dimensions and decoded pixels
-> optional normalization with reviewed encoder
-> immutable owned asset record
-> time-limited generation read URL
This is an application workflow, not a claim that every step is implemented by Genace’s storage route. The current route checks session, file size, and a MIME allowlist before upload. It does not show full signature inspection or image decoding in that handler.
Keep policy values explicit
Choose supported formats, maximum compressed bytes, dimensions, pixel count, and animation policy for the references your product accepts. Publish those application limits clearly. Do not infer a universal model constraint from your own upload settings or from the route’s local file-size constant.
If you normalize files, preserve the original in restricted storage when your business requires it and record which normalized version was submitted. Removing metadata or re-encoding can change content, so include quality review for product photography or other precision-sensitive references.
Authorize the resulting asset
Generate storage keys on the server instead of using an untrusted filename as a public path. Associate the asset with the local tenant and validation version. A user selecting an asset for generation must still be authorized to use it; upload success alone does not grant every tenant access.
The current adapters use the first image_inputs URL as the upstream reference. Present one active reference for those adapters and avoid implying that several selected uploads are fused automatically. The read URL must remain accessible for the relevant asynchronous access window.
Handle rejection without remote side effects
An invalid upload should fail before any generation request is dispatched. Keep the staged file unavailable and remove it according to your retention policy. Do not test the file by sending it to a paid model just to see whether the provider accepts it.
If a valid upload later becomes inaccessible, classify that separately from decoding failure. Preserve asset version and job context so access policy can be investigated without losing the user’s operation record.
Verification checklist
Use local fixtures for a valid supported image, HTML renamed as an image, a mismatched MIME label, truncated bytes, excessive dimensions, and a prohibited animated file. Confirm every rejection occurs before submission and that decoder resource limits are enforced. Test another tenant’s asset ID and verify access is denied even when its storage URL exists.
Continue with reference URL expiry, input validation, and SSRF boundaries.
Continue with security
Where these facts come from
- Editorial keyword hypothesis; search volume not measured
- https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html
- codebase: src/app/api/storage/upload/route.ts
- codebase: src/ai/providers/seedance.ts