Sign in

Outputs

fstab-decode — 5,480 bytes of x86 ELF from a Linux distribution — exports as a SARIF log carrying 26 results. Twenty-three are CVEs — twenty-one against glibc, two against the minimum kernel ABI the binary declares in its .note.ABI-tag — and every one is marked floor_only: unconfirmable. Two are build-posture facts about the whole image. Exactly one names an address inside the program's own code.

{
  "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
  "version": "2.1.0",
  "runs": [{
    "tool": { "driver": {
      "name": "openbinary",
      "informationUri": "https://openbinary.ai",
      "version": "0.11.0", "semanticVersion": "0.11.0",
      "rules": [ /* 26 entries — one per rule that fired, and nothing else */ ]
    }},
    "artifacts": [{
      "location": { "uri": "002556361f8e06ec…" },
      "roles": ["analysisTarget"],
      "hashes": { "sha-256": "002556361f8e06ec5ff0761777bbe5283030eaab4ccee4c5ea6994147ff765fe" }
    }],
    "results": [
      {
        "ruleId": "command-exec.execvp",
        "level": "warning",
        "message": { "text": "Calls execvp(): PATH-search exec with array args. Same PATH-traversal exposure as execlp(); attacker control of PATH yields code execution." },
        "locations": [{ "physicalLocation": {
          "address": { "absoluteAddress": 1232, "kind": "function", "fullyQualifiedName": "sub_540" },
          "artifactLocation": { "uri": "002556361f8e06ec…" }
        }}],
        "properties": { "cwe_id": 78, "confidence": "medium",
                        "detector": "static-rule", "reachable_from_main": false }
      },
      {
        "ruleId": "CVE-2025-8058",
        "level": "warning",
        "message": { "text": "The regcomp function in the GNU C library version from 2.4 to 2.41 is subject to a double free if some previous allocation fails. …" },
        "locations": [{
          "logicalLocations": [{ "kind": "module", "name": "glibc 2.3.4" }],
          "physicalLocation": { "artifactLocation": { "uri": "002556361f8e06ec…" } }
        }],
        "properties": {
          "match_confidence": "floor_only", "kev": false,
          "cvss": { "version": "4.0", "base_score": 5.900000095367432,
                    "vector": "CVSS:4.0/AV:L/AC:H/AT:P/PR:L/UI:P/VC:L/VI:L/VA:H/SC:L/SI:L/SA:H" }
        }
      }
    ],
    "properties": { "tool_version": "0.11.0", "schema": "2.1.0", "arch": "x86" }
  }]
}

absoluteAddress is 1232 — 0x4d0 — while fullyQualifiedName is sub_540. They are unrelated addresses: 0x4d0 sits below .text, the PLT stub for execvp and the call target this detector family records, while sub_540 is the function that made the call, rendered sub_<hex> because it carries no symbol. A consumer that reads the name as a label for the address will mis-anchor, and what the address field means differs per family. glibc 2.3.4 is not the glibc this binary ran against either; it is the symbol-version floor recovered from the ELF's version requirements, and every CVE hanging off it is named-as-affected, not confirmed-as-vulnerable.

Every output is a projection of the stored analysis through one of three surfaces: a REST API, 48 MCP tools, and a SARIF 2.1.0 log. That analysis is not one row: the binary record, the CWE-findings slot, the threat assessment, the strings sidecar, and the functions and call-graph blobs are separate per-sha stores, fused at read time by whichever surface is asking.

SectionAnswers
The SARIF documentwhat a log contains, and which finding families map to which severity levels
Result locationshow a virtual address becomes a uri a code scanner will accept
Limits and truncationwhat is dropped past 25,000 results, and how the drop is recorded
Result confidencehow sure a CVE match, a reachability flag, or a threat row actually is
Output surfaceswhich of REST, MCP, and SARIF carries what, and how each is gated
The query DSLwhich fields are queryable, with which operators
Per-binary outputsthe field inventory for one analysed binary, marked by surface
Per-container outputswhat a firmware image, package, or archive yields instead
Corpus-wide outputsthe seven outputs spanning the whole corpus or a fleet

The SARIF document

Every export is a single run with a single tool.driver named openbinary, whose version and semanticVersion are the exporter's own build — 0.11.0 above, the same string that stamps run.properties.tool_version, not the version of the engine that produced the analysis. The engine version sits on the stored record and is emitted nowhere in the log, so a binary analysed two engine releases ago still exports 0.11.0. SARIF 2.1.0 is what GitHub code scanning and DefectDojo already ingest, so an export lands in an existing queue rather than a new dashboard.

The analysed binary is a run.artifacts entry, never a result. The driver.rules catalog is derived from the results that survived, not from the rule set that could have fired, so every ruleId in the document resolves to a rule and no orphan rule is shipped.

Finding families and anchors

Five finding families project into that one run, each anchoring to a different kind of location:

FamilyruleIdLocation it anchors toresult.taxa
CWE findings, binary and sourcethe detector rule id (command-exec.execvp)an address, or a path:line:col regionnever — projected with an empty technique list
Embedded secretsthe secret rule idthe byte offset the scanner matched atthe technique ids the rule carries
CVE / SBOM matchesthe CVE idone logicalLocation per affected componentnever
Behavior capabilitiesthe capability rule idthe attributed function, when one resolvedthe technique ids the rule carries
Threat-ledger indicatorsthreat/ + the indicator rule idthe row's first evidence anchor carrying a VAthe technique ids the rule carries

Rule id collisions

Rules dedup on the pair (family, rule id), not on the id alone. A CWE rule literally named threat/something therefore does not silently merge into the threat namespace: whichever of the two colliding keys is emitted second takes a suffix naming its own family — #cwe here — and every result referencing it is rewritten to match. Inputs with no collision emit no suffix at all.

Severity levels

Each family maps onto SARIF's four levels — none, note, warning, error — differently:

Inputerrorwarningnote
CWE / CVE severitycritical, highmediumlow, info, none, unknown
Secret kindprivate-key and symmetric-key material — PEM and DER private keys, PKCS#12, OpenPGP session keys, AES and SM4 key schedules, leaked firmware keysevery other kind: tokens, JWTs, certificates, password hashes
Threat-indicator evidence strengthDefinitive, ProvenSuggestivePresence, and any unrecognised band
Capabilitiesall of them

Capabilities take note unconditionally: they record what the code can do, and grading them by severity would launder a capability into a verdict.

ATT&CK taxonomy

MITRE ATT&CK rides as a single run.taxonomies component, built from the union of techniques the surviving results referenced, so every result.taxa reference resolves. When nothing referenced a technique the component is omitted rather than emitted empty — the state of every log whose findings are all CWE and CVE, since neither family emits result.taxa even where the CWE registry entry has an ATT&CK mapping.

Result locations

Every result carries an artifactLocation.uri, because GitHub code scanning drops any result without one and a virtual address is not a path.

Synthetic uris for binary results

Every binary-anchored result on the per-binary route carries the sha256 as its uri, for every format. The builder prefers the basename — stripped of any / or \ prefix and percent-encoded down to a single RFC 3986 path segment, because a control byte or a CJK character in a display name fails the schema's uri-reference check and gets the whole log rejected — then falls back to the sha256, then to the literal binary. The name seed never resolves here: the record the exporter reads carries no top-level name, size, or format, all three nested under the fingerprint.

That same absence is why the log above has such a thin artifacts entry and run.properties:

FieldWhat it would carryOn the binary route
artifacts[0].location.urithe basenamealways the sha256
artifacts[0].lengththe file size in bytesomitted
artifacts[0].properties.formatELF / PE / Mach-Oomitted
run.properties.format, run.properties.display_namethe same two, run-levelomitted
run.properties.archx86present — arch is a top-level record field

The basename-and-percent-encode path does run on the two surfaces whose uris are real paths: source findings and package member paths.

What the address field means

absoluteAddress carries whatever value the producing detector recorded, and that is not one kind of thing:

ResultabsoluteAddressfullyQualifiedName
CWE finding, address-bearingthe VA the detector recorded — the call target for the command-exec family, the call site for most others, the enclosing function's entry for whole-function detectors like excessive-alloc.stackthe calling function's name; falls back to location.symbol when the caller has no name
CWE finding with no VAthe caller's VA, when one was recordedas above
Embedded secreta file byte offset, not a virtual addressthe secret's kind (rsa_private_key_der, gcp_service_account, leaked_firmware_key, …)
Capabilitythe attributed function's VAthat function's name
Threat-ledger rowthe row's first evidence anchor carrying a VAthe resolved symbol, when one exists

A tool that maps absoluteAddress through a section table mis-places every secret result, because a byte offset and a VA differ by the section's load bias; the only in-band signal is that the secret family omits kind: "function" on the address object. On a stripped binary with no recovered call graph, a CWE result's fullyQualifiedName falls through to the callee primitive — the name reads strcpy or system, neither the enclosing function nor a function defined in this binary.

Source file paths

Source findings carry the real relative path plus a region, treated as strictly repo-relative because that path arrives from a symbol table or an archive entry name, both attacker-controlled. Every .., ., and empty segment is dropped and each survivor percent-encoded.

Input pathWhat the uri becomes
../../etc/passwdcannot escape — the .. segments are dropped
/etc/shadowcannot escape — the empty segment is dropped
café/app.ccaf%C3%A9/app.c — a two-segment path with the non-ASCII bytes percent-encoded
nothing safe remainsthe binary's synthetic artifact location, rather than a hostile uri

Taint witnesses

A finding carrying a taint witness also emits codeFlows — one threadFlow whose locations are the proven Source → Propagate → Sink steps in order, each an address with the step's role and symbol in its message. The primary location stays the sink. That is the same shape CodeQL and Semgrep ship, so a compliance buyer can diff them.

The witness is not SARIF-only: the same ordered address / role / symbol chain rides the finding on GET /binary/{sha} and the findings tool, so a consumer that never exports SARIF still gets the proof. Only taint detectors that retain a source anchor populate it — interprocedural summary detectors prove parameter-index reachability without recording a per-operation witness, and static-rule findings carry none at all.

Threat-ledger evidence

A threat-ledger row's detail text and matched-string evidence ride the free-text message and properties fields only — never a uri or helpUri — because they are baked from bytes the adversary chose. From such a row only the numeric virtual address, and a symbol name if one resolved, is lifted into a location.

Limits and truncation

Six limits bound an export, and each records separately what it dropped:

LimitValueWhat happens past it
Results per run25,000Lowest-ranked results evicted; run.properties.truncated and omitted_results record it
Rules per run25,000Catalog truncated after sort by emitted id
Locations per result1,000Caps the CVE multi-component fan-out
Members per package1,024Excess members are not projected; truncated_members and members_omitted record it
Surface bytes per member32 MiBMember skipped, counted as members_oversized. Bounds projection CPU, not memory: one corrupt findings array cannot monopolise a request every other member shares
Concurrent package exports3, process-wide429. Not a rate limit: each in-flight export holds a blocking thread plus one member's surfaces and a bounded result set

GitHub's twenty-runs-per-file limit is satisfied by construction — every export is exactly one run. The result cap is GitHub's too, and it is enforced continuously rather than at the end: the accumulator is a bounded keep-top-N heap holding at most 25,000 results at any moment, evicting the current worst on every push past the cap. Peak memory is a function of the cap, not of how many findings the binary produced. The eviction order is total and therefore reproducible — level descending, then rule id ascending, then insertion sequence — so two exports of the same analysis truncate to byte-identical documents.

A firmware image exports as one merged run with one artifacts entry per member and a global keep-top-N rather than a per-member share, so results compete on severity across the whole image instead of being rationed. Member results carry artifactLocation.index, the SARIF-standard disambiguator, so two members sharing an in-image path stay attributable; the single-binary path never sets it, which keeps its output byte-identical.

Selection into the 1,024 cap is a weaker guarantee than the eviction that follows it. Members are ranked on cheap signals only — the stored verdict label and the CVE rollup, no findings read — because reading every member's findings to decide which members to read is the cost the cap exists to avoid. A member with a quiet verdict and no CVEs but a large findings array is cut before its findings are ever looked at.

A package log's run.properties names both axes: package (sha256, name, kind), members_total, members_analyzed, members_projected, members_unanalyzed, members_omitted, members_failed, members_oversized, truncated_members. Members omitted by the 1,024 cap never fold into omitted_results, which counts evicted results only; truncated and omitted_results appear only when truncation actually happened.

Result confidence

Every CVE result carries its match_confidence, and the five tiers are ranked:

TierMeans
range_matchedThe advisory's affected range explicitly contains the resolved component version
exactThe version equals an enumerated affected version from OSV
range_unparseableA range was present but did not parse as semver, CPE, or calver — an operator audit item
floor_onlyOnly a lower bound is known — from an ELF symbol-version requirement, a .note.ABI-tag minimum, or a signature-mined build. The advisory names the component; the range cannot be confirmed
name_onlyNo version at all; the advisory matched on component name

floor_only is not a defect being hidden — it is the alternative to fabricating a range_matched from a minimum. It is also the majority case for a distro ELF: 23 of fstab-decode's 26 results are floor_only, all inherited from a glibc 2.3.4 floor that the real deployed glibc almost certainly exceeds.

Reachability flags, capabilities, and threat rows each carry their own convention for what a missing or ungraded value means:

SignalPropertyEmitted whenWhat absence or fallback means
Reachability from entryreachable_from_mainthe analysis recorded a definite true or falseabsent means unknown, never flattened to false
Pre-auth reachabilityreachable_before_auththe same ruleabsent when no network-listener roots resolved at all, the normal state for a command-line tool
Capability classifierconfidence — sound or heuristic — plus superset, superset_kind, low_confidence, category and the evidence, all verbatim in result.propertiesevery capabilityThe classifier's third tier, superset, has no confidence value of its own: it serializes as sound with superset: true and a superset_kind naming the leaf (taint-flow, reachability, resolved-argument, dynamic-resolution, XPC). scoring_eligible: false marks a real capability that deliberately carries no verdict weight
Threat-row evidence bandthe SARIF levelevery threat-ledger rowa missing, mistyped, or unrecognised band maps to note, not warning

Threat-ledger rows fail low, not high: defaulting an ungraded row upward would rank unproven evidence above a recognised-but-weak band.

Output surfaces

The same analysis leaves through three surfaces, and every named output is a projection of the stored analysis record through one of them, not a route of its own:

SurfaceShapeCarries
REST31 artifact-scoped routes under /api/v1/binary/{sha256}, 7 under /api/v1/package/{sha256}, 2 under /api/v1/source/{sha256}the full field inventory below
MCP48 toolsthe same stored record, addressed by tool call
SARIFone 2.1.0 log per binary, per source file, and per packagethe five finding families

The SARIF projector runs no analysis, opens no binary, and computes nothing new. It reads already-resolved, already-gated JSON.

Access control

The projector performs zero access control of its own; gating is inherited by composing the same read facades every other surface uses. Each route denies differently:

RouteDenialWhat the caller gets
Binary SARIFno static-audit granta valid log with the CWE and secret families absent — not an error, not a partial document, not a 403
Binary SARIFbinary not visiblethe same not-found every other read returns
Package SARIFcaller is not Pro403 for the whole document. The gate runs after the visibility check, so an unseen package still 404s and the 403 never leaks existence
/api/v1/source/{sha256}/sarifany denial, a missing static-audit grant included404

Static audit is grant-only: no plan tier clears it, Pro included. It sits with raw binary download, whole-binary reconstruction, corpus-wide statistics, and curator annotation in the set reachable only through a per-user grant an operator issues by hand. Two of the five SARIF families — CWE findings and secrets — are therefore absent from a paying Pro customer's log by default, and the CWE result opening this brief is reachable only by a grant-holding caller. One carve-out: on a deployment with no auth provider configured, the operator running the binary is the data owner, so every grant-only feature is on.

Projector dependencies

The projector depends on serde, serde_json, and thiserror — no analysis code, no storage, no typed finding model — and that last omission is load-bearing. The identifying fields of every finding family, rule ids and summaries and ATT&CK id lists, are interned strings that serialize out but round-trip back to empty through the analysis types. Re-reading the JSON through those types would silently blank every rule id in the export. Having no access to them makes that mistake unavailable.

The source SARIF route

/api/v1/source/{sha256}/sarif collapses every denial into one 404, a missing static-audit grant included, because on that route the gate result is itself the existence signal. Since shas are content-addressable, an attacker computes them from files they already hold; a 200-with-empty-log would answer "was this exact file uploaded and scanned by someone" at one request per candidate — a corpus-wide file-membership oracle. The uniform 404 closes it.

The query DSL

The corpus answers a compositional DSL whose identifiers are a hand-maintained subset of the indexed fields, not the display fields and not the index itself.

Field kindIdentifiers
Tokenized textframeworks, framework_paths, entitlements, imported_symbols, endpoints, apis_called, static_libs, bsd_syscalls, mach_traps, dlsym_targets, xpc_services, indicator_rule_names, mitre_technique_ids, name
Numericincluding file_size, function_count, known_vuln_count, max_section_entropy, text_entropy
Facetsplatform, arch, binary_type, mach_o_type, signing_status, package (curated provenance, independent of the byte-derived platform), component, indicator_categories, indicator_rules, attack_techniques, consistency_kinds, vuln_severity, has_kev, hardening_feature, hardening_severity, is_apple_signed, and the eight action_* booleans
Indexed, but absent from the DSLverdict, capabilities, analyze_status, linkage, named_coverage, named_bp, cwe, cwe_rule, finding_severity

Those last nine are real indexed fields — most counted by the corpus-statistics endpoint, named_bp a sortable numeric, verdict additionally filterable through the search endpoint's own verdict parameter. They are absent because the DSL's field table is a separate hand-maintained list, not a view of the schema.

The queryable field set is versioned — schema 12 today — and the version is a wipe boundary, not a migration: adding a field bumps it and every existing index must be rebuilt before the new identifier answers anything.

Each field kind fixes its legal operators:

Field kindOperatorsCannot express
Flat facets and hashes==, !=
Multi-value facets==, !=, ANY, ALL, CONTAINS
Numericthe comparisons
Tokenized text==, ANY, CONTAINS — all three the same term match at token granularity!= is rejected outright, so there is no way to ask which binaries lack a syscall
file_size > 100000 and platform == "FreeBSD"          → 67 binaries

The same expression rides the search endpoint's filter= parameter.

Per-binary outputs

One analysed binary yields the fields below. api marks a REST endpoint, mcp an MCP tool; an entry carrying neither is computed and consumed internally.

Identity and status

OutputWhat it carriesSurfaces
Namebest sighting filename, else the embedded namemcp
Visual fingerprintbyte-map and bigram renderings of the raw bytes, for visual triage and look-alike searchapi
Perceptual hasha 64-bit dHash of the bigram image, ranked by Hamming distance. The documented bands — 5 for two recompiles of the same source, 15 for the same family, past 25 for unrelated — are an assertion, not a measurement. What is measured, on synthetic inputs, is the separation: a 16-byte perturbation moves at most 8 of the 64 bits, two structurally unrelated inputs at least 10api
Analysis statusengine version, analysis timestamp, live reanalysis stage, queue position, terminal statusmcp api

Description and provenance

OutputWhat it carriesSurfaces
Generated descriptiona one-line title and prose summary of what the binary ismcp api
Fingerprint identityplatform, architecture (all slices for fat binaries), binary type and product-role label (daemon / kext / cli-tool / …), signing verdict, min OS, ABI, SDK, source version, file / image / header sizes, symbol-table state, signing authority, Team ID, bundle id, UUID or build id, interpreter, source path, designated requirementmcp api
Build provenanceinferred compiler, optimization level, and toolchain. On the pairwise-compare route and the command-line report, not the binary route; its statically-linked library list also falls back into the DNA fingerprint and the static_libs search field when no library profile resolvedapi
History and sightingsfirst seen, last seen, total sighting count, every filename it has been observed undermcp api
Membershipwhich curated packages and firmware images contain this binary, and at what pathapi
App Store enrichmentlive store listing for the bundle id: display name, publisher, version, category, rating, price, release dates, size, languages, what's-new, description, screenshotsapi

Structure

OutputWhat it carriesSurfaces
Program headersentry point, the segment and program-header table, the section-containment tree, load-command countmcp api
Sectionsper-section name, kind, flags, address, offset, size, entropy, content hash, embedded-format countmcp api
Build hardeningeach compile-time mitigation as on / off / not-applicable: PIE, stack canaries, ARC, hardened runtime, CFI, PAC, RELRO, NX, ASLR, DEP, CFG, CET, BTI, library validationmcp api
Objective-C summaryclass, category, and protocol name lists with countsmcp api
Fat slicesper-slice arch, encryption, signing status, Team ID, entitlement count, cdhash, identity-mismatch flagmcp api
Load commandsheader flags, dyld environment, install name, dynamic linker, linker options, sub-clients, debug object filesmcp api
ELF dynamic sectioninterpreter, SONAME, needed libraries, RPATH and RUNPATH, bind-now versus lazy, PIE, flagsmcp api
PE image headersubsystem, image base, entry, alignments, sizes, stack and heap reserves, link and compile timestamps, data directoriesmcp api
PE version infocompany, product, and version strings plus the resource summary. On a stripped PE with no readable strings, this is the field that names the toolmcp api
PE debug infoembedded PDB path, build GUID and age, symbol-server idmcp api
CLR/.NET metadataruntime, flags, assembly identity (name, version, culture, public-key token), MVID, referenced assemblies, and how many CIL method bodies were recovered into control-flow graphsmcp api
Imports by libraryimported-symbol counts grouped by librarymcp api

System access

OutputWhat it carriesSurfaces
Entitlementsdeclared entitlement claims, key and valuemcp api
Capabilitiesthe ATT&CK-mapped behavior inventory: per-capability summary, confidence, technique links, per-function attribution. See Capabilitiesmcp api
Behavioral aspectsan aspect-taxonomy summary of what the binary doesmcp api
Action profileeight booleans: opens files, opens network, spawns processes, loads code dynamically, sends Mach messages, direct syscalls, computed syscalls, likely packed. Each is also a query facetmcp api
System surface and call signaturesresolved syscalls and library calls with their resolved arguments: domain, name, per-call count, argument valuesmcp api
XPC servicesper-service mach name, role, kind, call sites, sends, auth statemcp api
Bundle identitybundle id, name, executable, version, min system version, privileged helpers, authorized clients, URL schemesmcp api
Consistencydeclared-versus-actual divergences (unused or undeclared entitlements, private-entitlement abuse, bundle-id impersonation) with affected keys and ATT&CK links. Part of the static-audit surface, so grant-only — the key is omitted, never nulled, for callers without itapi

Network and libraries

OutputWhat it carriesSurfaces
Network surfacenetworking frameworks, static endpoint literals, resolved outbound targets (host, port, protocol, caller), DNS lookups, inbound listeners, raw-socket countmcp api
Libraries and SBOMdetected libraries with name, version, supplier, function count, and evidence; the statically-linked rollup; CycloneDX 1.6 and SPDX 3.0 exportmcp api

Functions

OutputWhat it carriesSurfaces
Function listevery recovered function with name, address, origin (user / library / runtime / glue), library attribution, rarity markermcp api
Imports and exportsimported and exported symbols with address, and library for importsmcp api
Function originsuser, runtime, library, glue, and total counts plus top librariesapi
Function-starts countentries recovered from LC_FUNCTION_STARTSapi
Decompiled codeper-function output in any of six stages: raw disassembly, lifted IL, control-flow-graph edge list, SSA-form IL with phi nodes, structured pseudocode, typed C — with pipeline confidencemcp api
Per-function contextrecovered locals and arguments, one-hop callers and callees, referenced stringsapi
Annotationshuman and auto-filled names, comments, prototypes, and data names overlaid per addressmcp api
Annotation autofillsuggested names and comments for one function or the whole binarymcp api
Rust reconstructionthe whole binary emitted as a Rust crate tarball. Whether it compiles is a measured property, reported alongside class coverage, method coverage, lift ratio, and a count of // UNKNOWN markers — not a guarantee. Gated, job-basedapi

Strings

OutputWhat it carriesSurfaces
Interesting stringsgrouped by category: identifiers, file and config paths, URLs and endpoints, IOKit constants, telemetry, format templatesmcp api
Full strings tableevery recovered string with file offset, virtual address, encoding, and the functions referencing it; filterable, paginated, exportable. Promcp api

Threats

OutputWhat it carriesSurfaces
Verdictbenign / suspicious / likely-malicious / malicious, with a plain-English rationale and the rule-set versionmcp api
Family attributionattributed malware family names with nearest-neighbour confidencemcp api
Threat ledgertotal score and, per scored signal, the indicator label, category, ATT&CK links, match count, points, and evidence anchorsmcp api
Heuristic indicatorsrule matches over strings, imports, and sections, with address, rule, and techniquemcp api
Threat reportsknown IOC writeups this binary appears in, with cross-check linksapi

Vulnerabilities

OutputWhat it carriesSurfaces
Known CVEsmatched CVEs with severity, CVSS, KEV, EPSS, match confidence, affected components, and CWE. See CVEsmcp api
CWE code findingsstatic-audit findings with CWE id, severity, occurrence count, and per-site caller with inline decompile; plus reachability triage (reachable-from-entry, reachable-before-auth), the entry surfaces an attacker reaches through, a privilege-ceiling estimate, and the taint witness where one was proven. Grant-only. See Findingsmcp api
Secretsdetected credential and key material by kind: PEM and DER private keys, OpenSSH and PuTTY keys, PKCS#8, PKCS#12, PKCS#7 signed data, X.509 certificates, OpenPGP private and session keys, JWTs, AWS / GitHub / Slack tokens, GCP service accounts, crypt(3) and LDAP password hashes, AES and SM4 key schedules recovered from their key-expansion structure, and known-leaked firmware signing keys. Each carries a two-tier confidence — magic-only versus header-valid — location, ATT&CK links, and a redacted snippet. Grant-only, alongside the code findingsmcp api
Source findingsCWE findings for an extracted source file. Grant-onlyapi
SARIF exportthe SARIF 2.1.0 log, per binary (mcp api), per source file, and per package (api only, Pro)mcp api

Lineage

OutputWhat it carriesSurfaces
HashesSHA-256, SHA-1, MD5, UUID, cdhash, ssdeep, plus structural hashes over code, imports, frameworks, classes, entitlements, symbols, C++ classes, and hardeningmcp api
DNA fingerprintthe capability vector, structural hashes, and binary kind used for similaritymcp api
Similar binariesnearest-neighbour matches scored by Jaccard and cosinemcp api
Variant clustera neighbourhood graph, each node carrying verdict, type, status, and similaritymcp api
Visual variantsperceptual look-alikes ranked by dHash distanceapi
Combined verdictthe malware tier fused with the similarity-neighbourhood label, with rationaleapi
Unusual functionsfunctions rare relative to the reference corpusmcp api
Fleet hostsper-host inventory of where a binary is observed, with first and last seen. Fleet-gatedmcp api

Operations and lookups

OutputWhat it carriesSurfaces
Resolve name to shathe first visible binary matching a namemcp api
Pairwise comparea full diff of two binaries: shared and differing hashes, symbols, strings, endpoints, similarity scoresmcp api
Raw downloadthe original uploaded bytes by sha. Grant-onlymcp
On-demand re-analysisre-run the current engine over a binary you can already see, reusing the stored bytes. Proapi
Call-graph navigationgod nodes (top hubs), graph summary, node search, local subgraph, path existence, reachability with a witness path, attack-surface ranking. One bounded call answers "what calls this" or "does A reach B" instead of hand-walking edges; the local subgraph around one address is also a REST routemcp api
Batch host verifyup to 1,000 sha-256 hashes classified in one request into eight statuses: apple_baseline, apple_other_build, known_good, known, suspicious, known_bad, unknown, invalid. Each row carries the evidence behind it — verdict label, title, team id, sources, and the OS builds whose baseline packages contain the hash — so the client is not trusting an opaque answer. Anonymous callers classify against the public corpus; a token widens the visible set. A larger batch is a 413 naming the cap and the count received; the 8 MB body ceiling sits high enough that the entry count is always what rejects a batchmcp api
Triage playbookthe bundled tool catalog and query-DSL patterns, served as an MCP resourcemcp
Type prediction and anomaly scorea learned product-role prediction (label, confidence, top-k) and a per-type anomaly score (percentile, flagged), reachable through search facets and the anomalies feedapi

Fields computed but never serialized

These products are computed during analysis and reach no surface:

Computed productWhere it goes instead
The IL abstract domains — value ranges, points-to sets, guard and dispatch reasoningconsumed by analysis passes and discarded
Full Objective-C, Swift, C++, Go, DWARF, and PDB metadataonly the names-only summaries and CLR identity surface; the type and structure metadata stays internal
Per-function machine-learning feature vectorsonly the derived rarity output surfaces
The raw syscall, dynamic-load, and aspect surfacesthey feed the summaries above
IOKit surface, carved Mach traps, fileset entries, and data-in-code ranges
The completeness report card — analysis status, linkage, function-naming coverage in basis points with a by-source breakdown, and edge-resolution coverage (total call-graph edges versus those whose target is indirect or computed)no per-binary surface; two internal consumers. The search index turns status, linkage, and naming coverage into the analyze_status and linkage facets and a five-bucket coverage histogram in corpus statistics. The pipeline reads it to declare an analysis insufficient — status empty becomes "no functions discovered", a below-floor function count with almost nothing nameable becomes "stripped/opaque". Its decode-coverage, lift-ratio, and undecoded-opcode fields are always empty: nothing measures them yet
The per-pass error report naming which analysis passes failed on this binarylogged only

Per-container outputs

A firmware image, package, or archive is a distinct record family: it is never one binary, and its outputs describe a tree.

Package detail

OutputWhat it carriesSurfaces
Identitysha, filename, kind (firmware / app / dmg / zip / pkg / deb), size, upload time, statusmcp api
Observed-as identitiesevery distinct upload of this package: uploader, name, source, visibility, timeapi
Unpack statuslive stage, progress, queue positionapi
Membersthe extracted binaries with path, format, size, kind, language, format chain, analysis statusmcp api
Member progresstotal, analyzed, pending, failed, not-analyzedmcp api
Countsbinaries extracted, files extracted, total CVEsapi
Malicious rollupworst-case verdict across members with readable findingsmcp api
CVE bucketscounts by severity plus the top CVEs (id, severity, EPSS, component, binaries affected)mcp api
Composition and contentsartifact-kind breakdown and the per-file inventory: path, kind, size, sha, format chainmcp api
Container secretssecrets found anywhere in the container, by kind and severity, with where each was seenapi
SBOMcomponents with name, version, category, supplier, evidence, affected binaries, and CVEs; firmware CVEs; stats. CycloneDX 1.6 and SPDX 3.0mcp api

Firmware readout

One readout is computed over the unpack result and carried whole by the package-description tool. See Unpacking.

OutputWhat it carriesSurfaces
Extraction countswritten, skipped, identified-only, warningsapi
Container-version CVEsCVEs implied by the firmware version bannerapi
Format breakdownthe leaf carrier formats presentapi
Format chainsthe outer-to-inner nesting pathsapi
Largest payloadsthe biggest extracted filesapi
Arch distributionthe CPU architectures presentapi
Interesting findingsnotable file classes: CGI, remote-access daemons, HTTP servers, shadow files, IPsec, init scripts, keys and certificatesapi
CVE path heuristicsCVEs inferred from file-path patternsapi
Skipped breakdownwhy entries were not extracted: symlink, traversal, encrypted, and the restapi
Identified-only breakdownformats found but not extracted, split by reason: no extractor, low confidence, depth or budget exhaustedapi
Embedded URLsphone-home, update, and NTP endpoints found in scripts and configsapi
Warnings breakdownnon-fatal integrity anomalies by kindapi
Vendor carrierswhich vendor a carrier format impliesapi
Embedded filesystemsthe mounted filesystems present and their byte totalsapi
Kernel envelopeLinux kernel presence, location, versionapi
Byte coveragehow much of the raw image was identified, versus padding, versus unknownapi
Region mapthe located byte regions of the raw imageapi
Carved file typeswhat the leaf payloads are, by magicapi

Extraction ledgers

Every extraction decision is recorded, including the negative ones.

OutputWhat it carriesSurfaces
Written fileseach extracted file's path, original path, size, format chain, source offsetapi
Skip ledgereach rejected entry and whyapi
Identified-only ledgereach detected-but-not-extracted format with offset, depth, and reasonapi
Warnings ledgereach integrity anomaly and its detailapi
Unpack statstotal files, total bytes, max nesting depth, identified-only countapi
Progress streamlive extraction events: firmware version, CVEs, components, summary, completion, per-file progressapi

The per-entry confidence scores and probe internals behind the identified-only ledger are collapsed into reason labels, and the full per-file extraction trace beyond the written and skip ledgers stays inside the unpack pipeline.

Curated packages and comparison

OutputWhat it carriesSurfaces
Package rowid, kind (linux-distro / bsd / macos / windows / ipsw / docker / vendor), name, version, vendor, release date, source, arch, member count, baseline-versus-additiveapi
Members previeweach member with sha, name, version, path, status, size, format, verdictapi
Processing rollupdone, running, queued, failed, not-analyzed, queue positionapi
Curated SBOM rollupcomponents aggregated across membersapi
Curated malicious and CVE rollupworst-case verdict and CVE buckets across membersapi
Reverse rollupwhich packages contain a given binaryapi
Similar packagesrelated packages by shared components, CVEs, format chains, findings, and dominant arch, with a scoreapi
Package diffadded, removed, and changed files between two packages, with optional per-path verdict, CVE, and component enrichment, plus countsapi
Operationsre-run the full unpack, analyze a single extracted child, detect Docker/OCI image and image archapi

Corpus-wide outputs

Seven outputs operate over the whole corpus or a fleet rather than one artifact.

OutputWhat it carriesSurfaces
Searchfull-text and faceted search, scoped to the caller's visibilitymcp api
Querythe DSL above, also available as the search endpoint's filter= parametermcp api
Corpus statisticsfacet distributions, arch-by-platform and package-by-CWE matrices, coverage, and signature-database supply versus demand — scoped to the caller's visibility, with the three CWE facets (cwe, cwe_rule, finding_severity) stripped from callers without the static-audit grantmcp api
Whole-corpus statisticsthe same aggregates computed across the entire corpus rather than the caller's visible slice. Grant-only, and it 404s rather than 403s so the route's existence never leaksmcp api
Discovery and anomaliesa curated feed of recent uploads and the anomaly-flagged listingapi
Corpus renamerename a function across the entire public corpus. Curator-onlymcp
Fleet CVE and host rollupcross-binary CVE rollup and per-host inventory over the visible corpusapi

Reference