Fix Command Injection in Tornado
Command injection in Tornado occurs when untrusted input is passed directly to system shells via functions like os.system, os.popen, or subprocess.run(shell=True). In a high-performance framework like Tornado, this allows attackers to break out of the application logic and execute arbitrary code on the underlying host. The goal is to move from string-based shell execution to vector-based subprocess calls.
The Vulnerable Pattern
import tornado.web import os
class PingHandler(tornado.web.RequestHandler): async def get(self): # VULNERABLE: User input is directly interpolated into a shell command string target = self.get_argument(‘target’) command = f’ping -c 1 {target}’ output = os.popen(command).read() self.write(f’Result: {output}’)
The Secure Implementation
The fix involves two primary layers of defense. First, replace string-based command construction with a list (argument vector). When shell=False, the OS executes the binary directly, treating the user input as a literal string argument rather than a command to be parsed by /bin/sh. Second, avoid os.system or os.popen entirely in favor of the subprocess module, which provides better control over I/O and security boundaries. For additional hardening, validate input against a strict regex (e.g., ensuring 'target' is a valid IP or hostname) before processing.
import tornado.web import subprocess import shlex
class PingHandler(tornado.web.RequestHandler): async def get(self): target = self.get_argument(‘target’) # SECURE: Use a list of arguments and set shell=False (default) # This prevents the shell from interpreting metacharacters like ; or && try: result = subprocess.run( [‘ping’, ‘-c’, ‘1’, target], capture_output=True, text=True, shell=False, timeout=5 ) self.write(f’Result: {result.stdout}’) except subprocess.CalledProcessError as e: self.set_status(500) self.write(‘Command execution failed.’)
Your Tornado API
might be exposed to Command Injection
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.