T09 · Insecure Skill Coding Practices
- Location
SKILL.md:196- Finding
Shell Command Injection Through Unsafe Quoting of User-Controlled Arguments
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md:196-204
Vulnerability Type: Shell command injection caused by unsafe command construction
Risk Level: HighThe Skill explicitly instructs the agent to place user-provided values inside single quotes when constructing shell commands:
markdown ## Command Formatting IMPORTANT: Always use single quotes around user-provided values when running commands. ```bash python3 ~/.openclaw/skills/intros/scripts/intros.py register --bot-id 'chosen_username' python3 ~/.openclaw/skills/intros/scripts/intros.py connect 'some_user' python3 ~/.openclaw/skills/intros/scripts/intros.py message send 'bob' 'Hello there!' python3 ~/.openclaw/skills/intros/scripts/intros.py profile create --name 'Alice' --interests 'AI, startups'text ### Technical Analysis Single-quote wrapping does not safely escape arbitrary data for a shell command. If a user-controlled profile field, message, search query, or similar argument contains a single quote, it can terminate the quoted argument. The remaining input can then be interpreted by the shell as command syntax. This is particularly relevant to profile fields and message content because `scripts/intros.py` accepts arbitrary text for these arguments. Although bot identifiers are validated by the Python script, that validation only runs after the invoking shell has parsed and executed the command. It therefore cannot prevent shell-level injection. For example, a malicious value shaped like the following can close the quoted argument, execute another command, and comment out the remainder: ```text x'; touch /tmp/pwned; #If inserted into the documented profile command template, it would produce a command structurally equivalent to:
bash python3 ~/.openclaw/skills/intros/scripts/intros.py profile create --name 'x'; touch /tmp/pwned; #' --interests 'AI'Attack Path
- An attacker supplies malicious text th ...[truncated 1409 chars]
- Remediation
View remediation
Remediation Suggestions
-
Do not construct commands by interpolating user-controlled data into shell command strings.
-
Invoke the CLI with an argument array and disable shell interpretation. For example:
python subprocess.run( [ "python3", intros_script, "profile", "create", "--name", user_name, "--interests", user_interests, ], shell=False, check=True, ) -
Update
SKILL.mdto explicitly prohibit use ofshell=True,os.system, and equivalent shell-string execution for these commands. -
If a shell is unavoidable, apply a proven platform-specific escaping routine such as
shlex.quoteindependently to every dynamic argument. Do not rely on manually adding quote characters. -
Retain application-level validation, but treat it only as defense in depth because it cannot protect against injection that occurs before Python starts.
-
Add tests using apostrophes, semicolons, command substitutions, newlines, and shell redirection characters in all free-form fields to confirm they remain literal arguments.
-
