T05 · Unauthorized Access and Privilege Escalation
- Location
gh_extract.py:63- Finding
Arbitrary URL Fetching Enables Server-Side Request Forgery
- Content
View full analysis
str: # given a github url, return the raw url f = furl(url) host = "github.com" if f.host.lower() != host: logger.warning(f"Host is not {host}: {url}") return "" ``` ```python def save_github_url_to_file(url: str) -> Path: raw_url = get_github_raw_url(url) or url return save_url_to_file(raw_url) def extract_text_from_github_url(url: str) -> Path: raw_url = get_github_raw_url(url) or url return get_text_from_url(raw_url) ``` ```python def main(): args = cli() logger.remove() logger.add(sys.stderr, level=args.verbose and "DEBUG" or "INFO") if args.save: raw_url = get_github_raw_url(args.url) or args.url print(save_url_to_file(raw_url)) else: print(extract_text_from_github_url(args.url)) ``` ### Technical Analysis The Skill is documented as accepting GitHub URLs, and `get_github_raw_url()` appears to enforce that the input hostname is exactly `github.com`. However, invalid input causes the function to return an empty string. Every network-access path then uses the expression: ```python get_github_raw_url(url) or url ``` This restores the original, rejected, user-controlled URL. As a result, the hostname check does not establish an effective security boundary. In normal extraction mode, the arbitrary URL is supplied to `requests.get()`. In save mode, it is supplied to the external `wget` program. Redirect destinations are not restricted or revalidated. A public destination could therefore also redirect the request to an internal or otherwise prohibited address. This behavior exceeds the least privileges required to extract public GitHub content. The imp ...[truncated 1561 chars]- Remediation
View remediation
