T09 · Insecure Skill Coding Practices
- Location
scripts/searxng.py:205- Finding
Server-Side Request Forgery Through Unrestricted Instance and Search Result URLs
- Content
View full analysis
skill-config.json > default if base_url: self.base_url = base_url.rstrip("/") else: cfg_url = cfg.get("default_instance", "").strip() self.base_url = cfg_url.rstrip("/") if cfg_url else self.DEFAULT_INSTANCE ``` ```python def _fetch_full_content(self, url: str, max_chars: int = 4000) -> str: """Fetch a URL and return stripped plain text, up to max_chars.""" if not url: return "" try: self._wait_for_rate_limit() resp = self.session.get(url, timeout=8, allow_redirects=True) resp.raise_for_status() ct = resp.headers.get("Content-Type", "") if "html" not in ct and "text" not in ct: return "" extractor = _TextExtractor() extractor.feed(resp.text) return extractor.get_text(max_chars) except Exception as e: print(f"Warning: could not fetch {url}: {e}", file=sys.stderr) return "" ``` ```python url = f"{self.base_url}/search" response = self.session.get(url, params=params, timeout=10) response.raise_for_status() data = response.json() ``` ```python for r in data.get("results", data.get("items", [])): url = r.get("url", r.get("link", "")) fetched = self._fetch_full_content(url) if full_content else "" ``` ```python parser.add_argument( "--instance", default=None, metavar="URL", help="SearXNG instance URL (overrides config)", ) ``` ### Technical Analysis The client accepts an arbitrary SearXNG instance through `--instance` or `skill-config.json` without validating the URL scheme, hostname, resolved IP address, or destination network. It then sends a request to the supplied destin ...[truncated 2124 chars]- Remediation
View remediation
