T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/fetch.py:35
- Finding
- Arbitrary Python Code Execution Through Unsafe URL Interpolation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/fetch.py:35-96` **Vulnerability Type**: Python source injection through untrusted input **Risk Level**: High ### Vulnerable Code ```python code = f""" from scrapling.fetchers import StealthyFetcher import json url = "{url}" page = StealthyFetcher.fetch(url, headless=True, network_idle=True) ``` The dynamically generated source is subsequently executed: ```python result = subprocess.run( [VENV_PYTHON, "-c", code], capture_output=True, text=True, timeout=120 ) ``` ### Technical Analysis The positional URL argument is embedded directly into a dynamically constructed Python program without escaping or serialization. The generated program is then passed to a Python interpreter using the `-c` option. Although `subprocess.run` is invoked without `shell=True`, that does not prevent this vulnerability. The attacker is injecting Python syntax into source code interpreted by the child Python process, rather than injecting shell metacharacters into a command line. A URL containing a quotation mark and additional Python syntax can terminate the intended string assignment and introduce attacker-controlled statements. There is no URL validation, quoting through `repr`, or safe argument-passing boundary. ### Attack Path 1. An attacker supplies a crafted value as the required `url` argument. 2. The value closes the generated `url = "..."` string. 3. The attacker adds valid Python statements to the generated source. 4. `fetch_with_scrapling` invokes the configured interpreter with `python -c`. 5. The injected statements execute with the privileges and environment of the Skill process. 6. The attacker can then invoke operating-system commands, access local files, or read credentials available to that process. This path is reached directly for URLs classified as WeChat or anti-bot sites and as a fallback when Jina fetching fails. ### Impact Assessment Successful exploitation provides arbi ...[truncated 538 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Do not generate Python source code from the supplied URL. - Import Scrapling and invoke `StealthyFetcher.fetch` directly in the current process. - If process isolation is required, place fixed implementation code in a separate reviewed script and pass the URL through a normal argument array or serialized standard input. - Validate the URL with `urllib.parse`, allow only explicitly supported schemes such as HTTPS, and reject control characters. - Run browser-based fetching in a restricted process with minimal filesystem access, no unnecessary secrets, and constrained network permissions. - Add regression tests using URLs containing quotes, backslashes, newlines, and Unicode control characters. ]]>
