GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • CodeQL documentation
  • CodeQL overview
  • Writing CodeQL queries
  • CodeQL language guides
  • QL language reference
  • CodeQL standard-libraries
  • CodeQL query help
  • CodeQL repository
  • QL publications
  • CodeQL query help for C and C++
  • CodeQL query help for C#
  • CodeQL query help for GitHub Actions
  • CodeQL query help for Go
  • CodeQL query help for Java and Kotlin

This view

  • Original page
  • New address

GeezerVison is showing codeql.github.com — Unsafe shell command constructed from library input — CodeQL query help documentation

Unsafe shell command constructed from library input¶

ID: py/shell-command-constructed-from-input
Kind: path-problem
Security severity: 6.3
Severity: error
Precision: medium
Tags:
   - correctness
   - security
   - external/cwe/cwe-078
   - external/cwe/cwe-088
   - external/cwe/cwe-073
Query suites:
   - python-security-extended.qls
   - python-security-and-quality.qls

Click to see the query in the CodeQL repository

Dynamically constructing a shell command with inputs from library functions may inadvertently change the meaning of the shell command. Clients using the exported function may use inputs containing characters that the shell interprets in a special way, for instance quotes and spaces. This can result in the shell command misbehaving, or even allowing a malicious user to execute arbitrary commands on the system.

Recommendation¶

If possible, provide the dynamic arguments to the shell as an array to APIs such as subprocess.run to avoid interpretation by the shell.

Alternatively, if the shell command must be constructed dynamically, then add code to ensure that special characters do not alter the shell command unexpectedly.

Example¶

The following example shows a dynamically constructed shell command that downloads a file from a remote URL.

import os

def download(path): 
    os.system("wget " + path) # NOT OK

The shell command will, however, fail to work as intended if the input contains spaces or other special characters interpreted in a special way by the shell.

Even worse, a client might pass in user-controlled data, not knowing that the input is interpreted as a shell command. This could allow a malicious user to provide the input http://example.org; cat /etc/passwd in order to execute the command cat /etc/passwd.

To avoid such potentially catastrophic behaviors, provide the input from library functions as an argument that does not get interpreted by a shell:

import subprocess

def download(path): 
    subprocess.run(["wget", path]) # OK

References¶

  • OWASP: Command Injection.

  • Common Weakness Enumeration: CWE-78.

  • Common Weakness Enumeration: CWE-88.

  • Common Weakness Enumeration: CWE-73.

  • © GitHub, Inc.
  • Terms
  • Privacy
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.