T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/test-cli-commands.sh:239
- Finding
- Environment-Controlled Python Code Injection in SDK Tests<![CDATA[ ## Vulnerability Details **File Location**: `scripts/test-cli-commands.sh`, lines 239–245, 266–272, 296–302, 307–313, 317–324, and 329–335 **Vulnerability Type**: Python code injection through unsafe interpolation of environment-controlled values **Risk Level**: High ### Vulnerable Code ```bash python3 -c " from cloudrobo_workspace.client import WorkspaceClient from cloudrobo_core.sdk import Config, HttpClient client = WorkspaceClient(HttpClient(Config())) result = client.show_workspace('$workspace_id') print(str(result)[:500]) " ``` The same vulnerable construction is used by other SDK tests: ```bash result = client.list_workspace_members('$workspace_id') result = client.update_workspace('$workspace_id', {'name': 'sdk-updated'}) result = client.delete_workspace('$workspace_id') result = client.add_workspace_members('$workspace_id', {'member_list': [{'user_id': '${USER_ID}', 'role_ids': ['${ROLE_ID}']}]}) result = client.delete_workspace_members('$workspace_id', ['${USER_ID}']) ``` ### Technical Analysis Values originating from `WORKSPACE_ID`, `USER_ID`, and `ROLE_ID` are inserted directly into Python source code passed to `python3 -c`. Shell quoting does not encode these values as safe Python string literals. An input containing a single quote can terminate the intended Python literal and append arbitrary Python statements. For example, a crafted `WORKSPACE_ID` resembling the following can alter the generated program: ```text '); __import__("os").system("attacker-controlled-command"); # ``` No local validation is performed before the environment values reach the Python interpreter. Although the service may validate UUIDs remotely, that validation occurs only after the generated Python source has already been parsed and executed. The read-only SDK cases TC-20 and TC-22 are especially significant because they run automatically when SDK mode is selected and `WORKSPACE_ID` is present. They do not require the mutation confirmation mechanism. ### ...[truncated 1385 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Do not generate Python source code containing interpolated environment values. Pass all dynamic values as command-line arguments, standard input, or environment data, and treat them exclusively as data. A safe pattern is: ```bash python3 - "$workspace_id" <<'PY' import sys from cloudrobo_workspace.client import WorkspaceClient from cloudrobo_core.sdk import Config, HttpClient workspace_id = sys.argv[1] client = WorkspaceClient(HttpClient(Config())) result = client.show_workspace(workspace_id) print(str(result)[:500]) PY ``` Apply the same design to every SDK function using `WORKSPACE_ID`, `USER_ID`, or `ROLE_ID`. Additional hardening should include: 1. Validate `WORKSPACE_ID` and `ROLE_ID` against a strict UUID parser before invocation. 2. Validate `USER_ID` against the documented lowercase 32-character identifier format. 3. Reject values containing unexpected characters rather than relying only on server-side validation. 4. Add regression tests containing quotes, newlines, backslashes, semicolons, and Python syntax. 5. Avoid `eval`, generated source, or dynamically assembled interpreter commands for all test inputs. ]]>
