Skip to main content

Tornado EUVDEUVD-2026-90657

| CVE-2026-103263 HIGH
Improper Link Resolution Before File Access (CWE-59)
2026-10-01 VulnCheck GHSA-4cjq-6jh9-w2f5
8.2
CVSS 4.0 · Vendor: VulnCheck
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Identify internet-facing Tornado StaticFileHandler
  2. Delivery
    Locate or plant symlink escaping static root
  3. Exploit
    Send unauthenticated GET for symlink path
  4. Execution
    Prefix check passes, open() follows link
  5. Impact
    Read config/private keys/secrets

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A01:2025 - Broken Access Control
ASVS 5.0
V5 - File Handling Symlink resolution safety
Exploitation Conditions

Requires an application using tornado.web.StaticFileHandler to serve static files AND a symbolic link that resolves outside the configured static root existing inside that root. Per the advisory, this condition arises in apps serving user-uploadable content, or where the static directory is populated by build/deploy pipelines that create symlinks (npm link, webpack, Docker volume mounts, CDN sync tools); an attacker who can trigger symlink creation or exploit a pre-existing one succeeds. No authentication or user interaction is needed (PR:N/UI:N), and exploitation is purely a GET request. The limiting factor (CVSS 4.0 AT:P) is the symlink precondition: a static tree that never contains out-of-root symlinks is not exploitable. The read is bounded to files accessible to the Tornado process user. Fixed in 6.5.9, which uses os.path.realpath() and adds an opt-in allowed_symlink_directory.

Impact

This is a genuine, high-value issue for exposed Tornado deployments but its real-world exploitability hinges on a precondition rather than being a turnkey remote read. The vendor CVSS 4.0 vector (8.2, AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:N/VA:N) correctly captures the key nuance: it is network-reachable and unauthenticated (PR:N/UI:N), with high confidentiality impact (VC:H) and no integrity or availability impact - but it carries AT:P (Attack Requirements: Present), reflecting that a symlink escaping the static root must already exist inside it or be plantable by the attacker. A public PoC exists in the GHSA advisory (full reproduction steps), so weaponization effort is trivial where the precondition holds - but POC availability is NOT active exploitation. There is no EPSS score and no CISA KEV listing in the provided data, so there is no evidence of in-the-wild exploitation. The honest read: this is a real priority for any Tornado app that serves user-uploadable content or whose static dir is populated by build/deploy tooling that creates symlinks (npm link, webpack, Docker volume mounts, CDN sync), and a lower priority for static trees that never contain symlinks. Note a scoring nuance to verify: in CVSS 3.1 terms the symlink precondition is better expressed as AC:H, which would lower the 3.1-equivalent score versus the 8.2 4.0 figure.

Exploit ScenarioDerived

An attacker identifies a Tornado application serving files via StaticFileHandler and locates (or, via an upload/build pipeline, plants) a symbolic link inside the static root that points outside it - e.g. to /etc/passwd, a private key, or an app config file. They then issue an unauthenticated GET for that path; os.path.abspath() plus the startswith() prefix check passes because symlinks aren't resolved, while the subsequent os.path.isfile/open follow the link and return the target's contents. A public PoC with complete reproduction steps is published in the GHSA advisory.

This Week Schedule remediation this week. Why: HIGH severity (CVSS 7.0-8.9).
Patch available 0.5% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – Oct 01, 2026

Unauthenticated local file disclosure in Tornado before 6.5.9 lets remote attackers read files outside a configured static root by requesting a symbolic link that lives inside that root but resolves elsewhere, exposing configuration files, private keys, and application secrets readable by the Tornado process user. Exploitation is a single GET request requiring no authentication and no user interaction (assessed CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N), but it depends on a precondition rather than being turnkey: an out-of-root symlink must already exist inside the static directory, a situation the upstream advisory says arises in applications serving user-uploadable content or where build/deploy pipelines (npm link, webpack, Docker volume mounts, CDN sync tools) create symlinks. The issue is fixed in 6.5.9, public reproduction steps are published in the upstream GitHub Security Advisory, and there is no CISA KEV listing.

RemediationAI

Upgrade to Tornado 6.5.9 or later - vendor-released patch: 6.5.9 (pip install -U "tornado>=6.5.9"), delivered by upstream PR https://github.com/tornadoweb/tornado/pull/3719 and commit https://github.com/tornadoweb/tornado/commit/437ab5f76565403b3403438d2e555d11f8128d32, which switches get_absolute_path()/validate_absolute_path() to os.path.realpath() and adds the opt-in allowed_symlink_directory parameter; see the advisory at https://github.com/tornadoweb/tornado/security/advisories/GHSA-c2m8-h5v5-343r. If immediate upgrade is not possible, the most direct compensating control is to guarantee the static root contains no symlinks that resolve outside it: audit the tree with find <root> -type l -exec realpath {} \; and remove or replace any escaping links, and disable symlink following in whatever populates the directory (npm install --no-bin-links, avoid npm link/webpack symlink output, copy rather than bind-mount Docker volumes, and configure CDN/sync tooling to dereference links) - the trade-off is that legitimate symlink-based deploy layouts must be reworked and any in-root symlink convenience is lost. Do not serve user-uploaded content through StaticFileHandler on a shared filesystem; keep uploads in a dedicated path that is not symlink-writable by unprivileged users, or front static content with a reverse proxy (e.g. nginx) configured with symlink containment, accepting the added operational complexity of an extra component. Running the Tornado process as a low-privilege account with no access to /etc/passwd, private keys, or secret stores reduces the blast radius but does not eliminate the read, so it is a hardening measure rather than a fix. Removing any code path by which an attacker can cause symlink creation (upload, archive extraction, template or plugin writes into the static tree) closes the precondition entirely at the cost of restricting those features.

Affected VersionsENISA

Tornado 0 <6.5.9

Affected Packages

pypi tornado fix: 6.5.9

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 1 package in pypi

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

The flaw sits in tornado.web.StaticFileHandler and is classified as CWE-59 (Improper Link Resolution Before File Access, i.e. link following). Two cooperating methods are involved: get_absolute_path() normalises the requested path with os.path.abspath(), and validate_absolute_path() applies the same os.path.abspath() to the configured root and then performs a string prefix check (startswith('/var/www/static/')). os.path.abspath() collapses '.' and '..' segments but deliberately does not resolve symbolic links, so a path such as /var/www/static/link passes the prefix test no matter where 'link' actually points. The subsequent os.path.exists() and os.path.isfile() calls, however, do follow symlinks, so the file ultimately opened is the symlink's target - which may be anywhere on the filesystem reachable by the process user. The upstream fix replaces os.path.abspath() with os.path.realpath() in both methods so the resolved real path of the target is validated against the root, and it introduces an opt-in allowed_symlink_directory parameter for deployments that intentionally serve out-of-root symlinks. The regression tests added upstream confirm that escaping file and directory symlinks now return 403, that in-root symlinks still serve, and that a missing versus existing out-of-bounds target both return 403 so the handler cannot be used as a filesystem existence oracle. The affected component is the pip-distributed tornado package (CPE cpe:2.3:a:tornadoweb:tornado, EUVD-2026-90657), present anywhere an application mounts StaticFileHandler over a directory that may contain symlinks; the CVSS:4.0 vector's AT:P (Attack Requirements: Present) captures that this is only exploitable when the symlink precondition holds.

Know when Tornado gets its next vulnerability

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

Vendor (VulnCheck) PRIMARY 8.2 HIGH
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N
vuln.today AI 5.9 MEDIUM

Network, unauthenticated, no UI; AC:H because exploitation depends on an out-of-root symlink existing inside the static dir (not attacker-guaranteed); confidentiality-only arbitrary file read, so I/A:N.

3.1 AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N
4.0 AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N
Red Hat 5.9 MEDIUM

Primary rating from Vendor (VulnCheck).

CVSS VectorVendor: VulnCheck

Attack Vector
Network
Attack Complexity
Low
Attack Requirements
Present
Privileges Required
None
User Interaction
None
Vulnerable system: Confidentiality
High
Vulnerable system: Integrity
None
Vulnerable system: Availability
None
Subsequent system: Confidentiality
None
Subsequent system: Integrity
None
Subsequent system: Availability
None

DescriptionCVE.org

Tornado before 6.5.9 contains a path traversal vulnerability in StaticFileHandler that follows symbolic links inside the static root without confirming the resolved target stays within it. When a symlink pointing outside the static directory exists inside it, unauthenticated attackers can request it to read files such as configuration files, private keys, and application secrets accessible to the process user.

Technical POC Analysis

CWE-59 (Improper Link Resolution Before File Access, "Link Following").

Full technical POC analysis - root cause, step-by-step exploitation and patch breakdown - is part of the Pro and Business plans.

Executive ViewAI

Why It Matters

Tornado, the Python web framework used across a wide range of internal and customer-facing services, can be tricked into serving files from outside its designated static content directory, potentially exposing configuration files, private keys and application secrets to anyone who can reach the affected endpoint. Exploitation requires no credentials and no user interaction, but only succeeds where a symbolic link escaping the static root already exists - most commonly in services that accept user uploads or that rely on build and deployment tooling such as npm link, webpack, Docker volume mounts or CDN sync. Leadership should care because the data at risk is the credential material that protects other systems, making this a plausible stepping stone to broader compromise of the environments running Tornado.

Business Impact: High
Compensating Controls

Apply vendor patch.

Threat Intelligence Overview

EPSS Score
0.5%
Top 58% exploitable
Prevalence
High
widely-deployed, popular Python async web framework
Data Quality
5 sources
Confidence: Medium
EUVD NVD CVE.org EPSS Vulnrichment Vendor GitHub

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity HIGH
CISA KEV No
Public POC No
EPSS 0.5%
Patch available Yes
Active threat No
Deciding rule
HIGH severity (CVSS 7.0-8.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision
Scheduled
Exploitation
Poc
System Exposure· derived
Open
Automatable
No
Human Impact
High
Technical Impact
Partial

Priority Score

42
Low Medium High Critical
KEV: 0
EPSS: +1
CVSS: +41
PoC: 0
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Path traversal exploits occur when applications use user-controlled input to construct file system paths without proper validation.

CVE-2024-42733 CRITICAL POC
9.8 Mar 07

An issue in Docmosis Tornado v.2.9.7 and before allows a remote attacker to execute arbitrary code via a crafted script

CVE-2023-25266 HIGH POC
8.8 Feb 28

An issue was discovered in Docmosis Tornado prior to version 2.9.5. Rated high severity (CVSS 8.8), this vulnerability i

CVE-2025-67726 HIGH POC
7.5

py3-tornado in Alpine Linux received a security fix packaged as version 6.5.4-r0, addressing an unspecified vulnerabilit

CVE-2023-25265 HIGH POC
7.5 Feb 28

Docmosis Tornado <= 2.9.4 is vulnerable to Directory Traversal leading to the disclosure of arbitrary content on the fil

CVE-2023-25264 HIGH POC
7.5 Feb 28

An issue was discovered in Docmosis Tornado prior to version 2.9.5. Rated high severity (CVSS 7.5), this vulnerability i

CVE-2026-103262 HIGH
8.7 Oct 01

Denial of service in the Tornado web framework's CurlAsyncHTTPClient (all releases before 6.5.9) lets an unauthenticated

CVE-2026-31958 HIGH
8.7 Mar 11

In versions of Tornado prior to 6.5.5, the only limit on the number of parts in `multipart/form-data` is the `max_body_s

CVE-2026-91990 HIGH
8.7 Sep 15

Memory amplification denial of service in the Tornado Python web framework before 6.5.8 lets unauthenticated remote atta

CVE-2026-91992 HIGH
8.2 Sep 15

Credential leakage in Tornado's CurlAsyncHTTPClient (all releases through 6.5.6) lets sensitive per-request state — clie

CVE-2026-82397 HIGH
7.5 Aug 31

Denial-of-service in Tornado prior to 6.5.8 allows unauthenticated remote attackers to stall the entire server by sendin

CVE-2025-67725 HIGH
7.5

Tornado Python web framework on Alpine Linux received a security fix in package version 6.5.4-r0, addressing an uncharac

CVE-2024-52804 HIGH
7.5 Nov 22

Tornado is a Python web framework and asynchronous networking library. Rated high severity (CVSS 7.5), this vulnerabilit

Vendor StatusVendor

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy