- 필수 기능
- 시작하기
- Glossary
- 표준 속성
- Guides
- Agent
- 통합
- 개방형텔레메트리
- 개발자
- Administrator's Guide
- API
- Datadog Mobile App
- CoScreen
- Cloudcraft
- 앱 내
- 서비스 관리
- 인프라스트럭처
- 애플리케이션 성능
- APM
- Continuous Profiler
- 스팬 시각화
- 데이터 스트림 모니터링
- 데이터 작업 모니터링
- 디지털 경험
- 소프트웨어 제공
- 보안
- AI Observability
- 로그 관리
- 관리
",t};e.buildCustomizationMenuUi=t;function n(e){let t='
",t}function s(e){let n=e.filter.currentValue||e.filter.defaultValue,t='${e.filter.label}
`,e.filter.options.forEach(s=>{let o=s.id===n;t+=``}),t+="${e.filter.label}
`,t+=`ID: python-flask/command-injection
Language: Python
Severity: Error
Category: Security
CWE: 78
This rule identifies potential OS Command Injection vulnerabilities in Python code. These vulnerabilities occur when an application constructs shell commands by incorporating user-supplied or otherwise untrusted data directly into command strings without proper sanitization. An attacker can exploit this by crafting input that includes malicious shell commands, which are then executed on the server with the privileges of the running application. This can lead to unauthorized server access, data breaches, arbitrary code execution, or denial of service.
The rule specifically looks for:
subprocess
module functions (like run
, call
, Popen
, etc.) where the command argument is built using string formatting (f-strings, .format()
, %
operator) or concatenation with potentially unsanitized variables, especially when shell=True
might be implied or used.cmd
, command
, args
, etc.) where the string value is constructed using these unsafe methods, and these variables are likely intended for command execution.To prevent OS Command Injection vulnerabilities when constructing and executing shell commands in Python:
Prefer List Arguments with shell=False
: When using subprocess
functions (e.g., subprocess.run()
, subprocess.call()
), pass the command and its arguments as a list of strings. Ensure shell=False
is used (this is the default for subprocess.run()
). This method treats each item in the list as a literal argument and does not invoke a shell to interpret the command string, significantly reducing the risk of injection.
import subprocess
user_filename = "some_file.txt" # Example of an argument, potentially from user input
# Compliant: command and arguments as a list, shell=False (default)
try:
result = subprocess.run(["cat", user_filename], capture_output=True, text=True, check=True)
print(result.stdout)
except subprocess.CalledProcessError as e:
print(f"Error executing command: {e}")
except FileNotFoundError:
print("Error: Command not found.")
Use shlex.quote()
for Shell Execution: If you absolutely must use shell=True
or need to construct a single command string that will be interpreted by the shell, sanitize any dynamic parts of the command string (especially those derived from external input) using shlex.quote()
. This function escapes characters that have special meaning to the shell, making the input safe.
import subprocess
import shlex
user_input = "some value; malicious_command" # Example of user input
safe_argument = shlex.quote(user_input)
# Compliant: user input is quoted before being included in a command string for shell=True
try:
result = subprocess.run(f"echo {safe_argument}", shell=True, capture_output=True, text=True, check=True)
print(result.stdout)
except subprocess.CalledProcessError as e:
print(f"Error executing command: {e}")
Avoid Direct String Concatenation/Formatting for Commands: Do not build command strings by directly concatenating or formatting them with untrusted input if the command will be processed by a shell.
# Non-compliant example:
# user_directory = request.args.get("dir")
# command = "ls -l " + user_directory
# subprocess.run(command, shell=True) # Vulnerable
# Non-compliant example:
# search_term = request.args.get("term")
# command = f"grep '{search_term}' /var/log/app.log"
# subprocess.run(command, shell=True) # Vulnerable
Instead, use the list-based approach (Remediation #1) or shlex.quote()
(Remediation #2).
Validate and Sanitize All External Input: Beyond specific command construction, rigorously validate and sanitize any external input that influences program behavior, including what commands are run or what arguments are passed. Use allowlists for permissible inputs where possible.
Principle of Least Privilege: Run your application with the minimum privileges necessary. This will not prevent the injection itself but can limit the potential damage if such a vulnerability is exploited.
import subprocess
import urllib.parse
from flask import request
def vulnerable_example1():
param = request.headers.get('user_input', '')
param = urllib.parse.unquote(param)
command = f"echo {param}"
result = subprocess.run(command, shell=True, capture_output=True, text=True)
return result.stdout
def vulnerable_example2():
user_input = get_user_input()
cmd = "ls " + user_input
subprocess.call(cmd, shell=True)
def vulnerable_example3():
filename = request.args.get('file')
args = ["sh", "-c", "cat " + filename]
subprocess.run(args)
def vulnerable_example4():
search = input("Enter search term: ")
subprocess.check_output("grep '{}'".format(search), shell=True)
import subprocess
import shlex
def safe_example1():
# Using list arguments without concatenation
result = subprocess.run(["echo", "hello"], capture_output=True, text=True)
return result.stdout
def safe_example2():
# Using shlex.quote for proper escaping
user_input = get_user_input()
safe_input = shlex.quote(user_input)
subprocess.run(f"echo {safe_input}", shell=True)
def safe_example3():
# Parameterized approach
filename = "hardcoded.txt"
subprocess.run(["cat", filename])
def safe_example4():
# Static command without user input
command = "ls -la /tmp"
subprocess.run(command, shell=True)
# annotation_count: 0