T09 ยท Insecure Skill Coding Practices
- Location
scripts/network_monitor.sh:83- Finding
Arbitrary Python Code Execution Through Unsanitized DNS Input
- Content
View full analysis
Vulnerability Details
File Location:
scripts/network_monitor.sh, lines 83โ91
Vulnerability Type: Python code injection caused by unsafe source-code construction
Risk Level: HighVulnerable Code
bash dns) domain="${1:-}"; [ -z "$domain" ] && { echo "Usage: dns <domain>"; exit 1; } python3 -c " import socket domain = '$domain' print('DNS: {}'.format(domain)) for info in socket.getaddrinfo(domain, None): fam = 'IPv4' if info[0] == socket.AF_INET else 'IPv6' print(' {} {}'.format(fam, info[4][0])) ";;Technical Analysis
The user-controlled
domainargument is interpolated directly into source code passed topython3 -c. Although the shell variable is visually placed between single quotation marks, those quotation marks belong to the generated Python program and do not safely quote the value during source-code construction.An attacker can supply a value containing a single quote and Python syntax. This can terminate the intended Python string and insert additional statements. When the generated program remains syntactically valid, Python executes those statements with the privileges and environment of the skill process.
Quoting
"$domain"at the shell layer would not resolve this vulnerability because the unsafe operation is interpolation into Python source, not shell word splitting.Attack Path
- The attacker invokes the
dnscommand with a crafted domain argument containing Python syntax. - The shell assigns the argument to
domain. - Variable expansion inserts the untrusted value into the program supplied to
python3 -c. - The crafted value closes the intended Python string and injects additional Python statements.
- Python parses and executes the injected statements under the identity of the user running the skill.
- Injected Python can access files, invoke subprocesses, alter user-writable data, or communicate over the network subject t ...[truncated 639 chars]
- The attacker invokes the
- Remediation
View remediation
Remediation Suggestions
Do not interpolate untrusted data into dynamically generated Python source. Pass the domain as a positional argument and retrieve it through
sys.argv:bash dns) domain="${1:-}" [ -z "$domain" ] && { echo "Usage: dns <domain>"; exit 1; } python3 - "$domain" <<'PYEOF' import socket import sys domain = sys.argv[1] print("DNS: {}".format(domain)) for info in socket.getaddrinfo(domain, None): family = "IPv4" if info[0] == socket.AF_INET else "IPv6" print(" {} {}".format(family, info[4][0])) PYEOF ;;Additional hardening measures:
- Validate the input against the hostname formats the command intends to support, including explicit length limits.
- Reject control characters and unexpected whitespace before resolution.
- Keep the Python program in a quoted heredoc so shell expansion cannot alter its source.
- Run the skill with least privilege and without unnecessary access to secrets or sensitive files.
- Add regression tests using arguments containing quotes, semicolons, newlines, command-substitution syntax, and Python expressions to verify that every value is handled only as data.
