Attachments you should refuse before they reach the parser
Accepting any attachment is a decision to run a parser on bytes a stranger chose. The cheap defences are at the boundary: extension and content-type allowlists, size caps, and a hard limit on the number of parts.
Accepting any attachment is a decision to run a parser on bytes a stranger chose. The cheap defences are at the boundary: extension and content-type allowlists, size caps, and a hard limit on the number of parts.
Trust the decoded bytes, not the header
The Content-Type header is a claim. Check the magic bytes after decoding: a file named invoice.pdf that starts with PK is a zip, and a file named photo.jpg that starts with MZ is a Windows executable. Both are worth rejecting before anything else looks at them.
The zip bomb is a multipart message
A single attachment can expand from kilobytes to gigabytes when decompressed. If you unpack archives, cap the decompressed size and the file count, and stop the moment either is exceeded. Decompressing into a temp directory without a cap is how a container fills its disk.
Encrypted archives and macro documents
A password-protected zip cannot be scanned and exists specifically to defeat scanning. Reject it or quarantine it for manual review, but do not silently accept it. Office documents with macros belong in the same bucket.
One operational detail
Scan asynchronously but deliver the message synchronously with a quarantine flag. Blocking the inbound webhook on a virus scan makes the sender's timeout your timeout, and the sender will retry, producing duplicates.
Volanea enforces size and part-count limits at the API boundary and returns attachments as URLs, so scanning happens after the message is safely stored.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.