Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐍 PyPI
Not in CISA KEV

Tornado: StaticFileHandler follows symlinks outside static root (path traversal)GHSA-c2m8-h5v5-343r

Fix: tornadoweb/tornado#3719

GHSA-c2m8-h5v5-343r is a CWE-59 vulnerability in tornado. A fix is available for tornado — see the affected versions and patch details below.

Also known asCVE-2026-103263
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Oct 22, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.

Exploitation and automatability from CISA’s SSVC triage for GHSA-c2m8-h5v5-343r.

EPSS Exploitation Probability

via FIRST.org ↗
0.5%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs43th percentile — riskier than 43% of all scored CVEsHighest risk

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

Real-World Exposure

1 pkg affected
🐍tornado

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.

Description

Summary

StaticFileHandler allows an unauthenticated attacker to read arbitrary files from the server's filesystem by requesting a path that resolves to a symbolic link placed inside the static root directory. Any application that serves user-uploadable content, or whose static directory is populated by a build/deploy pipeline that creates symlinks (e.g. npm link, webpack, Docker volume mounts, CDN sync tools), is affected. An attacker who can trigger the creation of a symlink pointing outside the static root—or exploit one that already exists—can retrieve sensitive files such as /etc/passwd, private keys, configuration files, or application secrets.

Details

The vulnerability is in tornado.web.StaticFileHandler, specifically in the interaction between two methods in tornado/web.py:

os.path.abspath() normalises . and .. segments but does not resolve symbolic links. As a result, a path like /var/www/static/link passes the startswith("/var/www/static/") check regardless of where link actually points.

Immediately after, os.path.exists() and os.path.isfile() do follow symlinks, so the file they ultimately open is the symlink's target. The fix would be to replace os.path.abspath() with os.path.realpath() in both methods, so the resolved real path of the symlink target is validated against the root, not just its string representation inside the static directory.

PoC

Complete instructions, including specific configuration details, to reproduce the vulnerability. Prerequisites: Python 3.x, Tornado installed.

  1. Create the environment
mkdir -p /tmp/static
echo "DB_PASSWORD=s3cr3t" > /tmp/secret.conf   
ln -s /tmp/secret.conf /tmp/static/config.conf 
  1. Minimal vulnerable server (server.py):
import tornado.web, tornado.ioloop

app = tornado.web.Application([
    (r"/static/(.*)", tornado.web.StaticFileHandler, {"path": "/tmp/static"}),
])
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
  1. Exploit: curl http://localhost:8888/static/config.conf

Impact

Any application using StaticFileHandler is potentially affected if:

  • the static directory contains symlinks pointing outside it (common with build tooling), or
  • the application allows file uploads into the static directory without stripping symlinks.

An unauthenticated remote attacker can read any file readable by the process user: application secrets, private TLS keys, database credentials, /etc/shadow, SSH keys, or source code (depending on the process's filesystem permissions).

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐍PyPItornadoall versions6.5.9pip install --upgrade 'tornado==6.5.9'

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for tornado, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update tornado to 6.5.9 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-c2m8-h5v5-343r is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

Fixing This On Your OS

If you run this on a Linux distribution, patch through your package manager against the distro's own security advisory below — it tracks the exact backported fix for your release, which can ship on a different timeline (and sometimes a different severity) than the upstream project.

Red HatModerate

A moderate information-disclosure vulnerability was found in Tornado's StaticFileHandler. Tornado is shipped or depended upon in Red Hat Enterprise Linux (for example the pcs component), Red Hat OpenShift Container Platform, and other Red Hat products that bundle the python-tornado package or pull it in through…

Workaround published by Red Hat
Mitigation for this issue is either not available or the currently available options do not meet the Red Hat Product Security criteria comprising ease of use and deployment, applicability to widespread installation base, or stability.
Source: Red Hat security advisory for GHSA-c2m8-h5v5-343r (CC BY 4.0)
UbuntuMEDIUM

Frequently Asked Questions

### Summary StaticFileHandler allows an unauthenticated attacker to read arbitrary files from the server's filesystem by requesting a path that resolves to a symbolic link placed inside the static root directory. Any application that serves user-uploadable content, or whose static directory is populated by a build/deploy pipeline that creates symlinks (e.g. npm link, webpack, Docker volume mounts, CDN sync tools), is affected. An attacker who can trigger the creation of a symlink pointing outside the static root—or exploit one that already exists—can retrieve sensitive files such as /etc/passw
O3 Security · Impact-Aware SCA

Is GHSA-c2m8-h5v5-343r in your dependencies?

Find it across PyPI, including transitive dependencies.

Tornado: StaticFileHandler follows symlinks outside static…