How to Handle File Uploads Securely in an API

File upload endpoints are a common attack vector if not implemented carefully — this guide covers the key security considerations for handling user-uploaded files safely.

Why File Uploads Are High-Risk

An upload endpoint accepts arbitrary user-controlled content, potentially including malicious files (malware, scripts disguised as innocuous file types) or content designed to exploit processing vulnerabilities — treat every upload as untrusted input requiring careful validation.

Validating File Type Correctly (Not Just Trusting the Extension)

const fileType = require('file-type');
const type = await fileType.fromBuffer(uploadedBuffer);
if (!['image/jpeg', 'image/png'].includes(type?.mime)) {
  throw new Error('Invalid file type');
}

Never trust a file's claimed extension or client-provided MIME type alone — verify actual file content/magic bytes match the expected type, since a malicious file can easily be renamed to appear as an allowed type.

Enforcing a File Size Limit

app.use(express.json({ limit: '5mb' }));

Prevent excessively large uploads that could exhaust disk space or memory — set a reasonable limit based on your genuine use case's needs.

Never Execute or Directly Serve Uploaded Files from the Same Domain

Storing and serving uploaded files from the same domain/origin as your application creates risk (a malicious uploaded HTML/SVG file could execute in a browser under your domain's origin) — serve user uploads from a separate domain/subdomain, or object storage (see How to Use Object Storage for Application File Uploads) with appropriate content-type headers preventing execution.

Generating New Filenames, Never Trusting User-Provided Names

const crypto = require('crypto');
const newFilename = crypto.randomUUID() + path.extname(originalFilename);

Never use a user-supplied filename directly for storage — risks path traversal attacks (a filename like ../../etc/passwd) and filename collisions; generate a new, safe filename server-side.

Scanning Uploads for Malware

clamdscan /path/to/uploaded/file

See How to Scan for Malware with ClamAV — for applications accepting uploads from untrusted users, scanning uploaded files before storage/processing adds a meaningful additional protection layer.

Storing Uploads Outside the Web Root

If storing locally (rather than object storage), ensure uploaded files aren't stored directly within a web-server-served directory where they could be directly requested/executed — store outside the web root and serve through application logic with appropriate access control.

Setting Appropriate Content-Disposition Headers

Content-Disposition: attachment; filename="download.pdf"

For files that shouldn't be rendered inline in a browser (particularly anything user-uploaded), setting attachment disposition forces download rather than inline rendering, reducing certain content-based attack vectors.

Rate Limiting Upload Endpoints

See How to Rate Limit an API with Nginx — upload endpoints are a natural target for abuse (storage exhaustion, resource consumption); apply appropriate rate limiting specific to this endpoint.

Common Errors

Uploaded image processing crashes or hangs — image/file processing libraries have historically had vulnerabilities exploitable via crafted malicious files; keep processing libraries updated, and consider processing uploads in an isolated/sandboxed context given this risk.

Continue Reading

Browse more articles in Object Storage, Messaging & APIs.

  • secure file upload api, file upload validation, prevent malicious file upload, file upload security best practices
  • 0 Корисниците го најдоа ова како корисно
Дали Ви помогна овој одговор?

Понудени резултати

How to Set Up Self-Hosted S3-Compatible Object Storage with MinIO

MinIO is a high-performance, self-hosted object storage server compatible with the S3 API —...

How to Use Object Storage for Application File Uploads

Storing user-uploaded files directly on your application server's disk creates scaling and...

How to Install and Configure RabbitMQ on a VPS

RabbitMQ is a widely-used, robust message broker — enabling applications to communicate...

How to Install and Configure Redis as a Message Queue

Redis, primarily known as a cache, also works well as a lightweight message queue for simpler use...

How to Build and Secure a REST API on a VPS

This guide covers the essential security and architecture practices for deploying a REST API on...