T09 · Insecure Skill Coding Practices
- Location
scripts/extract_paddleocr.py:105- Finding
Unvalidated OCR Result URL Enables Server-Side Request Forgery
- Content
View full analysis
str: headers = {'Authorization': f'bearer {api_key}'} start = time.time() while True: resp = requests.get(f'{job_url}/{job_id}', headers=headers, timeout=60) resp.raise_for_status() data = resp.json().get('data', {}) state = data.get('state') if state == 'done': return (data.get('resultUrl') or {}).get('jsonUrl', '') if state == 'failed': raise RuntimeError(f"OCR任务失败: {data.get('errorMsg', 'unknown')}") if state == 'running': prog = data.get('extractProgress', {}) ui.log(f"[OCR] job={job_id} running pages={prog.get('extractedPages','?')}/{prog.get('totalPages','?')}") if timeout_seconds > 0 and (time.time() - start) >= timeout_seconds: raise TimeoutError(f'OCR超时: {job_id}') time.sleep(max(0.2, poll_seconds)) def fetch_markdown(jsonl_url: str) -> str: resp = requests.get(jsonl_url, timeout=180) resp.raise_for_status() ``` ### Technical Analysis The OCR polling response controls `resultUrl.jsonUrl`. The application passes this value directly to `requests.get()` without validating: - The URL scheme - The destination hostname - The resolved IP address - Redirect destinations - Whether the result host belongs to the configured OCR service Consequently, a compromised, malicious, or incorrectly configured OCR endpoint can cause the application to send an HTTP request to an arbitrary destination reachable from the user's system. This includes loopback interfaces, private network ranges, link-local services, and cloud instance metadata endpoints. The f ...[truncated 1950 chars]- Remediation
View remediation
