[{"data":1,"prerenderedAt":367},["ShallowReactive",2],{"blog-prompts/secure-file-uploads":3},{"id":4,"title":5,"body":6,"category":346,"date":347,"dateModified":348,"description":349,"draft":350,"extension":351,"faq":352,"featured":350,"headerVariant":353,"image":352,"keywords":352,"meta":354,"navigation":355,"ogDescription":356,"ogTitle":352,"path":357,"readTime":352,"schemaOrg":358,"schemaType":359,"seo":360,"sitemap":361,"stem":362,"tags":363,"twitterCard":365,"__hash__":366},"blog/blog/prompts/secure-file-uploads.md","Secure File Uploads with AI Prompts",{"type":7,"value":8,"toc":336},"minimark",[9,16,21,24,96,100,103,160,170,174,177,215,219,222,257,266,282,286,289,310,324],[10,11,12],"tldr",{},[13,14,15],"p",{},"File uploads are dangerous. Attackers can upload malicious scripts, oversized files for DoS, or files with misleading extensions. Validate file type by content (not extension), enforce size limits, store outside webroot, and use random filenames. These prompts help you build safe upload handling.",[17,18,20],"h2",{"id":19},"file-upload-validation","File Upload Validation",[13,22,23],{},"Use this prompt to generate a complete file upload validation module. Your AI will produce code that checks magic bytes, enforces size limits, allowlists file types, and strips EXIF metadata from images.",[25,26,28,31,34,53,56,71,74,88],"prompt-box",{"title":27},"Validate Uploaded Files",[13,29,30],{},"Implement secure file upload validation.",[13,32,33],{},"Requirements:",[35,36,37,41,44,47,50],"ol",{},[38,39,40],"li",{},"Validate file type by content (magic bytes), not extension",[38,42,43],{},"Enforce maximum file size",[38,45,46],{},"Allowlist permitted file types",[38,48,49],{},"Generate random filename for storage",[38,51,52],{},"Store outside web-accessible directory",[13,54,55],{},"For images, validate:",[57,58,59,62,65,68],"ul",{},[38,60,61],{},"Magic bytes match claimed type",[38,63,64],{},"Actually parseable as image",[38,66,67],{},"Dimensions within limits",[38,69,70],{},"Strip EXIF metadata (privacy)",[13,72,73],{},"Implementation:",[57,75,76,79,82,85],{},[38,77,78],{},"Use file-type library to check magic bytes",[38,80,81],{},"Use sharp or similar to validate/process images",[38,83,84],{},"Reject if validation fails",[38,86,87],{},"Never trust Content-Type header",[13,89,90,91,95],{},"Example allowlist:\nconst allowedTypes = ",[92,93,94],"span",{},"'image/jpeg', 'image/png', 'image/webp', 'application/pdf'",";\nconst maxSize = 5 * 1024 * 1024; // 5MB",[17,97,99],{"id":98},"secure-storage","Secure Storage",[13,101,102],{},"Copy this prompt to set up secure file storage with cloud providers or local filesystems. You'll get configuration for private S3/R2 buckets with signed URLs, safe filename generation, and proper content headers.",[25,104,106,109,112,120,123,137,140,151,154,157],{"title":105},"Store Files Safely",[13,107,108],{},"Set up secure file storage for uploads.",[13,110,111],{},"Storage options:",[35,113,114,117],{},[38,115,116],{},"Cloud storage (S3, Cloudflare R2) - recommended",[38,118,119],{},"Local filesystem outside webroot",[13,121,122],{},"For S3/R2:",[57,124,125,128,131,134],{},[38,126,127],{},"Private bucket with signed URLs for access",[38,129,130],{},"Separate bucket from application code",[38,132,133],{},"Set proper Content-Type on upload",[38,135,136],{},"Consider CDN for delivery",[13,138,139],{},"For local storage:",[57,141,142,145,148],{},[38,143,144],{},"Store outside public directory",[38,146,147],{},"Serve through application (not static)",[38,149,150],{},"Set Content-Disposition header",[13,152,153],{},"Filename handling:\nconst safeFilename = crypto.randomUUID() + '.jpg';\n// Never use user-provided filename",[13,155,156],{},"Serving files:\nres.setHeader('Content-Type', 'image/jpeg');\nres.setHeader('Content-Disposition', 'inline'); // or 'attachment' for downloads\nres.setHeader('X-Content-Type-Options', 'nosniff');",[13,158,159],{},"Never serve with user-controlled Content-Type.",[161,162,163],"warning-box",{},[13,164,165,169],{},[166,167,168],"strong",{},"Never trust file extensions:"," An attacker can name a PHP script \"innocent.jpg\". Validate by reading the file's magic bytes, not its name. And never store uploads where they can be executed.",[17,171,173],{"id":172},"image-processing-security","Image Processing Security",[13,175,176],{},"This prompt asks your AI to build a secure image processing pipeline using sharp. You'll get functions that validate dimensions, strip EXIF data, and re-encode uploads to sanitize embedded payloads.",[25,178,180,183,186,189,192,195,198,212],{"title":179},"Process Images Safely",[13,181,182],{},"Implement secure image processing for uploads.",[13,184,185],{},"Using sharp (Node.js):",[13,187,188],{},"async function processImage(buffer, options) {\nconst image = sharp(buffer);\nconst metadata = await image.metadata();",[13,190,191],{},"// Validate dimensions\nif (metadata.width > 4000 || metadata.height > 4000) {\nthrow new Error('Image too large');\n}",[13,193,194],{},"return image\n.resize(options.maxWidth, options.maxHeight, { fit: 'inside' })\n.rotate() // Auto-rotate based on EXIF\n.withMetadata(false) // Strip EXIF (removes location data!)\n.jpeg({ quality: 80 }) // Re-encode (sanitizes)\n.toBuffer();\n}",[13,196,197],{},"Benefits of re-encoding:",[57,199,200,203,206,209],{},[38,201,202],{},"Strips embedded scripts/payloads",[38,204,205],{},"Removes EXIF metadata (privacy)",[38,207,208],{},"Normalizes format",[38,210,211],{},"Validates image is actually valid",[13,213,214],{},"Always re-encode uploaded images rather than storing originals.",[17,216,218],{"id":217},"client-side-validation","Client-Side Validation",[13,220,221],{},"Use this prompt to add client-side file validation for a better upload experience. Your AI will generate JavaScript that checks file type and size before upload, with optional image preview functionality.",[25,223,225,228,231,242,245,248,251,254],{"title":224},"Frontend Upload UX",[13,226,227],{},"Add client-side file validation for better UX.",[13,229,230],{},"Note: This is for UX only - always validate server-side!",[13,232,233,234,237,238,241],{},"function validateFile(input) {\nconst file = input.files",[92,235,236],{},"0",";\nconst maxSize = 5 * 1024 * 1024; // 5MB\nconst allowedTypes = ",[92,239,240],{},"'image/jpeg', 'image/png', 'image/webp'",";",[13,243,244],{},"if (!file) return;",[13,246,247],{},"if (!allowedTypes.includes(file.type)) {\nshowError('Please upload a JPEG, PNG, or WebP image');\ninput.value = '';\nreturn;\n}",[13,249,250],{},"if (file.size > maxSize) {\nshowError('File must be under 5MB');\ninput.value = '';\nreturn;\n}",[13,252,253],{},"// Optional: preview image\nconst reader = new FileReader();\nreader.onload = (e) => previewImage(e.target.result);\nreader.readAsDataURL(file);\n}",[13,255,256],{},"Remember: Attackers bypass JavaScript. Server must validate too.",[258,259,260],"tip-box",{},[13,261,262,265],{},[166,263,264],{},"Pro tip:"," Use a dedicated service like Cloudflare Images or Imgix for image processing. They handle resizing, format conversion, and security, taking the burden off your servers.",[267,268,269,276],"faq-section",{},[270,271,273],"faq-item",{"question":272},"Can uploaded images contain malware?",[13,274,275],{},"Yes. Images can contain embedded scripts, exploit image parser vulnerabilities, or use polyglot techniques (valid image AND valid script). Re-encoding with a library like sharp sanitizes most threats.",[270,277,279],{"question":278},"Should I scan uploads for viruses?",[13,280,281],{},"For high-risk applications (user file sharing), yes. Use ClamAV or a cloud service. For images only, re-encoding is usually sufficient. For documents, consider sandboxed preview generation.",[17,283,285],{"id":284},"further-reading","Further Reading",[13,287,288],{},"Want to understand the vulnerability before fixing it? These guides explain what's happening and why.",[57,290,291,298,304],{},[38,292,293],{},[294,295,297],"a",{"href":296},"/blog/vulnerabilities/exposed-api-keys","Understanding exposed API keys",[38,299,300],{},[294,301,303],{"href":302},"/blog/how-to/hide-api-keys","How to hide API keys step-by-step",[38,305,306],{},[294,307,309],{"href":308},"/blog/best-practices/secrets","Secret management best practices",[311,312,313,319],"related-articles",{},[314,315],"related-card",{"description":316,"href":317,"title":318},"Input validation patterns","/blog/prompts/sanitize-user-input","Sanitize User Input",[314,320],{"description":321,"href":322,"title":323},"Form security","/blog/prompts/secure-forms","Secure Forms",[325,326,329,333],"cta-box",{"href":327,"label":328},"/","Start Free Scan",[17,330,332],{"id":331},"check-your-upload-security","Check Your Upload Security",[13,334,335],{},"Scan your file upload handling for vulnerabilities.",{"title":337,"searchDepth":338,"depth":338,"links":339},"",2,[340,341,342,343,344,345],{"id":19,"depth":338,"text":20},{"id":98,"depth":338,"text":99},{"id":172,"depth":338,"text":173},{"id":217,"depth":338,"text":218},{"id":284,"depth":338,"text":285},{"id":331,"depth":338,"text":332},"prompts","2026-02-25","2026-03-06","AI prompts to secure file upload functionality. Validate file types, scan for malware, and store uploads safely to prevent attacks.",false,"md",null,"cyan",{},true,"AI prompts to implement secure file upload handling.","/blog/prompts/secure-file-uploads","[object Object]","BlogPosting",{"title":5,"description":349},{"loc":357},"blog/prompts/secure-file-uploads",[364],"Frontend","summary_large_image","6Y7eQctwd8u0nfVL80Cs9NAkoxuqKf_t3ITM3maPtLE",1775843938168]