Skip to content

Security: hellstation/Tracework

Security

SECURITY.md

Security

MailTrace is a local triage tool for untrusted email. The controls below are what the program does. They were checked with the offline test suite in this repository. This document is not a third-party audit, and a clean report is not a finding that a message is safe.

Default behavior

analyze and ioc do not open a network connection. They do not fetch extracted URLs, talk to threat-intel services, or submit the message anywhere.

Web UI (Tracework)

mailtrace serve starts Tracework: a hub plus MailTrace (/email/) and InfraChronicle (/infra/). It listens on the bind address you choose (default 127.0.0.1:8000).

MailTrace uploads are analyzed like analyze: no URL fetching, no DNS, no attachment execution. Responses set a strict Content-Security-Policy on /email, do not turn extracted URLs into links, and escape message text in HTML.

InfraChronicle performs allowlisted outbound HTTP/DNS to passive OSINT sources when you run an investigation or search. SSRF guards and response size limits apply; see infrachronicle provider and validation code. Optional API keys in .env enable extra providers.

The UI is intended for localhost or a trusted lab network, not the public Internet without TLS, authentication, and network controls.

Authentication headers are copied and labeled as recorded results. MailTrace does not recompute SPF, DKIM, or DMARC, and the report models reject an independently_verified flag.

Optional DNS

mailtrace dns-policy queries TXT records only after --confirm-network. It looks up sender-authentication names: the From, Return-Path, and Sender domains, _dmarc.<domain>, and {selector}._domainkey.<domain> when a DKIM-Signature header supplies them. It does not query hosts taken from URLs, and it does not decide pass or fail. The names you query are sent to the configured resolver. Names that are not valid DNS names are not queried. The query count is capped.

A TOML config file cannot turn networking on. Config rejects unknown keys.

Attachments and HTML

Attachment bytes are hashed in memory. They are written only when --extract-attachments names a directory. The tool refuses a symlinked output directory, skips an existing symlink in that directory, and creates files with O_EXCL and O_NOFOLLOW where the platform provides it. Saved names are basenames restricted to letters, digits, dot, underscore, and hyphen, with a hash prefix. Archives are not unpacked. Files are not executed and are not opened with an external program.

HTML is parsed with the standard-library parser to collect links and a few structural signals. It is not rendered in a browser. Script bodies, event-handler values, and CSS-hidden text are not copied into reports. HTML reports escape text, set Content-Security-Policy: default-src 'none', and do not emit links for extracted URLs.

Limits and errors

Parsing stops at configurable ceilings for message size, MIME part count, part depth, nested-message depth, attachment size, header count, and URL count. Hard upper bounds on those settings are enforced by the config model. Over-size input is rejected before a full parse when the file size is already known.

The CLI disables Typer's pretty exceptions so a traceback does not dump local variables that may hold message bytes. Error text names the problem class or a path the user supplied. It does not include the message body.

Reports include header fields, URL strings, filenames, hashes, and observations. They do not include the message body, archive members, or active-content payloads.

What this does not cover

Observations are heuristics. A missing authentication header, an unusual domain, or a Reply-To mismatch is context for an analyst, not a verdict. Hidden content in images, encrypted parts, and unsupported encodings can be missed. There is no public-suffix list and no brand list behind the host checks.

There aren't any published security advisories