Web Security / Intermediate: browser and data interpretation defenses / Lesson 11
Uploads and the complete file lifecycle
Treat uploaded content, names, storage, processing, and download access as connected defensive boundaries.
On this page
Lesson goals
- Distinguish claimed file type from validated content and approved processing.
- Define bounded storage and retrieval with resource ownership.
Follow a file beyond the upload endpoint
A file feature includes receipt, size limits, naming, type interpretation, storage, processing, sharing, download, retention, and disposal. An upload endpoint that accepts bytes is only the beginning. Identify which users may create, read, replace, or delete each file and which service performs processing. A filename, extension, or client Content-Type is a claim, not proof of content. Restrict accepted formats to the actual product need and use supported parsers. This course works with metadata and synthetic facts only; it uploads no file and invokes no file scanner or conversion service.
Define an explicit intake and storage contract
The planning record below names a small fictional document feature. Its size is illustrative, not a universal safe limit. A real implementation must enforce limits before excessive buffering, validate content with the selected format parser, and account for decompressed or processed size as appropriate. Generate storage identifiers through the application rather than using an untrusted path as an authority. Separate public names from internal storage names, and store content where it cannot become executable application code. A restricted storage prefix alone does not establish download authorization or safe processor behavior.
{
"feature": "synthetic-note-attachment",
"allowedTypes": ["reviewed-document-format"],
"illustrativeMaxBytes": 131072,
"storageName": "application-generated-id",
"storageExecution": "not-permitted",
"downloadPermission": "resource-scoped",
"processingState": "review-required"
}
The schema is descriptive and does not configure a server or create storage. The byte limit is a classroom choice. Real format, processing, scanning where approved, and retrieval policies need separate reviewed implementation and evidence.
Treat processors and generated output as dependencies
Image, document, archive, and media libraries interpret complex formats and need support, updates, resource limits, and isolation appropriate to the task. A prefix or magic-byte check is not full validation. Processing can expand content or generate new files, so bound memory, duration, output count, and output size under the platformโs supported controls. Do not execute user-supplied code to inspect an attachment. If a service uses approved malware scanning or content reconstruction, define its failure and quarantine policy; a clean label does not establish every security property. Keep sensitive files out of general diagnostic logs and public test fixtures.
Keep verification facts separate from admission
The pure gate consumes declared synthetic facts about size, type review, and processing state. It demonstrates that a valid-looking extension alone does not admit a file. It neither parses file bytes nor performs scanning or storage. A production gate must receive trustworthy results from the actual approved validators and bind them to the same immutable file identity. Otherwise metadata can describe one file while another is served. Denied content should not become publicly retrievable, and retries must not create orphaned private copies or bypass the normal review path.
def attachment_review(facts, max_bytes=131072):
if type(facts.get("size")) is not int or not 0 < facts["size"] <= max_bytes:
return "reject-size"
if facts.get("typeReviewed") is not True:
return "hold-type-review"
if facts.get("processingComplete") is not True:
return "hold-processing"
return "check-download-permission"
assert attachment_review({"size": 100, "typeReviewed": False}) == "hold-type-review"
assert attachment_review({"size": 100, "typeReviewed": True, "processingComplete": True}) == "check-download-permission"
The function uses only supplied lab metadata. It cannot verify a real file or scan result. Even the final state still requires resource-scoped access; no upload, download, account, or storage operation occurs.
Authorize delivery and verify cleanup
Download and preview routes must enforce current access and return safe content headers through maintained framework APIs. A user-facing filename must not become an uncontrolled response-header or path value. Review inline versus attachment behavior, browser sniffing, cache scope, and public-link expiry according to the feature. Temporary processing copies need owned cleanup and retention. Test legitimate formats, size boundaries, missing review evidence, rejected processing, and cross-account retrieval using harmless fixtures in an authorized environment. Never interpret successful upload or one clean scanner result as proof that the complete file lifecycle is safe.
Common errors and fixes
The extension is accepted as content proof
- Why it happens
- A user-controlled label replaces format validation.
- How to fix it
- Use approved content parsing and processing evidence.
- Prevent it next time
- Separate claimed and verified type fields.
A stored attachment bypasses download permission
- Why it happens
- Storage location is confused with resource authorization.
- How to fix it
- Enforce current scope at every retrieval path.
- Prevent it next time
- Test direct and preview access independently.
Processing creates unbounded resource use
- Why it happens
- Only incoming byte size was considered.
- How to fix it
- Bound supported processing work and generated output.
- Prevent it next time
- Review memory, time, expansion, and cleanup together.
Check your understanding
1. A 100-byte metadata record says a file is approved. What else must admission establish?
Show worked solution
Trustworthy validation of the actual file identity, accepted format, bounded processing, storage policy, and current access. A client-supplied approval flag is not evidence. Keep metadata bound to the bytes that will actually be served.
2. Why include cleanup in the upload security model?
Show worked solution
Temporary or rejected copies can retain private information, consume resources, or later become reachable outside the intended lifecycle. Assign ownership, retention, and interruption recovery, then verify deletion and access boundaries under the approved process.
Key takeaways
- Uploads create a lifecycle, not just a byte-receipt route.
- Type claims and processing evidence are distinct.
- Retrieval, resource limits, and cleanup complete the boundary.