T09 · Insecure Skill Coding Practices
- Location
scripts/ragflow_ping.py:33- Finding
Bearer token can be transmitted over plaintext HTTP or forwarded during redirects
- Content
View full analysis
Vulnerability Details
File Location:
scripts/ragflow_ping.py:33-39, 47-58;scripts/ragflow_smoke.py:34-41, 48-56;scripts/ragflow_status.py:31-38, 45-48;examples/api-examples.sh:19, 34-48
Vulnerability Type: Unprotected transmission of credentials and insufficient destination validation
Risk Level: HighVulnerable Code
scripts/ragflow_ping.py:33-39:python def http_get(url: str, api_key: str | None = None, timeout: int = 10) -> tuple[int, bytes]: headers = {"Accept": "application/json"} if api_key: headers["Authorization"] = f"Bearer {api_key}" req = urllib.request.Request(url, headers=headers, method="GET") try: with urllib.request.urlopen(req, timeout=timeout) as resp: return resp.status, resp.read()scripts/ragflow_ping.py:47-58:python base_url = get_env("RAGFLOW_BASE_URL").rstrip("/") api_key = os.environ.get("RAGFLOW_API_KEY", "").strip() or None st, _ = http_get(f"{base_url}/openapi.json", api_key=None) if st != 200: print(f"LIVENESS_FAIL openapi.json status={st}") return 2 if not api_key: print("OK_LIVE (no api key set)") return 0 st2, body2 = http_get(f"{base_url}/v1/system/status", api_key=api_key)scripts/ragflow_smoke.py:34-41:python def http_get(url: str, api_key: str, timeout: int = 15) -> tuple[int, bytes]: headers = { "Accept": "application/json", "Authorization": f"Bearer {api_key}", } req = urllib.request.Request(url, headers=headers, method="GET") try: with urllib.request.urlopen(req, timeout=timeout) as resp: return resp.status, resp.read()scripts/ragflow_status.py:31-38:python def http_get(url: str, api_key: str, timeout: int = 15) -> tuple[int, bytes]: headers = { "Accept": "application/json", "Authorization": f"Bearer {api_key}", } re ...[truncated 3183 chars]- Remediation
View remediation
Remediation Suggestions
- Parse
RAGFLOW_BASE_URLbefore making requests and permit onlyhttpsby default. - Allow plaintext HTTP only for explicit loopback destinations such as
127.0.0.1,::1, orlocalhost, or behind a clearly named opt-in such asRAGFLOW_ALLOW_INSECURE_HTTP=1. - Reject URLs containing embedded user information, fragments, unexpected schemes, or malformed hostnames.
- Disable redirects for authenticated requests, or implement a redirect handler that permits only same-scheme, same-host, and same-port redirects.
- Never downgrade an authenticated request from HTTPS to HTTP.
- Configure certificate verification with the system trust store or an explicitly supplied private CA. Do not introduce a global TLS-verification bypass.
- Apply the same validation to all Python helpers, shell examples, and documented curl commands.
- Use a narrowly scoped monitoring credential with short lifetime and straightforward revocation.
- Add automated tests covering plaintext remote URLs, cross-origin redirects, HTTPS-to-HTTP redirects, URLs with user information, and loopback exceptions.
- Parse
