Shell Command with Wildcard Character

MEDIUM

os.system() calls containing wildcard characters (*) may lead to unintended file inclusion or command injection through wildcard expansion.

Rule Information

Language
Python
Category
Python Core
Author
Shivasurya
Shivasurya
Last Updated
2026-03-22
Tags
pythonwildcardglob-expansioncommand-injectionos-systemCWE-78OWASP-A03
CWE References

Interactive Playground

Experiment with the vulnerable code and security rule below. Edit the code to see how the rule detects different vulnerability patterns.

pathfinder scan --ruleset python/PYTHON-LANG-SEC-013 --project .
1
2
3
4
rule.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

About This Rule

Understanding the vulnerability and how it is detected

Shell commands containing wildcard characters such as * (glob), ? (single character), and [ ] (character class) are expanded by the shell before the command executes. When wildcards are used in commands executed via os.system() or similar shell-invoking functions, an attacker who can create files in the target directory can exploit wildcard expansion to inject additional command-line flags or arguments.

The classic wildcard injection technique creates files with names like "-rf ." or "--checkpoint-action=exec=malicious.sh" in a directory that is processed with wildcards. When tar, rsync, chown, chmod, or similar commands run with a wildcard argument, the shell expands the wildcard to include the attacker-created filenames as additional command-line arguments, effectively injecting arbitrary flags into the command.

Use Python's glob module or pathlib for file pattern matching, and pass argument lists to subprocess.run() to avoid wildcard expansion entirely.

Security Implications

Potential attack scenarios if this vulnerability is exploited

1

Argument Injection via Malicious Filenames

An attacker who can create files in a directory processed with wildcards can create filenames that look like command-line flags (e.g., --checkpoint=1 for tar). The shell expands the wildcard to include these filenames as arguments, injecting attacker- controlled flags into the command execution.

2

File Inclusion Beyond Intended Scope

Wildcards in copy, tar, or rsync commands may match more files than intended if an attacker creates files in the target directory. This can cause sensitive files to be included in archives, transmitted over the network, or processed by insecure handlers.

3

Chown/Chmod Privilege Escalation

Running chown or chmod with wildcards is particularly dangerous. An attacker who creates a symlink named "file*" in the directory can cause chown to traverse the symlink and change ownership of arbitrary system files, leading to privilege escalation.

4

Data Destruction

Wildcard expansion in rm or find commands can include unintended files and directories in deletion operations. An attacker creating strategically named files can trigger deletion of configuration files, logs, or application data.

How to Fix

Recommended remediation steps

  • 1Replace shell commands with wildcards using Python's glob module or pathlib.Path.glob() for file pattern matching, combined with subprocess.run() using a list of arguments.
  • 2When using tar, rsync, or similar tools that must process multiple files, explicitly enumerate the files in Python and pass them as individual arguments rather than using shell wildcards.
  • 3Validate that files in directories processed with wildcards cannot be created by untrusted users; ensure proper directory permissions.
  • 4Use subprocess.run() with shell=False (the default) and a list of arguments to prevent shell wildcard expansion entirely.
  • 5For chown/chmod operations on multiple files, use Python's os.chown() and os.chmod() functions directly to avoid shell wildcard risks.

Detection Scope

How Code Pathfinder analyzes your code for this vulnerability

This rule detects os.system() calls where the command string contains wildcard characters (* or ?). The rule flags these patterns as they indicate shell wildcard expansion is in use, which requires review to ensure the wildcarded directory cannot contain attacker-controlled filenames that could inject arguments.

Compliance & Standards

Industry frameworks and regulations that require detection of this vulnerability

CWE Top 25
CWE-78 ranked #5 in 2023 Most Dangerous Software Weaknesses
OWASP Top 10
A03:2021 - Injection
NIST SP 800-53
SI-10: Information Input Validation
PCI DSS v4.0
Requirement 6.2.4 - Protect web-facing applications against injection attacks

References

External resources and documentation

Similar Rules

Explore related security rules for Python

Frequently Asked Questions

Common questions about Shell Command with Wildcard Character

Yes, exploiting wildcard injection requires that an attacker can create files with strategically crafted names in the directory being processed. Directories with proper permissions that prevent attacker file creation are not exploitable via this technique. However, shared directories, upload directories, and world-writable temp directories are common targets.
tar (--checkpoint-action), rsync (-e option), chown (symlink traversal), chmod, find (-exec), and cp are the most commonly exploited commands. These tools accept flag-like arguments that can be injected via malicious filenames and have been used in real-world privilege escalation attacks on Linux systems.
Yes. subprocess.run() with shell=True passes the command to /bin/sh, which performs wildcard expansion. The safe solution is subprocess.run() with shell=False (the default) and an explicit list of file paths obtained via Python's glob module, not a shell wildcard.
Use Python's glob.glob() or pathlib.Path.glob() to expand the pattern in Python code, then pass each resulting path individually to subprocess.run() as a list argument. This performs the same file matching without invoking the shell and without vulnerability to filename-based argument injection.
Windows cmd.exe also performs wildcard expansion, though the specific exploitation techniques differ. On Windows, subprocess.run() with shell=False on Python 3 uses CreateProcess directly without shell expansion, which avoids this risk. Use list arguments and avoid shell=True on all platforms.
Look for all uses of os.system(), subprocess.run(shell=True), subprocess.Popen(shell=True), and os.popen() where the command string contains wildcards or processes directories that users can write to. Also audit cron jobs, backup scripts, and deployment scripts for the same pattern.

New feature

Get these findings posted directly on your GitHub pull requests

The Shell Command with Wildcard Character rule runs in CI and posts inline review comments on the exact lines — no dashboard, no SARIF viewer.

See how it works