Skip to main content

Inbound media threat scan and quarantine model

Every inbound MMS attachment and every inbound email attachment passes through a byte-level threat scan before it is forwarded to an agent inbox, a vision agent turn, or archived into the message store. This page explains the scan model: what it inspects, how a verdict is banded, what each channel does with a blocked attachment, and how to read the quarantine marker on a message. This is the inbound counterpart of outbound composition checks. URL reputation, covered in POST /messages/url-scan, grades the destination URLs in a body you send; the threat scan below inspects the media BYTES a sender uploads to you — a different trust boundary.

Where inbound media crosses the trust boundary

Two inbound paths hand a sender-controlled payload to something a customer trusts:
  • MO SMS/MMS attachments — an MMS arrives carrying media URLs. Orbit downloads the bytes and, for image attachments, forwards them to the vision agent turn so the agent can reason over what the picture shows. That download-then-forward step is where a malicious payload would otherwise ride straight into the agent inbox.
  • Inbound email attachments — when an inbound email lands, its attachments are archived to the tenant media bucket and surfaced in the message detail view (see the inbound email parse guide). Archiving means re-hosting sender-controlled bytes on a durable URL, so a poisoned part would otherwise become a shareable link inside your inbox.
Both paths scan the decoded bytes before that forward/archive step, at the one place the payload crosses from “bytes a stranger sent” to “content an agent or a teammate opens.” Message body text that accompanies the media still processes — only the attachment itself is gated.

The scan model

The engine is a deterministic, offline heuristic scorer. It needs no external credential and no third-party feed to run, and its additive weights and band thresholds are pinned by tests so the verdict for a given payload never drifts. It inspects three signal families: File signatures (magic bytes). The first bytes of the payload are matched against known-dangerous families, up to the first 512 KB of the attachment:
  • The EICAR standard anti-virus test signature — every AV engine flags it; an attachment carrying it is quarantined identically to real malware.
  • Native executables: Windows PE/MZ headers, Linux ELF headers, macOS Mach-O and Java class headers.
  • Windows .lnk shell-link launchers, and script #! shebangs.
  • OLE2 compound documents (legacy macro-capable Office) and OOXML packages carrying an embedded vbaProject.bin (macro payload).
  • PDFs with active content: /JavaScript, /Launch, /OpenAction, /EmbeddedFile.
  • Markup payloads (SVG, HTML, XHTML/XML) embedding <script> blocks, inline event handlers, javascript: URIs, or PHP code.
Declared metadata. The declared Content-Type and the filename extension are scored independently: a declared executable/installer/script type (application/x-msdownload, application/x-sh, Java archive, MSI, PHP, …) or an extension like .exe, .scr, .bat, .ps1, .jar, .apk is a strong signal on its own. Macro-enabled Office extensions (.docm, .xlsm, .pptm, …) score lower but still flag. Archive containers (.zip, .dmg, …) are a mild signal — common in smuggling chains. Spoofing. The cross-signal checks catch the classic delivery tricks:
  • The declared type says image/jpeg but the magic bytes are an executable, archive, or document (magic-type-mismatch).
  • The declared type is binary media but the bytes are markup (html-disguised-as-media).
  • Deceptive double extensions — invoice.pdf.exe, photo.jpg.scr — where a safe-looking decoy extension sits in front of the real one.
External verdicts. When the platform operator wires a real AV engine (ClamAV, VirusTotal, or a similar feed), its verdict is injected as the dominant signal — a malicious external verdict maxes the score. The heuristic layer remains the always-on baseline beneath it, exactly as the URL-reputation model treats external verdicts.

Bands and recommendations

Each finding adds points; the composite score caps at 100 and maps to three bands: The verdict carries a transparent finding list — for every signal, a machine-readable code, a severity, the points it contributed, and a human explanation — so you (or we) can see exactly why a verdict landed without reading the payload. Three outcomes follow from the bands:
  1. Quarantine (malicious). The attachment is dropped. On the vision-agent path the agent turn still proceeds with the text-only body; on the email path the part is never uploaded to the media bucket. Quarantined bytes are never re-hosted, and the block is recorded with finding codes only — no payload and no sender content — so the audit trail stays PII-safe.
  2. Suspicious. The attachment is still delivered, but a warn log is emitted with the band, score, and finding codes so a security reviewer can pull the record. This is an advisory, not a block.
  3. Clean. Delivered exactly as before the model existed.

Channel behavior split

The same engine gates both inbound paths; the divergence is in what “dropped” looks like per channel. MMS / vision-agent path. The scan runs on the downloaded attachment bytes inside the inbound webhook pipeline, after inbound message routing has resolved the tenant and the AI enrichment chain selected the target. A quarantine verdict only affects the media object: the message, its metadata, and a text-only agent turn all proceed — the payload is never forwarded to the vision agent. Inbound email path. Each attachment part of an inbound email is scanned individually in the background archiver. A part with action quarantine is dropped; a part with action allow (clean or advisory-suspicious) is archived to the tenant bucket with the standard 7-day signed URL and surfaced in the message detail view. Dropped parts are recorded on the message’s metadata.email_attachments_quarantined list — filename, declared content-type, size, score, band, and finding codes — so the block is visible on the audit trail without re-hosting anything dangerous.

Observability

  • The inbound_media_threat_quarantined_total counter increments per dropped MMS attachment, labeled by channel, with an email_inbound_attachment_skipped_total counter for the email path (reason: threat_quarantined).
  • Every quarantine and every suspicious hit emits a warn log carrying the band, composite score, and finding codes.
There is deliberately no tenant-facing config knob: the gate is a platform baseline control, like the generic upload allow-list, not a per-org toggle. Organizations that want stricter verdicts can have the operator wire an external AV verdict feed into the scan — that feed then dominates the heuristic baseline, without any change to the channel behavior above.

The customer contract

A quarantined attachment is not a lost message. The envelope, sender, body text, and any remaining attachments all route and resolve normally — only the blocked part is absent. When an inbox shows a message that references a media object that never renders, check for the quarantine marker before reprocessing the message. Reading the marker. On inbound email messages, open the message’s metadata.email_attachments_quarantined list. Each entry names the dropped part (filename, declared type, size), the score and band, and the machine codes of the findings that tripped it — enough to decide whether to ask the sender to resend in a safer format. metadata.email_attachments carries only the parts that survived. How this differs from the other content gates. Threat scanning is about the payload bytes, not the content’s policy posture. RCS and WhatsApp content-policy moderation (which judges what the content says, e.g. prohibited categories) runs on a different surface entirely, and URL reputation on composed outbound bodies runs through the composes-side POST /messages/url-scan endpoint. None of these layers substitute for the others.

Cross-references