TTP

September 25, 2026 · View on GitHub

Version: 1.0
Last Updated: 2026-06-11
Scope: Transparent Tor Proxy (TTP) v0.4.x
Methodology: STRIDE per component

This document provides a structured threat model and risk assessment for TTP. It is intended for security auditors, contributors evaluating the security posture of the project, and users who want to understand the residual risks before deploying TTP in high-risk scenarios.


Table of Contents

  1. Security Objectives
  2. Trust Boundaries & Assets
  3. Threat Model (STRIDE)
  4. Known Limitations & Residual Risks
  5. Supply Chain Security
  6. Security Controls Summary
  7. Out of Scope

1. Security Objectives

TTP is designed to achieve the following security properties, in order of priority:

#ObjectiveDescription
1Traffic ConfidentialityAll TCP traffic from the host must be routed through Tor. No cleartext traffic must reach the ISP.
2DNS Leak PreventionAll DNS queries must be resolved by Tor's internal resolver. System, application, or browser-level DNS must not bypass the Tor network.
3IPv6 Routing & Leak PreventionNative transparent IPv6 support through Tor when supported; dropped to prevent leaks if IPv6 loopback is unavailable.
4Crash-Safety / Fail-ClosedIf TTP crashes, the network must be restored to a known state. The system must never be left in a half-configured state that leaks traffic.
5Integrity of Session StateThe session lock and runtime configuration must not be tampered with by unprivileged processes.
6Supply Chain IntegrityTTP release artifacts must be signed. Dependencies must be audited for known CVEs.

Critical Disclaimer: TTP is a best-effort privacy tool. It is not a guarantee of anonymity. See Section 4 for explicit residual risks.


2. Trust Boundaries & Assets

2.1 Trust Boundaries

┌─────────────────────────────────────────────────────────┐
│  TRUST BOUNDARY: Root Process (ttp running as root)      │
│                                                           │
│  ┌──────────────┐   ┌────────────┐   ┌───────────────┐  │
│  │  ttp CLI     │──▶│  nftables  │──▶│  Linux Kernel │  │
│  │  (Python)    │   │  (inet ttp)│   │  (netfilter)  │  │
│  └──────────────┘   └────────────┘   └───────────────┘  │
│         │                                                 │
│         │           ┌────────────┐   ┌───────────────┐  │
│         └──────────▶│  systemd   │──▶│  ttp-tor.svc  │  │
│                     └────────────┘   └───────────────┘  │
│         │                                                 │
│         └──────────▶ /run/ttp/ (tmpfs) — volatile lock   │
└─────────────────────────────────────────────────────────┘
         │
         ▼ (all traffic exits via)
┌──────────────────────────────────┐
│  TRUST BOUNDARY: Tor Network      │
│  (Entry Guards → Relays → Exit)  │
└──────────────────────────────────┘
         │
         ▼
┌──────────────────┐
│  PUBLIC INTERNET │
└──────────────────┘

2.2 Protected Assets

AssetClassificationWhere Stored
Session lock file (PID, config)Sensitive (runtime)/run/ttp/ttp.lock (tmpfs, root-only)
Tor control auth cookieSecret/run/tor/ttp/auth_cookie (tmpfs, tor-user-only)
Tor Entry Guard stateSensitive (performance)/var/lib/tor/ttp/ (root-owned)
Generated torrcConfiguration/run/tor/ttp/torrc (tmpfs, root-only)
User's real IP addressHighly sensitiveNever stored by TTP
User's DNS queriesHighly sensitiveRouted through Tor's DNSPort, never logged by TTP

3. Threat Model (STRIDE)

3.1 ttp/firewall/ Package — nftables Rules

ThreatSTRIDE CategoryDescriptionMitigationResidual Risk
Rule injection via concurrent nft commandTamperingAn attacker with root access runs nft to add bypass rules to inet ttp tableAtomic rule load via nft -f ensures consistent state at load time. Watchdog re-applies rules if the table is modified.Low. Requires root compromise; watchdog detects within 15s.
Redirect silently stops matchingInformation DisclosureThe NAT redirect is present in the table but no longer matches the traffic it should — a competing nat chain that DNATs first, a rule reordered by a concurrent write. The ruleset still looks correct, so shape-based checks pass.For plain DNS a competing nat chain can take the connection first: the kernel accepts nat chains down to priority -199, below TTP's -150, and the first one to bind a connection ends NAT evaluation for it. filter_out therefore rejects any query whose original destination port was 53 and which is not headed for loopback, ahead of the LAN bypass that would otherwise accept a rewrite to a LAN resolver (#29; measured in tests/test_nse_rules.py). That reject, like the DoH and DoT rejects, carries a named counter and is unreachable while the redirect works (ADR 0012), so the watchdog treats a rise in any of the three since its previous check as an integrity failure rather than as a user's DNS habit (a first reading is compared against zero). The DNS leak probe reads the redirect counter around its own query instead of inferring from the reply, which cannot distinguish Tor's answer from the resolver's.Low. Detected within one watchdog cycle. A counter that cannot be read is reported absent, so the check degrades to "unknown", never to "clean".
Pre-existing connections survive rule applicationInformation DisclosureTCP connections established before ttp start continue in cleartextNo ct state established accept anywhere, so their packets reach the catch-all, which answers TCP with a reset. filter_out accepts traffic to the host's own addresses so that reset (and the ICMP error for UDP) reaches the local socket: before #36 the catch-all rejected those error replies too on a public address, and the application hung until its own timeout. Measured in tests/test_nse_rules.py for a sending and a receive-only connection, with a LAN connection shown to survive.Low. Nothing escapes either way; a connection is reset at its next packet in either direction. An idle one lives until then, carrying nothing.
LAN bypass creates cleartext side-channelInformation DisclosureLocal LAN traffic (RFC 1918) bypasses Tor, revealing internal network topologyDefault behavior; explicitly documented. Disabled with --no-lan-bypass.Medium. Accepted design tradeoff; user-controlled.
Outbound traffic leak during session teardownInformation DisclosureDuring graceful teardown, closing active Tor circuits could leak in-flight packets in cleartextA temporary teardown lockdown rule drops all non-loopback outbound traffic (excluding Tor UID). conntrack state is also flushed.Low. Outgoing paths are locked before rules are destroyed.
nftables rule persistence after crashElevation of PrivilegeIf TTP crashes, inet ttp rules might remain without DNS overlay, creating inconsistent stateWatchdog detects inconsistency; ttp stop --restore-only performs forced cleanup; ttp start detects orphaned lock and auto-restores.Low. Multiple recovery paths exist.

3.2 dns.py — DNS Overlay

ThreatSTRIDE CategoryDescriptionMitigationResidual Risk
Application-level DNS bypass (DoH, DoH/QUIC)Information DisclosureBrowsers using DNS-over-HTTPS (TCP) or HTTP/3 QUIC (UDP 443) bypass the system resolver entirely3-layer defense: (1) NAT output redirects all TCP/443 to Tor TransPort; (2) torrc maps DoH canary domains to 0.0.0.0; (3) nftables blocks DoT (port 853), well-known DoH IP:port 443 via TCP and UDP (QUIC).Medium. Mitigations are best-effort. Unlisted DoH resolvers are proxied through Tor; QUIC DoH to unlisted resolvers is not blocked. Disable DoH/Secure DNS in browser settings for maximum security.
Stale mount stack from prior crashDenial of ServiceMultiple stale bind-mounts on /etc/resolv.conf block normal operationPre-start cleanup iterates /proc/mounts and removes stale layersLow. Handled at startup.
Symlink attack on /etc/resolv.confTamperingOn systemd systems, /etc/resolv.conf is a symlink; an attacker could redirect itTTP resolves the real path via os.path.realpath() before mountingLow. Mitigated; requires root to modify the symlink target.
DNS query content analysis by exit nodeInformation DisclosureTor exit nodes can observe DNS queries if not using Tor's internal resolverTTP forces all DNS through Tor's DNSPort — queries never leave the Tor circuit as plaintextLow (by design). Tor DNS resolution is used.

3.3 tor_install.py / tor_control.py — Tor Daemon

ThreatSTRIDE CategoryDescriptionMitigationResidual Risk
Malicious Tor package from distributionTamperingA compromised package manager provides a backdoored Tor binaryTTP uses the OS-native package manager (apt, dnf, pacman) which verifies package signaturesLow. Depends on distribution integrity; outside TTP's control.
Forged SELinux policy revision stampTamperingTTP records the policy revision it installed in /var/lib/ttp/selinux-policy-version, because semodule reports presence but not version. A writer of that file could assert a revision that is not loaded, suppressing the reinstall.The file and its directory are root-owned. The stamp can only ever suppress a recompile, and a host left without the current policy is one where Tor cannot bind its DNSPort: start then fails verification and exits 3 with the kill-switch standing, rather than routing anything in cleartext. A missing or unreadable stamp reads as "not current".Low. Requires root; fails closed, and the worst non-root outcome is a redundant recompile.
Tor control socket unauthorized accessElevation of PrivilegeAn unprivileged process connects to /run/tor/ttp/control.sock and sends SHUTDOWNSocket permissions: CookieAuthentication 1 + ControlSocketsGroupWritable 1 with the Tor service groupLow. Cookie auth required; socket group-restricted.
Tor never bootstraps after the rules are appliedInformation Disclosurestart applies the ruleset at step 2 but only observes the bootstrap at step 5. A failure there finds the ruleset, the DNS overlay and the lock already in place.Kill-switch REJECT rule and policy drop block everything that is not explicitly bypassed. The session is left standing rather than torn down, and start exits 3 (not 0) so a caller cannot read the blocked network as a success. A Tor that dies during startup no longer reaches this row: the unit is Type=notify, so systemctl restart fails at step 1 with Tor's own journal lines attached, before any rule is written. What remains here is the narrower case of a daemon that starts correctly and then fails to bootstrap.Low. Fail-closed by design.
Tor service fails to start before the rules are appliedInformation Disclosuresetup_managed_tor exits at step 1, so no rule has been written yet. Under ttp restart the previous session has already been torn down, so the host is left on plain clearnet rather than protected.Teardown restores the network to its known pre-TTP state instead of a half-configured one, prints Traffic in cleartext, and start exits 1.Low, provided the operator reads the exit code. Fail-open by construction: this is requirement 4 (crash-safety), not a silent leak - but a user who assumes restart failed safely would be wrong.
Malicious Tor exit nodeInformation DisclosureTor exit node observes unencrypted cleartext traffic (HTTP, unencrypted protocols)Out of scope for TTP. Users must use TLS at the application layer.High (inherent Tor limitation). Not addressable by TTP.

3.4 state.py — Lock File & Session

ThreatSTRIDE CategoryDescriptionMitigationResidual Risk
Lock file tampering by unprivileged userTamperingAn attacker modifies /run/ttp/ttp.lock to spoof session stateLock file is owned by root (chmod 600); tmpfs path is root-managedLow. Requires root.
TOCTOU race on orphan detectionElevation of PrivilegeBetween orphan detection and cleanup, a new session could be startedAtomic lock write + PID validation; only root can run ttp startLow. Root-only execution.

3.5 watchdog/ — Session Watchdog Package

ThreatSTRIDE CategoryDescriptionMitigationResidual Risk
Watchdog service killed by attackerDenial of ServiceAn attacker with root access kills ttp-watchdog.service to disable monitoringWatchdog is optional; its absence does not degrade the firewall or DNS protectionMedium. Without watchdog, no auto-healing or killswitch. Mitigated by always-on nftables rules.
False-positive killswitch activationDenial of ServiceA transient system event (e.g., systemd reload) triggers the two-strike killswitchTwo-strike policy (first failure triggers healing, second triggers killswitch); 3s stabilization windowLow. Designed to minimize false positives.

3.6 ttp bypass — cgroups v2 Bypass

ThreatSTRIDE CategoryDescriptionMitigationResidual Risk
Slice hijacking by unprivileged userElevation of PrivilegeAn unprivileged process writes its own PID to /sys/fs/cgroup/ttp-bypass.slice/cgroup.procs to escape Tor routingSlice controller cgroup directories are owned by root and writable only by root. systemd-run commands targeting ttp-bypass.slice require sudo/root privileges.Low. Standard user processes cannot migrate themselves to the bypass slice.
Insecure slice file configurationsTamperingAn attacker modifies /run/systemd/system/ttp-bypass.slice to gain persistent bypass or alter slice settingsSlice definition files are created dynamically on-demand, owned by root, and deleted upon ttp stop.Low. Requires root access to edit systemd slice configurations.

3.7 ttp-watchdog — Privilege-Separated Watchdog Daemon

Corrected in 0.4.9. Until 0.4.9 this section overstated the separation in two ways, both found by the September 2026 audit. NoNewPrivileges=yes was described here but never emitted into the generated unit. And ensure_runtime_dir() chowned all of /run/ttp to the ttp-watchdog account, so "no write access to system directories" did not hold: that account could replace root's lock, log, resolv.conf and nftables ruleset with symlinks and redirect a root-privileged write. Both are fixed — the directory stays root-owned and the unit emits the directive — but the residual risk below is stated for the fixed design, not the prior one.

ThreatSTRIDE CategoryDescriptionMitigationResidual Risk
Watchdog process compromiseElevation of PrivilegeAn attacker exploits the watchdog to execute arbitrary code with full root privilegesThe watchdog drops all root privileges, running under the unprivileged user ttp-watchdog with NoNewPrivileges=yes and the minimal set of capabilities (CAP_NET_ADMIN).Low. The watchdog holds CAP_NET_ADMIN, so it can program nftables directly; it has no write access to system directories and cannot run administrative shell commands.
Insecure Polkit rules authorizationTamperingAn attacker bypasses authentication checks to start/stop the watchdog servicePolkit rules explicitly restrict starting/stopping ttp-watchdog.service to root users and the TTP controller.Low. Standard Polkit controls prevent unauthorized service state tampering.

3.8 systemd-resolved — DNS Resolution Edge Cases

ThreatSTRIDE CategoryDescriptionMitigationResidual Risk
DBus API query bypassInformation DisclosureAn application queries resolved via DBus IPC directly, bypassing the /etc/resolv.conf bind-mount overlayOutbound DNS queries originating from the systemd-resolved daemon process are intercepted by the TTP NAT output firewall rules and forced through Tor's DNSPort on loopback.Low. Intercepting outbound port 53 traffic from resolved guarantees DBus bypass queries are still Tor-resolved.
resolved fallback DNS servers leakInformation Disclosureresolved falls back to compiled-in Google/Cloudflare DNS servers, bypassing TorAll outbound cleartext DNS queries (UDP/TCP port 53) are strictly intercepted by nftables. Direct WAN DNS queries are dropped/rejected.Low. Fail-closed firewall ensures no fallback queries escape in cleartext.

systemd-resolved Interaction Matrix

systemd-resolved StateResolv.conf ConfigurationTTP Action & MitigationRisk Level
Active (Stub Mode)Symlink to /run/systemd/resolve/stub-resolv.conf (pointing to 127.0.0.53).TTP applies bind-mount overlay to the target file. systemd-resolved's stub listener queries are hijacked by TTP firewall rules and redirected to Tor DNSPort.Low. DNS queries to 127.0.0.53 are securely forced into Tor.
Active (Static Mode)Symlink to /lib/systemd/resolv.conf or /usr/lib/...TTP resolves realpath and bind-mounts. Outgoing queries to external DNS servers are blocked by nftables filter drop rules.Low. Fail-closed firewall blocks leaks.
InactiveStatic file (managed by NetworkManager/dhclient).TTP bind-mounts directly on /etc/resolv.conf.Low. Overlay mount forces nameserver 127.0.0.1.
Resolved DBus Query BypassDirect DBus IPC from applications (e.g. systemd-resolved API).resolved query is processed by systemd-resolved daemon, which attempts upstream DNS resolution. The upstream query is intercepted by TTP nftables output rules and redirected to Tor DNSPort.Low. NAT redirection catches outbound DNS queries on port 53.

3.9 cli.py — Entry Point & Privilege Escalation

ThreatSTRIDE CategoryDescriptionMitigationResidual Risk
ttp binary replaced with malicious versionTamperingAn attacker replaces the ttp binary installed in /usr/local/bin/Release artifacts are signed via Sigstore; native packages use OS package manager signature verificationLow. Requires root or write access to installation path.
Argument injection via --bypass-userElevation of PrivilegeMalicious input in --bypass-user could be passed to shell commandsUser/group names are resolved via Python's pwd/grp libraries to numeric UIDs/GIDs before use; no shell interpolationLow. Mitigated by library-level resolution.
Python dependency compromiseTamperingA compromised version of typer, stem, or rich is installedDependabot monitors for CVEs; pip-audit --path . is part of the security workflowMedium. Inherent supply-chain risk for any Python application.

4. Known Limitations & Residual Risks

This section documents risks that are by design, inherent to Tor, or out of scope for TTP to mitigate.

Caution

If you are a whistleblower, journalist, or person at high personal risk, do not rely on TTP alone. Use Tails OS or the official Tor Browser instead.

RiskSeverityDescriptionUser Mitigation
Malicious Tor exit nodeHighExit nodes can read unencrypted traffic (HTTP, SMTP, etc.)Always use HTTPS/TLS at the application layer
Browser-level DNS-over-HTTPSMediumNormal browsers may bypass system DNS via DoH (port 443). TTP routes unlisted DoH through Tor, but it compromises anonymity.Disable "Secure DNS" in browser settings for all standard browsers
Double Tor hop (Tor Browser)Low/MediumUsing Tor Browser while TTP is active creates a double-hop that degrades anonymityUse a standard browser (Firefox) while TTP is active
Application-level identifier leaksHighCookies, browser fingerprint, logged-in accounts, and WebRTC can deanonymize you regardless of IP routingUse a fresh browser profile; avoid logging into personal accounts
IPv6 loopback unsupportedLow/MediumIf IPv6 loopback is unsupported by the host OS, IPv6 connectivity is lost since TTP drops all IPv6 to prevent leaksEnsure the host kernel supports IPv6 loopback for full dual-stack routing
Kernel network namespace bypassHighApplications using their own network namespaces (e.g., Docker containers, VMs) bypass nftables entirelyOut of scope; TTP only controls the host network namespace
Timing correlation attacksHighA global passive adversary can correlate entry/exit traffic timing to deanonymize usersInherent Tor limitation; not addressable by TTP
Physical access / kernel-level rootkitCriticalIf the host OS is compromised at the kernel level, no user-space tool can provide security guaranteesUse full disk encryption; operate from a live OS (Tails) for high-risk scenarios

4.1 Toggleable Proxy Model vs. Whonix Gateway/Workstation Compartmentalization

TTP runs as a local transparent proxy on the host, meaning it can be toggled on and off at runtime. This introduces fundamental design differences and increased risks compared to dedicated gateway architectures like Whonix:

  1. Lack of Physical/Virtual Isolation: In Whonix, the workstation VM is completely isolated and has no physical network path to the WAN; its only network interface connects to the gateway VM, which forces all traffic through Tor. Under TTP, everything runs in the same host namespace. If the TTP firewall or service fails, or if a user-space application bypasses the routing rules (e.g. via specific namespaces, custom routing tables, or raw socket creation by privileged processes), cleartext leaks can occur.

  2. Transition and Toggle Leak Risks: Since TTP is toggleable, active connections, sockets, and local caches (such as DNS) exist before ttp start and after ttp stop. Applications may establish cleartext sessions that survive TTP's initialization, or leak packets during startup/shutdown phases before rulesets are atomically committed.

  3. No Defense-in-Depth against Root Compromise: If a host running TTP is compromised, root processes can easily disable nftables, bypass UID/GID exemptions, or read memory directly. In a segmented Gateway/Workstation model, compromising the Workstation VM does not compromise the Gateway's routing integrity.

4.2 Leak Testing Requirements (Zero-Leak Assertions)

TTP's Network Sandbox Engine (NSE) test suite programmatically validates the firewall ruleset against leaks. The testing requirements are modeled after official industry leak-testing protocols:

The NSE environment asserts at the link layer that:

  1. No TCP/UDP packets escape the WAN interface except those generated by the Tor daemon user (UID) or explicit cgroup bypasses.
  2. All DNS traffic is intercepted and redirected to Tor's DNSPort, with zero cleartext DNS queries escaping to standard nameservers.
  3. No IPv6 traffic escapes to the WAN if IPv6 routing is disabled or unsupported.

4.3 Lifecycle Transitions: What Is Measured and What Is Not

Every containment assertion in TTP's suite is about a steady state: a ruleset is loaded into a namespace, a packet is fired, and its absence on the wire is asserted. The leaks that happen to real users are in the transitions — the seconds in which the ruleset, the DNS overlay, the Tor process and the lock file are not all in the same state. This section says which transitions are measured, so that the ones that are not cannot be mistaken for the ones that are.

Measured. The third column matters as much as the second: two of these run on every commit and two do not, and a reader should not have to guess which.

TransitionWhat is assertedWhere it runs
The teardown lockdown windowapply_teardown_lockdown() closes the LAN/bypass traffic that TTP otherwise permits, and still exempts the Tor UID — which do_stop needs, because it applies the lockdown before asking Tor to close its circuits.tests/test_nse_rules.py, on the wire, in CI on every commit
A completed teardowndestroy_rules() leaves no inet ttp table behind and the host reaches the WAN again. A teardown that strands the lockdown rule would remove the user's network with no session left to explain it.Same
ttp start failing mid-sequenceThe four rollback branches in ttp/commands/start.py each unwind a different amount of state.Unit tests, in CI on every commit. Not on the wire
A live session under tamperingtests/chaos_monkey.py sweeps six faults against a running session — Tor stopped, Tor SIGKILLed behind systemd's back, table flushed, table destroyed, resolv.conf unmounted, link flapped — auditing containment after each.make chaos-monkey, manual, not in CI. Needs a runner that can survive losing its own network

Measured in a VM. scripts/vm/lifecycle/run.sh boots a disposable Debian 13 guest under QEMU and records every packet it sends with QEMU's filter-dump, outside the guest and below TTP's own firewall. A probe inside the guest, running as an ordinary non-bypassed user, keeps trying to reach 198.51.100.7 (TEST-NET-2, never a Tor relay) over UDP/53 and TCP/80. A packet to that address in a capture is a leak, and a capture with TTP stopped must contain the probe or the run is void. It runs in .github/workflows/lifecycle.yml when the firewall, lifecycle or DNS code changes, weekly, and on demand.

TransitionWhat is assertedResult
Shutdown with an active sessionNo probe packet from systemctl poweroff until the VM is off.Holds: the network goes down while TTP's rules are still loaded.
Suspend/resume onto a new networkAfter S3 suspend, wake, and a move to a different subnet (new NIC, new lease), no probe packet, and the session is still ACTIVE.Holds: rules, DNS overlay and Tor survive; Tor rebuilds circuits.
Reboot with an active sessionThe host comes back in one defined state, not half a session.The session ends: no table, no overlay, no /run/ttp, ttp status says INACTIVE, and the host is in cleartext from the first minute (DNS and NTP in the capture).

The reboot row is a statement of behaviour, not a pass: a TTP session is volatile by design and nothing restores it at boot. An operator who reboots is unprotected until they run ttp start again. The suite checks that this is what happens, so the day it changes, it changes on purpose.

A mutant that exempts the probe's user from nat output and filter_out fails all three containment checks, so the suite can go red.

Still not measured. The chaos sweep is not yet run inside the VM, so it remains a manual gate. Shutdown and reboot are measured on Debian with systemd-networkd only, not under NetworkManager. Tracked in #30.


5. Supply Chain Security

5.1 Release Artifact Integrity

All TTP release artifacts (.deb, .rpm, .whl, .tar.gz) are signed using Sigstore (keyless signing via GitHub Actions OIDC). Signatures can be verified with:

cosign verify-blob \
  --bundle <artifact>.sigstore.json \
  --certificate-identity "https://github.com/onyks-os/TransparentTorProxy/.github/workflows/release.yml@refs/tags/<tag>" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  <artifact>

The release workflow runs on tag pushes, so the certificate identity is bound to refs/tags/<tag>, never to a branch. See verification.md for the full procedure.

5.2 Dependency Monitoring

Dependency CVE scanning, Dependabot configuration, and the remediation SLA are documented in the authoritative source:

DEPENDENCIES.md § 2.3 — Vulnerability Monitoring & Remediation

5.3 Trusted Code Paths

  • All commits to main require a Pull Request with maintainer review.
  • Security-critical files (ttp/firewall/, dns.py, tor_control.py, selinux.py, watchdog/, .github/workflows/) require explicit sign-off from the Project Lead (see MAINTAINERS.md).
  • All commits must include a Signed-off-by header (DCO) — see CONTRIBUTING.md.

6. Security Controls Summary

ControlTypeStatus
Atomic nftables rule loadingPreventive✅ Implemented
Kill-switch (reject all on failure)Preventive✅ Implemented
IPv6 routing or fallback blockingPreventive✅ Implemented
DoT (port 853) blockingPreventive✅ Implemented
DoH canary domain mitigation (torrc MapAddress)Preventive✅ Implemented (best-effort)
DoH TCP+QUIC IP blocking (nftables, port 443)Preventive✅ Implemented (v0.4.7)
Teardown outbound traffic lockdownPreventive✅ Implemented
Conntrack table flush during teardownPreventive✅ Implemented
DNS bind-mount overlay (no disk writes)Preventive✅ Implemented
Volatile runtime (tmpfs, zero persistent configuration residue)Preventive✅ Implemented
Cookie-authenticated Tor control socketPreventive✅ Implemented
Session watchdog with auto-healingDetective + Corrective✅ Implemented (optional)
Emergency killswitch (two-strike policy)Corrective✅ Implemented
Crash recovery (orphaned lock detection)Corrective✅ Implemented
Sigstore artifact signingPreventive✅ Implemented
Dependabot CVE monitoringDetective✅ Enabled
pip-audit scoped to projectDetective✅ Documented
DCO commit sign-offPreventive✅ Required
PR review for security-critical filesPreventive✅ Policy (MAINTAINERS.md)

7. Out of Scope

The following threats are explicitly out of scope for TTP's security model:

  • Anonymity against a global passive adversary (timing attacks, traffic analysis at internet scale)
  • Security of the Tor network itself (malicious relays, Tor protocol vulnerabilities)
  • Application-layer deanonymization (browser fingerprinting, cookie tracking, WebRTC leaks)
  • Host OS compromise (kernel rootkits, malicious hardware, physical access attacks)
  • Non-host network namespaces (Docker, LXC, VMs running on the same host)
  • User behavioral deanonymization (logging into personal accounts, metadata in documents)
  • Protection across a reboot, or from boot. A session lives in /run and ends with the machine; TTP has no start-at-boot mode. After a reboot the host is in cleartext until ttp start is run again - measured in section 4.3, not assumed.

For high-risk use cases, refer to Tails OS or Whonix.