Securing File Uploads: Implementing Mime-Type Validation in CRM SaaS
In our crm-saas-backend project, we recently hit a bottleneck regarding data ingestion. Our users need to bulk-import client lists, and the system needed a robust way to ensure that only expected file formats enter our processing pipeline. Allowing arbitrary files is like inviting a stranger into your home without checking their ID—you never know what kind of malicious payload might follow.
The Problem: Trusting Client Input
When building a file import feature, the most common trap is relying solely on the file extension (like .csv or .xlsx) provided by the client's browser. Since headers can be easily spoofed, we needed a strategy that prioritizes the file's true content over its label.
The Solution: Enforcing Type Safety at the Gateway
To address this, we implemented a new endpoint POST /clients/import within our NestJS architecture. Instead of just accepting a binary stream, we introduced a validation layer that checks the MIME type before the data ever reaches our domain logic. By leveraging the framework's pipes, we ensure the request fails early if the file type is unsupported.
@Post('import')
@UseInterceptors(FileInterceptor('file'))
async importClients(
@UploadedFile(new ParseFilePipe({
validators: [
new FileTypeValidator({ fileType: 'text/csv' }),
],
})) file: Express.Multer.File,
) {
return this.clientService.processImport(file);
}
Why Hexagonal Matters Here
By following our Hexagonal Architecture, this validation lives at the application edge (the 'adapter' layer). This keeps our core business services clean. The service layer doesn't need to know if the file came from an API request, a CLI command, or a background worker; it only cares about the sanitized data handed to it by the domain logic.
Takeaways for Robust Imports
- Never Trust the Client: Always perform server-side validation of file metadata.
- Fail Fast: Use framework-level pipes to stop invalid requests before they consume resources.
- Sanitize Early: Keep validation logic at the boundaries of your architecture to protect your inner business services.
Generated with Gitvlg.com