File upload security
Skill ShieldNet-360/secure-vibe/dist/agent-skills/.agents/skills/file-upload-security
SecureVibe — prevention-first security for AI-written code. Signed SKILL.md knowledge that makes AI coding assistants write secure code at generation time, plus a deterministic CI gate. Offline · keyless · Ed25519-signed. By ShieldNet360.
npx -y skills add ShieldNet-360/secure-vibe --skill file-upload-securityAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Validate user uploads: MIME magic bytes, filename sanitization, size limits, separate serving domain, AV scanning, polyglot detection — Applies to: when generating an HTTP file-upload endpoint; when wiring presigned-URL upload to S3 / GCS / Azure Blob; when adding image/PDF/document processing of user uploads; when reviewing user-generated-content storage and serving
SKILL.md
4.7 KB, as published. Nobody here has run it
File Upload Security
Validate user uploads: MIME magic bytes, filename sanitization, size limits, separate serving domain, AV scanning, polyglot detection
ALWAYS
- Verify magic bytes of every upload server-side.
Content-Typeand file extension are attacker-controlled and never sufficient. Use libmagic,file-type(Node),mimetypes-magic(Python), or Tika. - Maintain an allowlist of accepted types per endpoint (
image/png,image/jpeg,application/pdf, …). Deny everything else, includingtext/html,image/svg+xml(carries<script>),text/xml, andapplication/octet-stream. - Sanitize filenames: strip directory components, normalize Unicode, reject
.., NUL byte, control chars, reserved Windows names (CON,PRN,AUX,NUL,COM1-9,LPT1-9), and any non[a-zA-Z0-9._-]characters. Store as a UUID / hash and keep the original filename in a separate, escaped metadata column. - Enforce a size limit at the proxy / API gateway and at the application — at least double-layer. The proxy limit prevents bandwidth DoS; the app limit prevents memory exhaustion when a proxy is misconfigured.
- Store uploads outside the document root and serve them from a separate domain (
usercontent.example.net) on a CDN. SetContent-Disposition: attachmentfor non-image types and aContent-Security-Policy: default-src 'none'; sandboxheader to neutralize any inline-rendered HTML/SVG. - Run a virus scanner (ClamAV, VirusTotal, Sophos) on every upload before making it accessible to other users — out of band so the request itself isn't latency-bound.
- Re-encode media server-side:
convert in.jpg out.jpg(ImageMagick with a strictpolicy.xml),ffmpeg -ifor video,pdftocairofor PDFs. Re-encoding strips most polyglot / steganographic payloads and exotic codec exploits. - For SVG specifically: either render server-side to a raster format, or pass through a strict allowlist sanitizer (DOMPurify in Node,
lxml.html.cleanin Python) that strips<script>,<iframe>,<foreignObject>,xlink:hrefwithjavascript:, and CSS expression / url() with non-data URIs.
NEVER
- Trust
Content-Typefrom the client. The mime sniffer in IE / older Chrome reads the body for type clues — an HTML payload disguised asimage/pngwill run as HTML when served same-origin. - Construct the storage path with the user-supplied filename. Path traversal (
../../etc/passwd) and the Windows reserved-name class both reduce to "let attacker pick where to write." - Serve uploads from the same origin as the application. Serving on
api.example.com/uploads/x.htmlmeans a malicious HTML upload runs with full access to api.example.com cookies and CORS. - Use a stack that processes uploads with ImageMagick / libraw / ExifTool / ffmpeg without strict policy.xml / sandbox / version control. ImageTragick (CVE-2016-3714) and GitLab ExifTool (CVE-2021-22205) both relied on a server happily handing user-controlled bytes to a media library.
- Allow PDF upload + render in-browser without verifying the PDF passes structural validation (e.g.
pdfinfo). Malicious PDFs are a common JavaScript-in-PDF / XFA RCE primitive against Adobe Reader on the recipient side, even when the server is safe. - Use
.docx/.xlsx/.zipextraction withunziporpython -m zipfilewithout a path-traversal-safe extractor. Zip slip (CVE-2018-1002201) extracted files outside the target directory through../entries. - Use S3 / GCS presigned upload URLs without a strict
Content-Typesigned condition and a fixed object-key prefix. Without the conditions, the client can upload anything to any key.
KNOWN FALSE POSITIVES
- Internal-only admin uploads (e.g. an ops dashboard) may legitimately trust file extension because the trust boundary is the SSO + IP allowlist. Document this as a deliberate decision in the endpoint.
- Some integrations (e.g. exporting CSV from BI tools) need to round-trip user-supplied filenames; preserve them in metadata, but the on-disk name must still be a UUID.
- Tarballs / DEBs / RPMs in a build pipeline don't need AV scan — the trust boundary is the build pipeline's signing key, not the AV.