T09 · Insecure Skill Coding Practices
Warning
- Location
- searxng_search.py:55
- Finding
- Search Queries Can Be Transmitted over Plaintext HTTP<![CDATA[ ## Vulnerability Details **File Location**: `searxng_search.py:55-68` **Related Documentation**: `SKILL.md:32-35` **Vulnerability Type**: Plaintext transmission of potentially sensitive search queries **Risk Level**: Medium ### Vulnerable Code ```python params = {"q": query, "format": "json"} if lang: params["language"] = lang url = f"{base_url}/search?{urllib.parse.urlencode(params)}" req = urllib.request.Request(url, headers={ "Accept": "application/json", "User-Agent": "Moltbot-SearXNG/1.0" }) try: with urllib.request.urlopen(req, timeout=30) as resp: data = json.loads(resp.read().decode()) ``` The documented configuration explicitly uses an unencrypted HTTP endpoint: ```bash export SEARXNG_URL="http://your-searxng-host:8888" ``` The associated URL-processing code in `searxng_search.py:25-33` does not require HTTPS: ```python def get_base_url() -> str: """Get and validate SEARXNG_URL from environment.""" url = os.environ.get("SEARXNG_URL", "").strip() if not url: return "" # Normalize: remove trailing slash, ensure no /search suffix for base url = url.rstrip("/") if url.endswith("/search"): url = url[:-7] return url ``` ### Technical Analysis The Skill must transmit a user-provided query to a SearXNG instance to perform its declared web-search function. That network access is functionally necessary and does not, by itself, exceed minimum privilege. However, the implementation accepts arbitrary URL schemes, and the documentation recommends an `http://` configuration. The search query is included in the request URL through the `q` query-string parameter. When HTTP is used, neither the query nor the returned search results receive transport confidentiality or integrity protection. A network observer, compromised proxy, or other on-path attacker could inspect sensitive search terms or modify the response in transit. URL-based que ...[truncated 1493 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Require `https://` for all non-loopback SearXNG endpoints and reject unsupported or plaintext schemes before issuing a request. 2. Permit HTTP only through an explicit development override and only for loopback addresses such as `127.0.0.1`, `::1`, or `localhost`. 3. Replace the HTTP setup example in `SKILL.md` with an HTTPS endpoint. 4. Document that search queries are transmitted to and may be logged by the configured SearXNG service. 5. Continue using the default Python TLS certificate verification behavior; do not introduce unverified SSL contexts. 6. Avoid placing credentials in `SEARXNG_URL`, because connection-error output can disclose the configured base URL. 7. Consider a validation pattern similar to: ```python from urllib.parse import urlparse def get_base_url() -> str: url = os.environ.get("SEARXNG_URL", "").strip().rstrip("/") if not url: return "" parsed = urlparse(url) loopback_hosts = {"localhost", "127.0.0.1", "::1"} if parsed.scheme != "https": if parsed.scheme != "http" or parsed.hostname not in loopback_hosts: raise ValueError( "SEARXNG_URL must use HTTPS; HTTP is allowed only for loopback endpoints" ) if url.endswith("/search"): url = url[:-7] return url ``` ]]>
