T09 · Insecure Skill Coding Practices
- Location
scripts/pipeline.py:146- Finding
Untrusted RSS URLs Can Trigger Server-Side Requests Through Screenshot Capture
- Content
View full analysis
Vulnerability Details
File Location:
scripts/pipeline.py, lines 146–161 and 258–271
Vulnerability Type: Server-Side Request Forgery (SSRF) through unvalidated browser navigation
Risk Level: MediumVulnerable Code
python link = "" if link_el is not None: link = link_el.attrib.get("href", "") or (link_el.text or "").strip() pub_date = date_el.text.strip() if date_el is not None and date_el.text else "" desc = desc_el.text.strip() if desc_el is not None and desc_el.text else "" if not title or not link: continue # Check if launch-related text_blob = f"{title} {desc}".lower() if not any(kw in text_blob for kw in keywords): continue iid = item_id(title, link) if iid in existing_ids: continue launches.append({ "id": iid, "title": title, "url": link,The stored URL subsequently reaches the browser screenshot command:
python url = item.get("url", "") if not url: continue print(f" Capturing: {item['title'][:60]}") try: # Use OpenClaw browser tool if available result = subprocess.run( ["openclaw", "browser", "screenshot", "--url", url, "--out", str(out_file)], capture_output=True, text=True, timeout=45, ) if result.returncode != 0: print(f" ⚠ Screenshot failed: {result.stderr[:100]}") except Exception as e: print(f" ⚠ Screenshot error: {e}")Technical Analysis
RSS entry links are externally controlled. The pipeline stores these links without validating their URL scheme, destination host, resolved IP address, port, or redirect chain. During the screenshot stage, each stored URL is passed directly to the OpenClaw browser.
Although the argument-list form of
subprocess.runprevents shell command injection, it does not constrain browser navigation. A malicious or compromised RSS feed can provide a URL targeting a loopback address, private network, link-local service, cloud metadata endpoint, or another resource accessible from the browser's ...[truncated 1846 chars]- Remediation
View remediation
Remediation Suggestions
- Accept only explicitly permitted URL schemes, preferably
https. - Reject URLs containing embedded credentials, malformed hosts, or unexpected ports.
- Resolve destination hostnames before navigation and reject loopback, private, link-local, multicast, reserved, unspecified, and cloud metadata address ranges for both IPv4 and IPv6.
- Revalidate the destination after DNS resolution immediately before use to reduce DNS-rebinding risk.
- Validate every redirect target rather than validating only the initial URL.
- Consider an allowlist of expected product or publisher domains where operationally feasible.
- Run screenshot capture in an isolated browser profile without user credentials, cookies, local-file access, or access to the host and private networks.
- Apply outbound network controls at the container, sandbox, or firewall layer so application-level validation is not the sole defense.
- Record rejected destinations without logging credentials, sensitive query parameters, or other secrets.
- Add tests covering loopback, RFC1918, link-local, IPv6-local, alternate IP notation, DNS rebinding, and public-to-private redirects.
- Accept only explicitly permitted URL schemes, preferably
