← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2026-38978 · CWE-1021 · Disclosed 2026-06-02

transmission through 4

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is a control panel behind glass that forgot to stop other websites from putting their own buttons over it

CVE-2026-38978 is a clickjacking / UI-redress weakness in Transmission's browser-facing management surface. Upstream issue and fix data show the affected path is the HTTP response handling for the bundled WebUI and RPC endpoints, where Transmission through 4.1.1 did not add X-Frame-Options or CSP frame-ancestors protections before returning content. The public report also demonstrated the same missing headers on a 4.2.0-dev build before the March 31, 2026 fix, so the vulnerable behavior was not limited to one packaging flavor.

In practice this is less severe than a generic 'network attack' label would imply. The attacker does not get code execution, data exfiltration, or direct server compromise from the missing headers alone; they need a victim to load an attacker page and click through a precisely aligned hidden frame. Transmission's defaults also add meaningful friction: rpc_whitelist_enabled is true and the default whitelist is 127.0.0.1, which kills many remote-path scenarios unless admins deliberately broaden exposure or publish the UI through a reverse proxy.

"ASSESSED AT MEDIUM: real bug, but it needs a live victim, browser clicks, and usually non-default exposure."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Host a lure page with a framed Transmission UI

The attacker uses a standard browser clickjacking setup: an iframe pointed at /transmission/web/ or /transmission/rpc, then CSS overlays or decoy buttons to steer clicks. No memory corruption or protocol bug is needed; the weakness is simply that vulnerable builds return frameable responses. The public GitHub issue includes reproducible header checks showing those protections were absent before the fix.
Conditions required:
  • Attacker can get the victim to browse to an attacker-controlled page
  • Victim browser can reach the Transmission WebUI/RPC endpoint, either on localhost, LAN, or a published URL
Where this breaks in practice:
  • If the UI is not reachable from the browser, the chain dies immediately
  • Precise UI alignment is brittle across browsers, screen sizes, and future UI changes
Detection/coverage: Most vuln scanners will only catch this with header inspection on /transmission/web/ and /transmission/rpc; network scanners looking for RCE patterns will miss it.
STEP 02

Rely on reachable admin surface and surviving access controls

Transmission daemon defaults matter here. The docs show rpc_enabled is true for transmission-daemon, rpc_bind_address defaults to 0.0.0.0, but rpc_whitelist_enabled is also true and rpc_whitelist defaults to 127.0.0.1. That means the realistic sweet spot is often browser-to-localhost or deliberately exposed/reverse-proxied deployments, not generic internet spray-and-pray exploitation.
Conditions required:
  • Target runs transmission-daemon with WebUI/RPC active
  • Whitelist/auth/reverse-proxy settings allow the victim browser to reach the interface
Where this breaks in practice:
  • Default IP whitelist sharply reduces true remote exposure
  • Many enterprise environments do not run Transmission at all, shrinking population
Detection/coverage: Configuration review is stronger than signature-based scanning here: inspect settings.json for rpc_whitelist_enabled, rpc_whitelist, rpc_authentication_required, and any non-localhost publishing.
STEP 03

Steer victim clicks into privileged actions

If the frame loads, the attacker can induce state-changing actions through the WebUI using the victim's browser context. This is classic UI-redress: the victim thinks they are clicking a harmless lure, but the clicks land on Transmission controls underneath. The likely outcome is unauthorized torrent management or settings changes inside Transmission, not host-level execution.
Conditions required:
  • Victim interacts with the lure page
  • Victim is already authenticated, or the deployment does not require authentication from the victim's reachable path
Where this breaks in practice:
  • User interaction is mandatory
  • Same-origin policy still blocks easy response reading; this is action-steering, not broad data theft
Detection/coverage: EDR will rarely flag the exploit itself. Best telemetry is unusual browser access to local/admin URLs plus Transmission logs showing unexpected Web/RPC actions.
STEP 04

Impact stays inside the Transmission management plane

The blast radius is bounded by what the WebUI/RPC can do: add/remove torrents, alter settings, or otherwise manipulate the torrent client. That can still create legal, operational, or data-handling headaches, especially on NAS or lab systems, but it is a long way from a one-click enterprise takeover.
Conditions required:
  • Victim actions successfully trigger meaningful WebUI operations
Where this breaks in practice:
  • No direct privilege escalation beyond the Transmission process context
  • Follow-on host compromise would require a separate bug or dangerous local scripting configuration
Detection/coverage: Audit for anomalous torrent additions, configuration changes, or script-hook changes in Transmission logs and config diffs.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo evidence of active exploitation found in reviewed authoritative sources, and no CISA KEV listing as of 2026-06-05.
Proof-of-concept availabilityPublic reproduction exists via GitHub issue #8726, including curl header checks and runtime evidence. I found no turnkey exploit kit or mass-exploitation tooling.
EPSS0.00017 from the user-provided intel. That is extremely low exploit-likelihood signaling; reviewed sources did not provide a trustworthy percentile for this CVE.
KEV statusNot listed in the CISA KEV catalog. Disclosure date provided in the case file is 2026-06-02.
Weakness classCWE-1021Improper Restriction of Rendered UI Layers or Frames, i.e. clickjacking / UI redress.
Affected versionsTransmission through 4.1.1 is affected per the CVE text. The public bug report also reproduced the missing headers on 4.2.0-dev before the fix landed on 2026-03-31.
Fixed versionUpstream 4.1.2 adds X-Frame-Options: SAMEORIGIN and Content-Security-Policy: frame-ancestors 'self' in the HTTP response path. I found no authoritative distro backport bulletin for this specific CVE during this review.
Exposure realityDefaults cut the reachable population down hard: docs show rpc_enabled=true for daemon, but also rpc_whitelist_enabled=true with default whitelist 127.0.0.1. Translation: many remote attacks fail by default, though browser-to-localhost and intentionally published reverse-proxy deployments remain in play.
Scanning / exposure dataTransmission's WebUI commonly uses TCP/9091. Public internet search engines like Shodan and Censys can query this surface, but I did not pull a defensible internet-wide count from an authoritative source for this assessment.
Reporter / fix provenanceBug reported by quart27219 on GitHub on 2026-03-24; fix merged by ckerr on 2026-03-31 and shipped in 4.1.2.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to MEDIUM (4.6/10)

The decisive downward pressure is attack-chain friction: this bug generally needs a reachable WebUI, a live victim in a browser, and successful click steering on a framed admin interface. It is a legitimate privilege-bearing web weakness, but the reachable population and blast radius are both much narrower than classic internet-facing application bugs.

HIGH Technical root cause and fixed-version assessment
MEDIUM Real-world enterprise prevalence and exposure population

Why this verdict

  • First assessment only: there is no vendor or authority CVSS baseline, so this is a fresh severity call rather than an upgrade or downgrade.
  • Remote reachability is narrower than it looks: although daemon docs show rpc_bind_address defaulting to 0.0.0.0, the default rpc_whitelist_enabled=true and rpc_whitelist=127.0.0.1 mean many deployments are not broadly reachable from arbitrary remote hosts.
  • Exploit requires a live victim and user interaction: attacker success depends on getting a user to browse a malicious page and click through a hidden frame. That is materially weaker than unauthenticated server-side exploitation.
  • Blast radius is mostly application-scoped: the likely outcome is unauthorized torrent or configuration operations inside Transmission, not direct host takeover, credential dumping, or broad data theft.

Why not higher?

This is not a no-click, no-auth, server-side compromise. The chain needs browser reachability plus user interaction, and Transmission's default whitelist sharply limits true remote exposure in many installations. Even when successful, the direct impact is typically bounded to the Transmission control plane.

Why not lower?

This is still a privileged admin UI missing a basic browser-side safety boundary, and the weakness is publicly reproducible. For systems where users browse the Web from the same machine that can reach the daemon—especially localhost or reverse-proxied NAS setups—an attacker can turn ordinary user clicks into unauthorized administrative actions.

05 · Compensating Control

What to do — in priority order.

  1. Add anti-framing headers at the reverse proxy — If you front Transmission with Nginx, Apache, Traefik, or a NAS proxy, inject X-Frame-Options: SAMEORIGIN and CSP frame-ancestors 'self' immediately. For a MEDIUM verdict there is no noisgate mitigation SLA — go straight to the 365-day remediation window, but exposed instances should still get this hardening on the next admin change window because it directly kills the exploit path.
  2. Keep the WebUI local-only — Preserve or restore the default local trust boundary: leave rpc_whitelist_enabled on, keep rpc_whitelist narrow, and do not publish port 9091 externally unless there is a business case. There is no mitigation SLA for MEDIUM, so treat this as hardening work folded into normal admin maintenance while you plan the upgrade within 365 days.
  3. Require authentication everywhere the UI is reachable — Turn on rpc_authentication_required anywhere the WebUI is reachable beyond localhost. Authentication does not solve clickjacking by itself, but it removes the easiest unauthenticated local/LAN cases and is worthwhile defense-in-depth while you complete patching in the 365-day remediation window.
  4. Disable the WebUI if nobody needs it — If your use case is CLI-only or API-free, remove the entire browser attack surface by disabling RPC/WebUI on those nodes. Again, no mitigation SLA for MEDIUM; use ordinary service review and cleanup cycles, then finish patching or retirement within 365 days.
What doesn't work
  • SameSite cookie tuning is not the main answer here, because Transmission often uses Basic auth and the OWASP guidance explicitly notes clickjacking can survive controls that only target cookie inclusion.
  • A generic WAF is weak value here; the browser is loading legitimate application pages, not sending obviously malicious payloads.
  • Relying on obscure URLs or a non-default port does not help. If the browser can reach the UI, a framed lure page can still target it.
06 · Verification

Crowdsourced verification payload.

Run this from an auditor workstation or the target host against the live WebUI/RPC endpoint. Invoke it as bash check-cve-2026-38978.sh http://127.0.0.1:9091 or bash check-cve-2026-38978.sh https://transmission.example.com; it needs only network access to the UI and curl, with no elevated privileges required.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check-cve-2026-38978.sh
# Detects whether a Transmission WebUI/RPC endpoint appears vulnerable to CVE-2026-38978.
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

set -u

BASE_URL="${1:-http://127.0.0.1:9091}"
BASE_URL="${BASE_URL%/}"
WEB_URL="${BASE_URL}/transmission/web/"
RPC_URL="${BASE_URL}/transmission/rpc"

need_cmd() {
  command -v "$1" >/dev/null 2>&1 || {
    echo "UNKNOWN: required command not found: $1"
    exit 2
  }
}

need_cmd curl
need_cmd awk
need_cmd sed
need_cmd grep

fetch_headers() {
  local url="$1"
  curl -ksS -D - -o /dev/null --max-time 10 "$url" 2>/dev/null
}

has_clickjack_protection() {
  local headers="$1"
  echo "$headers" | tr -d '\r' | grep -Eiq '^X-Frame-Options:[[:space:]]*SAMEORIGIN$|^X-Frame-Options:[[:space:]]*DENY$' && return 0
  echo "$headers" | tr -d '\r' | grep -Eiq '^Content-Security-Policy:.*frame-ancestors[[:space:]]+('\''self'\''|none)' && return 0
  return 1
}

extract_version() {
  local v=""
  if command -v transmission-daemon >/dev/null 2>&1; then
    v=$(transmission-daemon --version 2>/dev/null | sed -nE 's/.* ([0-9]+\.[0-9]+\.[0-9]+).*/\1/p' | head -n1)
  fi
  if [ -z "$v" ] && command -v transmission-qt >/dev/null 2>&1; then
    v=$(transmission-qt --version 2>/dev/null | sed -nE 's/.* ([0-9]+\.[0-9]+\.[0-9]+).*/\1/p' | head -n1)
  fi
  if [ -z "$v" ] && command -v transmission-cli >/dev/null 2>&1; then
    v=$(transmission-cli --version 2>/dev/null | sed -nE 's/.* ([0-9]+\.[0-9]+\.[0-9]+).*/\1/p' | head -n1)
  fi
  echo "$v"
}

verlte() {
  [ "$1" = "$2" ] && return 0
  [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" = "$1" ]
}

WEB_HEADERS=$(fetch_headers "$WEB_URL")
RPC_HEADERS=$(fetch_headers "$RPC_URL")
VERSION=$(extract_version)

WEB_OK=1
RPC_OK=1
has_clickjack_protection "$WEB_HEADERS" && WEB_OK=0
has_clickjack_protection "$RPC_HEADERS" && RPC_OK=0

if [ $WEB_OK -eq 0 ] || [ $RPC_OK -eq 0 ]; then
  echo "PATCHED"
  echo "detail: anti-framing headers detected on at least one Transmission HTTP response path"
  [ -n "$VERSION" ] && echo "version: $VERSION"
  exit 0
fi

if [ -n "$VERSION" ] && verlte "$VERSION" "4.1.1"; then
  echo "VULNERABLE"
  echo "detail: local Transmission version is $VERSION (<= 4.1.1) and no anti-framing headers were detected"
  exit 1
fi

if [ -n "$WEB_HEADERS$RPC_HEADERS" ]; then
  echo "VULNERABLE"
  echo "detail: endpoint responded but anti-framing headers were not detected on /transmission/web/ or /transmission/rpc"
  [ -n "$VERSION" ] && echo "version: $VERSION"
  exit 1
fi

echo "UNKNOWN"
echo "detail: could not retrieve headers and no local Transmission version was detected"
exit 2
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, inventory every Transmission deployment, especially NAS boxes, seed hosts, lab systems, and user-managed Linux boxes, then identify which ones actually expose the WebUI/RPC beyond localhost or through a reverse proxy. This lands at MEDIUM, so there is no noisgate mitigation SLA — go straight to the 365-day remediation window; use normal maintenance to tighten whitelist/auth settings and add proxy anti-framing headers where exposure exists, then complete the upgrade to 4.1.2 or later within the noisgate remediation SLA of 365 days. If you discover a publicly reachable WebUI, treat that node as an exception and harden it immediately even though the formal bucket remains MEDIUM.

Sources

  1. Transmission 4.1.2 release notes
  2. Transmission fix PR #8749
  3. Transmission fix diff showing added X-Frame-Options and CSP
  4. Public bug report / reproduction issue #8726
  5. Transmission configuration docs
  6. OWASP Clickjacking Defense Cheat Sheet
  7. MITRE CWE-1021
  8. CISA Known Exploited Vulnerabilities Catalog
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.