secure-file-validator

A secure file validation library for Node.js that performs signature checking and content validation. It hardenings app from malicious file uploads by validating file types, checking file signatures, and scanning for suspicious patterns.
This library is built following industry-standard security guidelines:
Features
- Secure file signature validation
- Content pattern scanning for malicious code
- Support for multiple file types (JPEG, PNG, GIF, PDF, SVG)
- Built-in security checks for PDF and SVG files
- Whitelist feature to handle false positive detections
- Zero dependencies
- Customizable file size validation
Installation
npm install secure-file-validator
Usage
Basic Usage (Default 5MB limit)
import { validateFile } from "secure-file-validator";
try {
const result = await validateFile("path/to/your/file.pdf");
if (result.status) {
console.log("File is valid:", result.message);
} else {
console.log("File validation failed:", result.message);
}
} catch (error) {
console.error("Error:", error);
}
Custom File Size Limit
import { validateFile } from "secure-file-validator";
const TEN_MB = 10 * 1024 * 1024;
try {
const result = await validateFile("path/to/your/file.pdf", {
maxSizeInBytes: TEN_MB,
});
if (result.status) {
console.log("File is valid:", result.message);
} else {
console.log("File validation failed:", result.message);
}
} catch (error) {
console.error("Error:", error);
}
PDF Whitelist for False Positive Handling
The library includes security checks for potentially dangerous PDF patterns. However, some legitimate PDFs may contain patterns like /Metadata/, /OpenAction/, or /JS/ that are flagged as suspicious. You can use the pdfWhitelist option to allow specific patterns:
import { validateFile } from "secure-file-validator";
const result = await validateFile("path/to/file.pdf", {
pdfWhitelist: ['Metadata', 'OpenAction', 'JS']
});
if (result.status) {
console.log("File is valid:", result.message);
} else {
console.log("File validation failed:", result.message);
}
Available PDF patterns to whitelist:
Metadata - PDF metadata (commonly found in legitimate PDFs)
OpenAction - Automatic actions when PDF is opened
JS - JavaScript abbreviation
JavaScript - JavaScript code
Launch - Launch actions
EmbeddedFile - Embedded files
XFA - XML Forms Architecture
Annots - Annotations
Note: Only whitelist patterns you trust. Whitelisting patterns reduces security checks and should be done carefully based on your specific use case.
Using Size Constants
const KB = 1024;
const MB = 1024 * KB;
const GB = 1024 * MB;
const options = {
maxSizeInBytes: 10 * MB,
};
const result = await validateFile("path/to/file.pdf", options);
Advanced Usage
import {
validateFile,
validateFileContent,
checkFileSignature,
} from "secure-file-validator";
async function validateUserUpload(filePath) {
const options = {
maxSizeInBytes: 15 * 1024 * 1024,
};
const fileValidation = await validateFile(filePath, options);
if (!fileValidation.status) {
return fileValidation;
}
const contentValidation = await validateFileContent(filePath, options);
return contentValidation;
}
async function validatePDFWithWhitelist(filePath) {
const result = await validateFile(filePath, {
maxSizeInBytes: 10 * 1024 * 1024,
pdfWhitelist: ['Metadata', 'OpenAction'],
});
return result;
}
Supported File Types
| Images | JPEG/JPG |
| Images | PNG |
| Images | GIF |
| Documents | PDF |
| Vector Graphics | SVG |
API Reference
validateFile(filePath, options)
Main validation function that performs all checks.
filePath | string | Path to the file to validate | required |
options | Object | Configuration options | {} |
options.maxSizeInBytes | number | Maximum file size in bytes | 5MB |
options.pdfWhitelist | string[] | Array of PDF patterns to whitelist (e.g., ['Metadata', 'JS']) | [] |
Promise<Object> | Async result object |
Promise<Object>.status | boolean indicating validation result |
Promise<Object>.message | string containing detailed message |
validateFileContent(filePath, options)
Performs content-specific validation.
filePath | string | Path to the file to validate | required |
options | Object | Configuration options | {} |
options.pdfWhitelist | string[] | Array of PDF patterns to whitelist (e.g., ['Metadata', 'JS']) | [] |
Promise<Object> | Async result object |
Promise<Object>.status | boolean indicating validation result |
Promise<Object>.message | string containing detailed message |
checkFileSignature(buffer, signatures)
Checks file buffer against known signatures.
buffer | Buffer | File buffer to check | required |
signatures | Array<Array<number>> | Valid signatures to check against | required |
boolean | True if signature matches, false otherwise |
File Size Configuration
The file size limit is configurable through the maxSizeInBytes option:
const limits = {
small: 1 * 1024 * 1024,
medium: 10 * 1024 * 1024,
large: 100 * 1024 * 1024,
custom: 15.5 * 1024 * 1024,
};
const result = await validateFile("file.pdf", {
maxSizeInBytes: limits.medium,
});
Example Results
{
status: true,
message: "Content validation passed"
}
{
status: false,
message: "File size exceeds limit of 5MB"
}
{
status: false,
message: "Invalid file extension"
}
{
status: false,
message: "Suspicious pattern detected: /<script/i"
}
Limitations
- Only supports specified file types
- No stream processing support
- Binary file content is not deeply analyzed
- Pattern matching is done on string representation of files
Error Handling
try {
const options = { maxSizeInBytes: 10 * 1024 * 1024 };
const result = await validateFile("path/to/file.pdf", options);
if (!result.status) {
console.error("Validation failed:", result.message);
}
} catch (error) {
console.error("System error:", error.message);
}
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
FAQ
Q: How can I set a custom file size limit?
A: You can pass the limit in bytes using the options parameter:
const limit = 10 * 1024 * 1024;
const result = await validateFile("file.pdf", { maxSizeInBytes: limit });
Q: What's the default file size limit?
A: The default limit is 5MB if no custom limit is specified.
Q: Can I set unlimited file size?
A: While technically possible by setting a very large number, it's not recommended as files are read into memory during validation.
Q: I'm getting false positives on legitimate PDFs. What should I do?
A: Some legitimate PDFs contain patterns like /Metadata/ or /OpenAction/ that are flagged as suspicious. You can use the pdfWhitelist option to allow these specific patterns:
const result = await validateFile("file.pdf", {
pdfWhitelist: ['Metadata', 'OpenAction', 'JS']
});
Only whitelist patterns you understand and trust, as this reduces security checks.
Q: How can I handle different size limits for different file types?
A: You can create a wrapper function:
async function validateWithTypeLimit(filePath) {
const extension = path.extname(filePath).toLowerCase();
const limits = {
".pdf": 10 * 1024 * 1024,
".jpg": 5 * 1024 * 1024,
".svg": 2 * 1024 * 1024,
};
return validateFile(filePath, {
maxSizeInBytes: limits[extension] || 5 * 1024 * 1024,
});
}
License
This project is licensed under the MIT License
Thank you 😀