{"description":"Trending threats, MITRE ATT\u0026CK coverage, and detection metadata. Fed continuously.","favicon":"https://feed.craftedsignal.io/favicon-32x32.png","feed_url":"https://feed.craftedsignal.io/products/tornado--6.5.8/feed.json","home_page_url":"https://feed.craftedsignal.io/","icon":"https://feed.craftedsignal.io/apple-touch-icon.png","items":[{"_cs_actors":[],"_cs_cpes":[],"_cs_cves":[],"_cs_exploited":false,"_cs_has_poc":false,"_cs_poc_references":[],"_cs_products":["Tornado (\u003c= 6.5.8)"],"_cs_severities":["high"],"_cs_tags":["path-traversal","web-application","python","tornado"],"_cs_type":"advisory","_cs_vendors":["Tornado"],"content_html":"\u003cp\u003eTornado versions 6.5.8 and earlier contain a path traversal vulnerability in the \u003ccode\u003eStaticFileHandler\u003c/code\u003e component that permits unauthenticated attackers to read arbitrary files from the filesystem. The vulnerability exists because \u003ccode\u003eget_absolute_path\u003c/code\u003e and \u003ccode\u003evalidate_absolute_path\u003c/code\u003e utilize \u003ccode\u003eos.path.abspath()\u003c/code\u003e to normalize requested paths and validate them against the configured static root. While \u003ccode\u003eos.path.abspath()\u003c/code\u003e correctly normalizes directory traversal sequences like \u003ccode\u003e..\u003c/code\u003e, it fails to resolve symbolic links. Subsequent file access operations (such as \u003ccode\u003eos.path.isfile()\u003c/code\u003e) resolve these symlinks to their actual targets.\u003c/p\u003e\n\u003cp\u003eIf an application serves a static directory containing symlinks - often introduced by build pipelines, web frameworks, or improper user-uploaded file handling - an attacker can traverse outside the intended static root by requesting a path that resolves through a symlink to sensitive files like configuration credentials, private keys, or system files. Defending organizations must ensure that \u003ccode\u003eStaticFileHandler\u003c/code\u003e is not used to serve directories containing untrusted or externally-linked content, or upgrade to a version incorporating \u003ccode\u003eos.path.realpath()\u003c/code\u003e for validation.\u003c/p\u003e\n\u003ch2 id=\"attack-chain\"\u003eAttack Chain\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003eAttacker identifies a target application utilizing the \u003ccode\u003etornado.web.StaticFileHandler\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eAttacker confirms the existence of a symbolic link within the application's static directory pointing to a sensitive file (e.g., \u003ccode\u003e/etc/passwd\u003c/code\u003e or \u003ccode\u003e/app/config.json\u003c/code\u003e).\u003c/li\u003e\n\u003cli\u003eAttacker sends a GET request to the Tornado server targeting the identified symlink (e.g., \u003ccode\u003eGET /static/symlink_name HTTP/1.1\u003c/code\u003e).\u003c/li\u003e\n\u003cli\u003eThe \u003ccode\u003eStaticFileHandler\u003c/code\u003e invokes \u003ccode\u003evalidate_absolute_path\u003c/code\u003e, which uses \u003ccode\u003eos.path.abspath()\u003c/code\u003e to check if the path starts with the configured static root.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eos.path.abspath()\u003c/code\u003e considers the path valid because it resides within the static directory structure as a string, ignoring that it is a symlink.\u003c/li\u003e\n\u003cli\u003eThe application proceeds to the file access stage where \u003ccode\u003eos.path.isfile()\u003c/code\u003e and subsequent read operations resolve the symlink target.\u003c/li\u003e\n\u003cli\u003eThe server reads the file content from the target location and returns the sensitive data to the attacker in the HTTP response body.\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"impact\"\u003eImpact\u003c/h2\u003e\n\u003cp\u003eSuccessful exploitation allows unauthenticated remote attackers to read any file readable by the user account running the Tornado application process. Depending on the environment, this typically includes application configuration secrets, database connection strings, TLS private keys, SSH keys, source code, and sensitive system files like \u003ccode\u003e/etc/shadow\u003c/code\u003e. This vulnerability impacts any deployment where the static root contains symlinks, which is a common scenario in modern development environments using Docker volume mounts, webpack-based build tools, or \u003ccode\u003enpm link\u003c/code\u003e.\u003c/p\u003e\n\u003ch2 id=\"recommendation\"\u003eRecommendation\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eUpgrade Tornado to a version that implements \u003ccode\u003eos.path.realpath()\u003c/code\u003e for directory validation to resolve and restrict symlinks to the static root.\u003c/li\u003e\n\u003cli\u003eIdentify and audit all directories served by \u003ccode\u003eStaticFileHandler\u003c/code\u003e for the presence of symbolic links using \u003ccode\u003efind /path/to/static -type l\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eImplement file system permissions that restrict the Tornado process user from accessing sensitive files outside of its intended scope as a defense-in-depth measure.\u003c/li\u003e\n\u003cli\u003eMonitor web server logs for suspicious requests to files typically not served as static assets, such as files ending in \u003ccode\u003e.conf\u003c/code\u003e, \u003ccode\u003e.key\u003c/code\u003e, \u003ccode\u003e.pem\u003c/code\u003e, or system configuration files.\u003c/li\u003e\n\u003c/ul\u003e\n","date_modified":"2026-10-01T04:20:55Z","date_published":"2026-10-01T04:20:55Z","id":"https://feed.craftedsignal.io/briefs/2026-10-tornado-path-traversal/","summary":"A path traversal vulnerability in Tornado's StaticFileHandler allows unauthenticated remote attackers to read arbitrary files via symbolic links within the static root directory.","title":"Tornado StaticFileHandler Symlink Path Traversal","url":"https://feed.craftedsignal.io/briefs/2026-10-tornado-path-traversal/"}],"language":"en","title":"CraftedSignal Threat Feed - Tornado (\u003c= 6.5.8)","version":"https://jsonfeed.org/version/1.1"}