T09 · Insecure Skill Coding Practices
- Location
- scripts/db-stats.sh:8
- Finding
- Configuration Values Are Interpolated into Executable Python Source## Vulnerability Details **File Location**: `scripts/db-stats.sh:8-12`, `scripts/list-apps.sh:8-12`, `scripts/list-models.sh:8-12`, `scripts/list-urls.sh:8-12`, `scripts/pending-migrations.sh:8-12`, and `scripts/settings-check.sh:8-12` **Vulnerability Type**: Python code injection through unsafe source generation **Risk Level**: High ### Vulnerable Code The following pattern appears in each affected script: ```bash cat > "$TMPFILE" << PYEOF import os, sys, django os.environ.setdefault('DJANGO_SETTINGS_MODULE', '${SETTINGS}') sys.path.insert(0, '${PROJECT_PATH}') django.setup() ``` The generated temporary file is subsequently executed. For example, `scripts/db-stats.sh` executes it as follows: ```bash cd "$PROJECT_PATH" "$PYTHON" "$TMPFILE" ``` ### Technical Analysis `SETTINGS` and `PROJECT_PATH` are read by `scripts/load-config.sh` from environment variables or the skill's JSON configuration file. The affected scripts place these values directly inside single-quoted Python string literals in an unquoted heredoc. Shell quoting around a variable expansion does not serialize its value as a valid Python string. A value containing a single quote, newline, and Python syntax can terminate the generated string literal and insert additional executable statements. The resulting temporary Python file is then executed using the configured interpreter. This flaw affects commands presented as inspection or read-only operations, including application, model, URL, database, migration, and settings inspection. Consequently, enabling the skill's read-only mode does not mitigate this injection path. ### Attack Path 1. An attacker gains the ability to influence `DJANGO_SETTINGS_MODULE`, `DJANGO_PROJECT_PATH`, or the corresponding values in `~/.openclaw/skills/django-claw/config.json`. 2. The attacker supplies a value crafted to terminate the surrounding Python string literal and append Python statements. 3. A user invokes ...[truncated 878 chars]
- Remediation
- ## Remediation Suggestions - Do not generate Python source containing interpolated configuration values. - Export the settings module and project path as environment variables, then retrieve them from `os.environ` inside a static, quoted Python program. - Alternatively, pass values as separate positional arguments and access them through `sys.argv`. - Quote heredoc delimiters, such as `<<'PYEOF'`, to prevent shell expansion inside the Python body. - Validate the settings module against an allowlist-compatible format, such as a dotted Python module name. - Resolve and validate the project path using canonical path operations before use. - Apply the same fix consistently to all six affected scripts. - Add regression tests using values containing quotes, newlines, backslashes, command syntax, and Python statements to verify that configuration values remain inert data.
