agentsclimarketplace

File upload security

Skill ShieldNet-360/secure-vibe/dist/copilot-skills/.github/skills/file-upload-security

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 servingFrom its SKILL.md

Install
npx -y skills add ShieldNet-360/secure-vibe --skill file-upload-security

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 15 stars15 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.

SKILL.md

4.7 KB, ~1.0k tokens by cl100k_base, as published. Nobody here has run it

<!-- Native skill bundle for GitHub Copilot. Generated by `secure-vibe dev regenerate`. --> <!-- Do not edit by hand; the source of truth is skills/file-upload-security/SKILL.md. -->

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-Type and 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, including text/html, image/svg+xml (carries <script>), text/xml, and application/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. Set Content-Disposition: attachment for non-image types and a Content-Security-Policy: default-src 'none'; sandbox header 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 strict policy.xml), ffmpeg -i for video, pdftocairo for 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.clean in Python) that strips <script>, <iframe>, <foreignObject>, xlink:href with javascript:, and CSS expression / url() with non-data URIs.

NEVER

  • Trust Content-Type from the client. The mime sniffer in IE / older Chrome reads the body for type clues — an HTML payload disguised as image/png will 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.html means 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 / .zip extraction with unzip or python -m zipfile without 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-Type signed 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.

What ships with it: 1 file

1.0 KB alongside SKILL.md

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.