T09 · Insecure Skill Coding Practices
- Location
code/app/services/bilibili_subtitle.py:113- Finding
Bilibili authentication cookies may be disclosed to an unvalidated subtitle host
- Content
View full analysis
Vulnerability Details
File Location:
code/app/services/bilibili_subtitle.py:113-123,code/app/services/bilibili_subtitle.py:512-523,code/app/services/bilibili_subtitle.py:576-581, andcode/app/services/bilibili_subtitle.py:604-608
Vulnerability Type: Cross-origin credential disclosure through an unvalidated remote URL
Risk Level: HighVulnerable Code
python for track in track_list: url = track.get("subtitle_url") if not url: continue subtitle_url = self._normalize_subtitle_url(url) try: response = self._request_with_retry(client, subtitle_url) payload = response.json() except Exception: continueThe same HTTP client is initialized with a default cookie header:
python def _client_headers(self, cookie_header: Optional[str]) -> dict[str, str]: headers = { "User-Agent": ( "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " "(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" ), "Referer": "https://www.bilibili.com/", "Accept": "application/json", } if cookie_header: headers["Cookie"] = cookie_header return headersRequests are made without destination validation:
python def _request_with_retry( self, client: httpx.Client, url: str, params: Optional[dict[str, Any]] = None, ) -> httpx.Response: last_error: Optional[Exception] = None for attempt in range(1, self.max_retries + 1): try: self._throttle() response = client.get(url, params=params) if response.status_code in {412, 429, 500, 502, 503, 504}: raise RuntimeError(f"HTTP {response.status_code}") response.raise_for_status() return response except Exception as exc: last_error = exc if at ...[truncated 2546 chars]- Remediation
View remediation
Remediation Suggestions
- Use separate HTTP clients for authenticated Bilibili API requests and subtitle downloads.
- Never configure the Bilibili cookie as a default header on the subtitle-download client.
- Attach cookies per request only after confirming that the destination is an explicitly approved Bilibili host.
- Parse every subtitle URL and require:
- The
httpsscheme. - An exact hostname or approved suffix from a narrowly defined allowlist.
- No embedded username or password.
- An approved port, normally 443.
- The
- Reject IP-literal destinations and hosts that resolve to loopback, link-local, private, reserved, or multicast addresses.
- If redirects are permitted, validate every redirect target before following it and strip authentication headers on any origin change.
- Add tests proving that a subtitle URL on an unapproved host never receives a
Cookieheader. - Consider initially requesting subtitles without authentication and adding narrowly scoped authentication only where the approved Bilibili endpoint requires it.
