T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/main.py:596
- Finding
- Arbitrary Python Code Execution Through Unsafe Ratio Evaluation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/main.py:596-603` **Vulnerability Type**: Unsafe use of `eval()` on enrichment-result data **Risk Level**: High ### Vulnerable Code ```python if ratio_col: # Convert ratio to numeric if needed if plot_data[ratio_col].dtype == object: plot_data['ratio_numeric'] = plot_data[ratio_col].apply( lambda x: eval(x) if '/' in str(x) else float(x) ) else: plot_data['ratio_numeric'] = plot_data[ratio_col] ``` ### Technical Analysis The visualization code evaluates string values from the `GeneRatio` or `Overlap` result column as Python expressions whenever the value contains `/`. Python's `eval()` does not restrict the expression to arithmetic and exposes Python built-ins by default. A malicious value such as the following would execute an operating-system command before completing the arithmetic expression: ```python __import__("os").system("attacker-command") / 1 ``` The affected result data originates from the enrichment-analysis output. Exploitation therefore requires an attacker to influence that output, such as through a compromised upstream data source, a malicious or compromised dependency, or replacement of the result object in an integrating application. The vulnerable function is reached by the local GO and KEGG analysis paths when Matplotlib is available and results contain a ratio column. ### Attack Path 1. An attacker gains control over, or compromises, the enrichment data returned to `run_go_enrichment_local()` or `run_kegg_enrichment_local()`. 2. The attacker places a Python expression containing `/` in the `GeneRatio` or `Overlap` field. 3. The program passes the resulting DataFrame to `create_visualizations()`. 4. The object-typed ratio column is processed by `eval()`. 5. The expression executes with the privileges and environment of the user running the Skill. ### Impact Assessment Successful exploitation permits arbitrary Python code ...[truncated 384 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Remove `eval()` entirely and parse ratios using strict numeric conversion: ```python def parse_ratio(value): text = str(value).strip() parts = text.split("/") if len(parts) != 2: raise ValueError(f"Invalid ratio: {text}") numerator = float(parts[0]) denominator = float(parts[1]) if not np.isfinite(numerator) or not np.isfinite(denominator): raise ValueError("Ratio components must be finite") if denominator == 0: raise ValueError("Ratio denominator cannot be zero") return numerator / denominator ``` Then use: ```python plot_data["ratio_numeric"] = plot_data[ratio_col].apply(parse_ratio) ``` Additional hardening should include: - Validate that expected result columns contain only numeric values or strictly formatted numeric ratios. - Reject malformed upstream records rather than attempting permissive interpretation. - Add tests containing Python expressions, zero denominators, non-finite values, and malformed ratios. - Run the analysis with minimum filesystem and network privileges as defense in depth. ]]>
