Skip to content
Naandalist
•
3 min read
•
v2.0.0
secure-file-validator

secure-file-validator

Zero-dependency Node.js helper for upload type checks: extension, size, magic numbers, plus a small PDF and SVG content policy.

Aligned with the file-type checking part of OWASP Unrestricted File Upload and CWE-434. Not an antivirus. Not a complete upload-security stack.

Features

  • Extension, size, and magic-number validation
  • PDF name-token policy (including hex-escaped names and Flate streams)
  • SVG policy for script, javascript:, event handlers, and risky embeds
  • Path or buffer / Uint8Array input
  • Stable result codes for branching in app code
  • Zero dependencies (Node.js 14.16+, ESM)

Installation

npm install secure-file-validator

Usage

Quick start

import { validateFile } from "secure-file-validator";

const result = await validateFile("uploads/photo.jpg");

if (result.ok) {
  // result.code === "OK"
} else {
  // result.code === "INVALID_SIGNATURE" | "PDF_JAVASCRIPT" | ...
  console.error(result.code, result.message);
}

result.status still exists as a deprecated alias of result.ok.

From an upload buffer

import { validateFile, validateBytes } from "secure-file-validator";

const result = await validateFile(req.file.buffer, {
  filename: req.file.originalname, // or extension: ".png"
});

if (!result.ok) {
  throw new Error(result.code);
}

const sync = validateBytes(req.file.buffer, { extension: ".png" });

Buffer / Uint8Array input must include filename or extension. Size is checked with byteLength.

Supported types

Extension Magic check
.jpg / .jpeg FF D8 FF
.png 89 50 4E 47
.gif 47 49 46 38
.pdf %PDF + %%EOF, then token policy
.svg <?xml or <svg, then SVG policy

Default size cap: 5MB (options.maxSizeInBytes).

PDF policy

Token Default code
/Metadata allow PDF_METADATA
/Annots allow PDF_ANNOTS
/OpenAction allow PDF_OPEN_ACTION
/JS, /JavaScript deny PDF_JAVASCRIPT
/Launch deny PDF_LAUNCH
/EmbeddedFile deny PDF_EMBEDDED_FILE
/XFA deny PDF_XFA
/RichMedia deny PDF_RICH_MEDIA
const strict = await validateFile(pdfPath, {
  pdf: { allowOpenAction: false },
});

// Dangerous: turns the script check off
const trusted = await validateFile(pdfPath, {
  pdf: { allowJavaScript: true },
});

SVG policy

Always denied: <script>, javascript:, event handlers (onload= …), <!ENTITY.

Denied by default, overridable with options.svg:

Rule Default code
foreignObject deny SVG_FOREIGN_OBJECT
data: URI deny SVG_DATA_URI
external href deny SVG_EXTERNAL_HREF
await validateFile(svgPath, {
  svg: { allowDataUri: true },
});

Result shape

{
  ok: false,
  status: false, // deprecated alias of ok
  code: "PDF_JAVASCRIPT",
  message: "Suspicious PDF name token detected: /JavaScript",
  details: { token: "JavaScript" }
}

License

MIT

For more details, please visit the GitHub repository.