File Signature 🛡️
Don't trust the file extension. Trust the bits.
file_signature is a pure Dart security utility that validates files by checking their Magic Bytes (Hex Signatures). It prevents "Rename Attacks" (e.g., renaming malware.exe to image.png) and works universally on Mobile, Web, and Desktop.
Supported Formats
Images
Documents & Archives
Video
Blocked Threats
🚀 Features
- 🔒 Security First: Validates the actual binary header, not the text extension.
- ⚡ Zero-Allocation Streams: Intercepts and guards large file uploads (GBs) without loading them into RAM.
- 🌐 Universal: Works on Android, iOS, Web, macOS, Windows, and Linux.
- 📦 Lightweight: Zero dependencies on native code.
📦 Installation
dependencies:
file_signature: ^1.0.0
🛠️ Usage
1. The Standard Check (XFile)
Ideal for image_picker or file_selector. It reads only the first 32 bytes.
import 'package:file_signature/file_signature.dart';
Future<void> uploadAvatar(XFile file) async {
try {
// Validates that the file is genuinely a PNG or JPEG
await FileSignature.guard(
file,
allowed: [FileFormat.png, FileFormat.jpeg],
);
// If code reaches here, the file is safe!
print("File verified.");
} on SecurityException catch (e) {
print("Blocked: ${e.message}");
}
}
2. The Stream Interceptor ("Middleware")
Ideal for large uploads (Video/PDF) or network piping. It peeks at the header and kills the stream if it's malicious.
Future<void> secureUpload(Stream<List<int>> dangerousStream) async {
try {
// This returns a safe stream.
// If the header is bad, the stream emits an error immediately.
final safeStream = FileSignature.guardStream(
dangerousStream,
allowed: [FileFormat.pdf],
);
// Pass 'safeStream' to Dio, HTTP, or AWS S3
await Dio().post('[https://api.com/upload](https://api.com/upload)', data: safeStream);
} on SecurityException catch (e) {
print("Malware upload attempt blocked!");
}
}
3. Memory Check (Uint8List)
Ideal for clipboard data or Base64 strings.
void checkClipboard(Uint8List data) {
if (FileSignature.isValid(data, allowed: [FileFormat.png])) {
print("Valid Image");
}
}
🛡️ Supported Formats
We support the most critical formats for upload security:
| Category | Formats |
|---|---|
| Images | PNG, JPEG, GIF, WebP, BMP |
| Documents | |
| Archives | ZIP (covers DOCX, APK, JAR, etc.) |
| Blocklist | EXE, ELF, Mach-O (Executables) |
❓FAQ
Q: Why not just check file.path.endsWith('.png')? A: Because anyone can rename virus.exe to virus.png. The OS will hide the extension, but the file is still an executable. file_signature reads the actual binary header (e.g., 89 50 4E 47) to confirm the type.
Q: Does this download the whole file? A: No. It uses Dart's openRead(0, 32) to fetch only the first 32 bytes. Validating a 10GB video takes milliseconds.
Q: Does it work on Web? A: Yes. It fully supports Blob slicing on the web.
🤝 Contributing
Found a new magic byte signature? PRs are welcome! ensuring the package remains lightweight is our priority.
Libraries
- file_signature
- File Signature