Securely Handle File Uploads and Cloud Storage
Secure file uploads and cloud storage - S3, R2, presigned URLs - covering magic-byte checks and path traversal fixes.
Why it matters
Implement robust file upload and cloud storage solutions, ensuring security and performance. This asset specializes in direct uploads via presigned URLs to services like S3 and Cloudflare R2, with advanced handling for large files and image optimization.
Outcomes
What it gets done
Implement secure file uploads using presigned URLs
Handle large file uploads efficiently without buffering
Validate file types using magic bytes, not just extensions
Optimize images post-upload
Install
Add it to your toolbox
Run in your project directory:
curl -fsSL https://spark.entire.vc/get/ag-file-uploads | bash Overview
File Uploads & Storage
Covers secure file upload and cloud storage patterns for S3 and Cloudflare R2: magic-byte type validation, size limits, path-traversal-safe filenames, and presigned URL scoping. Use whenever implementing file upload, S3/R2 storage, presigned URLs, multipart upload, or image upload handling.
What it does
File Uploads & Storage is an expert skill for handling file uploads and cloud storage - S3, Cloudflare R2, presigned URLs, multipart uploads, and image optimization - built around four core principles: never trust client file type claims, use presigned URLs for direct uploads instead of server proxying, stream large files rather than buffering them, and validate on upload while optimizing after. It documents four "Sharp Edges" security failure modes with severity, symptom, and fix. Trusting client-provided file type (CRITICAL) - a renamed malware.exe passes an extension check; the fix is checking magic bytes via the file-type library rather than the extension or Content-Type header:
import { fileTypeFromBuffer } from "file-type";
async function validateImage(buffer: Buffer) {
const type = await fileTypeFromBuffer(buffer);
const allowedTypes = ["image/jpeg", "image/png", "image/webp"];
if (!type || !allowedTypes.includes(type.mime)) {
throw new Error("Invalid file type");
}
return type;
}
No upload size restrictions (HIGH) - unbounded uploads exhaust memory/disk or run up storage bills; the fix is setting maxFileSize limits in Formidable/Multer, a client-side pre-check, and a ContentLength constraint on presigned PutObjectCommand requests. User-controlled filenames enabling path traversal (CRITICAL) - a filename like "../../../etc/passwd" used directly can overwrite system files; the fix is path.basename() plus either character sanitization or generating an entirely new crypto.randomUUID()-based name with an allow-listed extension. Presigned URLs shared or cached incorrectly (MEDIUM) - a private file's presigned URL cached by a CDN stays accessible beyond its intended scope; the fix is a short expiresIn window plus Cache-Control: no-store headers on the API response, or CloudFront signed URLs for finer control.
When to use - and when NOT to
Use this skill whenever the user mentions or implies file upload, S3, R2, presigned URL, multipart upload, image upload, or cloud storage. It delegates image-delivery/CDN optimization to performance-optimization and file-metadata database schema questions to postgres-wizard rather than handling those itself.
Inputs and outputs
Given a file-upload implementation task, the skill's validation checks flag two critical anti-patterns directly: checking only the file extension instead of magic bytes, and using a user-supplied filename directly in a file path instead of sanitizing it. Output is upload-handling code that validates real file type via magic-byte inspection, enforces size limits both client- and server-side, generates safe non-traversable filenames, and controls presigned-URL exposure with short expiry and no-cache response headers.
Integrations
Named tools and libraries: the file-type package (fileTypeFromBuffer/fileTypeFromStream) for real content-type detection, Formidable and Multer for server-side upload size limits, AWS S3's PutObjectCommand and getSignedUrl for presigned uploads and downloads, Node's path and crypto modules for filename sanitization, and CloudFront signed URLs as an alternative distribution-control mechanism.
Who it's for
Backend engineers implementing file-upload and cloud-storage features who need to avoid the specific, named security failure modes around file-type spoofing, unbounded upload size, path traversal, and presigned-URL leakage - not just a working upload flow, but a secure one.
FAQ
Common questions
Discussion
Questions & comments ยท 0
Sign In Sign in to leave a comment.