Upload Security Agent Skill
Upload security — magic byte validation, size limits, safe storage, random filenames.
The Skill
Full content, every format. Copy it, download it, or install with one command.
---
description: Upload security — magic byte validation, size limits, safe storage, random filenames.
homepage: https://yepapi.com/skills/upload-security
metadata:
tags: [security, uploads, files, validation]
---
# Upload Security
## Rules
- Validate file type by magic bytes (file signature), not just the extension or Content-Type header
- Enforce file size limits server-side: images (5MB), documents (10MB), general (1MB default)
- Generate random filenames with `crypto.randomUUID()` — never use the original filename
- Store uploads outside the webroot or in object storage (S3, R2) — never in `/public`
- Never execute or interpret uploaded files — treat all uploads as untrusted binary data
- Validate image dimensions to prevent pixel flood attacks (e.g., max 10000x10000)
- Scan uploads for malware in production with ClamAV or a cloud-based scanner
\`\`\`ts
// Magic byte validation
const FILE_SIGNATURES: Record<string, Buffer[]> = {
"image/jpeg": [Buffer.from([0xff, 0xd8, 0xff])],
"image/png": [Buffer.from([0x89, 0x50, 0x4e, 0x47])],
"image/gif": [Buffer.from([0x47, 0x49, 0x46, 0x38])],
"application/pdf": [Buffer.from([0x25, 0x50, 0x44, 0x46])],
};
function validateFileType(buffer: Buffer, expectedType: string): boolean {
const signatures = FILE_SIGNATURES[expectedType];
if (!signatures) return false;
return signatures.some((sig) => buffer.subarray(0, sig.length).equals(sig));
}
\`\`\`
\`\`\`ts
// Secure upload handler
import { randomUUID } from "node:crypto";
async function handleUpload(file: File) {
const buffer = Buffer.from(await file.arrayBuffer());
if (buffer.length > 5 * 1024 * 1024) throw new Error("File too large");
if (!validateFileType(buffer, file.type)) throw new Error("Invalid file type");
const ext = file.type.split("/")[1]; // derive from validated type, not filename
const safeName = `${randomUUID()}.${ext}`;
await uploadToS3(safeName, buffer);
return safeName;
}
\`\`\`
## Avoid
- Trusting the file extension — `malware.exe` renamed to `profile.jpg` bypasses extension checks
- Trusting the `Content-Type` header — clients set this to anything they want
- Storing uploads in a publicly served directory — uploaded HTML/SVG files execute as web pages
- Using the original filename — path traversal (`../../../etc/passwd`) and name collisions
- No file size limits — a 10GB upload crashes your server or fills your diskInstall
Why Use the Upload Security Skill?
Without this skill, your AI guesses at upload security patterns. It might hallucinate deprecated APIs, use outdated conventions, or miss best practices entirely. With it, your AI follows a proven ruleset — every suggestion aligns with current standards.
Drop this skill into your project and your AI instantly knows the rules. Better code suggestions, fewer errors, faster shipping.
Try These Prompts
These prompts work better with the Upload Security skill installed. Your AI knows the context and writes code that fits.
"Build a secure file upload handler with magic byte validation and random filenames"
"Add server-side file size limits and type validation to my upload endpoint"
"Create a file upload pipeline that stores files in S3 with proper security controls"
Works Great With
Upload Security skill — FAQ
It provides rules for magic byte file validation, server-side size limits, random filename generation, and safe storage outside the webroot. Your AI writes file upload code that prevents common attack vectors.
Run `npx skills add YepAPI/skills --skill upload-security` in your project root. This copies the skill file into your repo where your AI coding tool can read it automatically.
File extensions are trivially spoofed — renaming malware.exe to profile.jpg bypasses extension checks. Magic bytes (file signatures) are the actual binary header of the file, which is much harder to forge.