T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/extract_pdf_vision.sh:85
- Finding
- Arbitrary Python Code Execution Through Unsafe Argument Interpolation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/extract_pdf_vision.sh`, lines 85-113; related unsafe interpolation at lines 129-142 and 193-198 **Vulnerability Type**: Command injection through generated Python source **Risk Level**: High ### Vulnerable Code ```bash python3 -c " import pypdfium2 as pdfium import os # Open PDF pdf = pdfium.PdfDocument('$PDF_PATH') page_count = len(pdf) # Validate page number target_page = $PAGE_NUMBER if target_page == 0: target_page = 0 # First page (0-indexed) else: target_page = target_page - 1 # Convert to 0-indexed if target_page >= page_count or target_page < 0: raise ValueError(f'Invalid page number. PDF has {page_count} pages.') # Render page as image page = pdf[target_page] pil_image = page.render( scale=2, # 2x zoom for better quality rotation=0, ).to_pil() # Save image pil_image.save('$IMAGE_PATH') print(f'PDF page converted to image: $IMAGE_PATH') print(f'Total pages in PDF: {page_count}') " ``` The fallback configuration and response parsers use the same unsafe construction: ```bash BASE_URL=$(python3 -c " import json with open('$CONFIG_FILE', 'r') as f: config = json.load(f) print(config.get('models', {}).get('providers', {}).get('openai', {}).get('baseUrl', '')) ") ``` ```bash RESPONSE_TEXT=$(python3 -c " import json with open('$RESPONSE_PATH', 'r') as f: response = json.load(f) print(response['choices'][0]['message']['content']) ") ``` ### Technical Analysis Values originating from `--pdf-path`, `--page`, `--config`, and `--temp-dir` are interpolated directly into source code passed to `python3 -c`. Shell quoting does not protect the resulting Python program. A value containing quote characters and valid Python syntax can terminate the intended string or expression and append attacker-controlled statements. The vulnerable script does not constrain the page argument to an integer before embedding it as executable syntax. Path arguments are also inse ...[truncated 1463 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Remove dynamically generated Python source from the shell implementation. - Pass all data through positional arguments to a fixed Python program: ```bash python3 helper.py \ --pdf-path "$PDF_PATH" \ --page "$PAGE_NUMBER" \ --image-path "$IMAGE_PATH" ``` - Access arguments through `argparse` or `sys.argv`; never interpolate them into executable source. - Validate `PAGE_NUMBER` with a strict numeric expression before use: ```bash [[ "$PAGE_NUMBER" =~ ^[0-9]+$ ]] || { echo "Invalid page number" >&2 exit 1 } ``` - Perform JSON parsing in the existing Python implementation rather than through generated `python3 -c` commands. - Prefer removing the duplicate shell implementation and retaining only `pdf_vision_enhanced.py`, which uses structured Python arguments and does not construct executable source from the supplied paths. - Add regression tests containing quotes, backslashes, newlines, semicolons, and Python syntax in every path and prompt argument. ]]>
