T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/install_ga4_openclaw.sh:28
- Finding
- Persistent Shell Command Injection Through Unsanitized GA4 Property ID<![CDATA[ ## Vulnerability Details **File Location**: `scripts/install_ga4_openclaw.sh:28-36` **Vulnerability Type**: Unsanitized input interpolation and shell startup-file injection **Risk Level**: High ### Vulnerable Code ```bash python3 - <<PY from pathlib import Path import re rc = Path("$SHELL_RC") text = rc.read_text() if rc.exists() else "" text = re.sub(r'^export GA4_PROPERTY_ID=.*\\n?', '', text, flags=re.M) if text and not text.endswith('\\n'): text += '\\n' text += 'export GA4_PROPERTY_ID="$PROPERTY_ID"\\n' rc.write_text(text) print(f"Updated {rc}") PY ``` ### Technical Analysis The installer directly interpolates the attacker-influenced `PROPERTY_ID` argument into an unquoted heredoc containing Python source. No validation restricts this argument to the numeric format expected for a GA4 property ID. This creates two related injection opportunities: 1. A value containing Python string delimiters and suitable syntax can alter the generated Python program and execute arbitrary Python code during installation. 2. A value containing shell syntax, such as command substitution, can be written literally into `.bashrc` or `.zshrc`. When a later interactive shell parses that startup file, the injected shell expression is executed. For example, a property ID containing a command substitution expression can result in a startup-file entry conceptually equivalent to: ```bash export GA4_PROPERTY_ID="$(attacker-controlled-command)" ``` Because the installer deliberately modifies a persistent shell initialization file, exploitation can survive the original installation process. ### Attack Path 1. An attacker supplies or recommends a crafted value as the GA4 property ID. 2. The user or an Agent invokes the documented installer with that value as its first argument. 3. The installer embeds the value into generated Python source without validation or safe argument passing. 4. The crafted value either executes through Python during installation or causes a ...[truncated 803 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Validate the property ID before any use with a strict numeric allowlist: ```bash if [[ ! "$PROPERTY_ID" =~ ^[0-9]+$ ]]; then echo "Invalid GA4 property ID: expected digits only" >&2 exit 1 fi ``` - Do not interpolate shell variables into Python source. Pass values as command-line arguments or environment variables: ```bash python3 - "$SHELL_RC" "$PROPERTY_ID" <<'PY' import sys from pathlib import Path rc = Path(sys.argv[1]) property_id = sys.argv[2] PY ``` - Avoid modifying `.bashrc` or `.zshrc` when possible. Store the property ID in a dedicated configuration file with restrictive permissions and load it explicitly. - If a shell assignment must be generated, use a robust shell-escaping mechanism rather than manual quoting. - Write startup-file changes atomically and preserve the original file so the operation can be safely rolled back. ]]>
