Skip to content
machinemail

Attachments

How MachineMail rates inbound attachments as low, medium or high risk from their extension, declared content type and actual bytes, and which attachments get extracted text.

Every attachment gets an entry in trust.attachments with a risk of low, medium or high, the reasons behind it, and for text-like files the extracted_text.

json
{
  "attachment_id": "att_...",
  "filename": "invoice.pdf.exe",
  "content_type": "application/pdf",
  "risk": "high",
  "reasons": ["Executable or script file type .exe", "Double extension .pdf.exe disguises the real file type", "Content confirmed as Windows executable (PE)"]
}

Risk is decided from three things: the file name, the content type the sender declared, and the first bytes of the file itself. The highest risk any check raises wins.

High risk

CheckExample reason
Executable or script extension: .exe, .scr, .bat, .cmd, .msi, .dll, .jar, .js, .vbs, .hta, .ps1, .sh, .app, .apk, .lnk, .iso, .img, .vhd, .dmg, .pkg, .one, .py, .chm, .url, .reg and about sixty moreExecutable or script file type .exe
Macro-enabled Office file: .docm, .xlsm, .pptm, .xlsb and similarMacro-enabled Office document .docm
HTML or SVG file: .html, .htm, .svg, .mht and similar, which can render a fake sign-in page locally.html attachment can render a credential-harvesting page locally
Double extension hiding the real typeDouble extension .pdf.exe disguises the real file type
Name padded with spaces before the extensionFilename padded with whitespace to hide the extension
Right-to-left override character in the name, which makes an .exe display as if it ended in .pdfFilename contains a right-to-left override that disguises the real extension
Executable content type, such as application/x-msdownload or anything JavaScript, VBScript, Python or PerlExecutable content type application/x-msdownload
text/html content attached under a non-HTML nameHTML content attached as a file
Bytes that are a Windows, Linux or macOS executable under a non-executable nameFile content is a Windows executable (PE) despite its .pdf name
Bytes that are a Windows shortcut, a disk image, a #! script or HTML under another nameFile content is a disk image
An Office file containing a VBA macro projectOffice document contains a VBA macro project
A PDF with a /Launch actionPDF contains a Launch action

Medium risk

CheckExample reason
Archive: .zip, .rar, .7z, .gz, .tar and similar, which can hide executables from scannersArchive .zip can hide executables from scanners
Legacy Office format: .doc, .xls, .ppt, .rtf and similarLegacy Office format .doc can carry macros or exploits
Archive content type under a non-archive nameArchive content type application/zip
Bytes of one known type under another type’s extensionFile content is PDF but the name says .docx
A PDF containing JavaScript or embedded filesPDF contains JavaScript
Declared content type that does not match the extensionContent type text/plain does not match .pdf
An unnamed binary attachmentUnnamed binary attachment

Everything else, such as an ordinary PDF, PNG or DOCX whose bytes match its name, is low.

Extracted text

extracted_text is filled for attachments MachineMail can read as text:

  • plain text, CSV, Markdown, calendar (.ics) and log files
  • JSON, pretty-printed
  • HTML, rendered to text

Invisible characters are removed from the extracted text and it is cut at 100,000 characters. Up to 20,000 characters of extracted text across all attachments is scanned by the classifier, so instructions to an AI hidden in an attached file raise contains_instructions_to_agent just as they would in the body.

Note

Text extraction from PDF and Office documents is not yet available. Those attachments get a risk rating but no extracted_text.

How attachments feed the verdict

  • A high risk attachment makes the message at least suspicious.
  • The attachments component is 10% of the score: 1 with only low-risk attachments, 0.6 with a medium-risk one, 0 with a high-risk one.
  • High-risk attachments raise is_phishing, HTML attachments most of all.
  • Reasons for medium and high risk attachments are copied into the top-level trust.reasons as Attachment invoice.pdf.exe: ....

Using attachment reports in an agent

Download an attachment with GET /v0/inboxes/{inbox_id}/messages/{message_id}/attachments/{attachment_id} only when the task needs it, and check its report first:

ts
const report = message.trust.attachments.find((a) => a.attachment_id === attachmentId);
if (!report || report.risk !== 'low') throw new Error('Refusing to open a risky attachment');

Prefer extracted_text over opening the file yourself, and treat it as untrusted content, exactly like the body.