Fix Improper Assets Management in Tornado
Improper Assets Management in Tornado typically surfaces as 'Shadow APIs' or path traversal via misconfigured StaticFileHandlers. In the wild, this allows attackers to discover undocumented endpoints, legacy debug tools, or sensitive source code. If you aren't explicitly mapping your attack surface, you're leaving the door open for automated scanners to map it for you.
The Vulnerable Pattern
import tornado.ioloop import tornado.web import osclass DebugHandler(tornado.web.RequestHandler): def get(self): # Undocumented debug endpoint left in production self.write({‘status’: ‘debug’, ‘env’: dict(os.environ)})
def make_app(): return tornado.web.Application([ (r’/debug’, DebugHandler), # Vulnerable: Mapping the entire filesystem root to /static (r’/static/(.*)’, tornado.web.StaticFileHandler, {‘path’: ’/’}), ])
if name == ‘main’: app = make_app() app.listen(8888) tornado.ioloop.IOLoop.current().start()
The Secure Implementation
To remediate improper asset management: 1. Scope `StaticFileHandler` to a dedicated, non-sensitive directory using `os.path.join` to prevent root filesystem exposure. 2. Remove or protect 'Shadow APIs'—any endpoint used for testing or debugging must be behind an `@authenticated` decorator or removed from the production routing table. 3. Set `debug=False` in the `Application` settings to prevent the leak of stack traces and internal state via the Tornado Autoreloader or default error pages. 4. Use a whitelist approach for routes; avoid broad regex patterns that might inadvertently capture sensitive internal paths.
import tornado.ioloop import tornado.web import os from tornado.web import authenticatedclass BaseHandler(tornado.web.RequestHandler): def get_current_user(self): return self.get_secure_cookie(‘user’)
class AdminHandler(BaseHandler): @authenticated def get(self): self.write({‘status’: ‘secure_admin_access’})
def make_app(): # Define explicit static directory static_path = os.path.join(os.path.dirname(file), ‘public_assets’)
return tornado.web.Application([ # 1. Explicit routing with no wildcards for sensitive data (r'/admin/dashboard', AdminHandler), # 2. Scoped StaticFileHandler (r'/static/(.*)', tornado.web.StaticFileHandler, {'path': static_path}), ], debug=False, # 3. Disable debug mode in production cookie_secret='__LONG_RANDOM_STRING__')
if name == ‘main’: app = make_app() app.listen(8888) tornado.ioloop.IOLoop.current().start()
Your Tornado API
might be exposed to Improper Assets Management
74% of Tornado apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.