scripts: harden github_blob_to_raw against substring URL spoofing
CodeQL flagged scripts/notebook_to_python.py:33's
`if "github.com" in url and "/blob/" in url` as
py/incomplete-url-substring-sanitization: "github.com" can sit
anywhere in the URL, so an attacker-controlled URL like
https://attacker.example.com/github.com/blob/x would be rewritten
to a raw.githubusercontent.com URL and fetched as if it were a
real GitHub blob.
Switch to urllib.parse.urlparse and require parsed.netloc ==
"github.com" exactly, then rewrite via a proper urlunparse on the
parsed components (path is replaced with first /blob/ -> / only).
Query strings and fragments now round-trip correctly too, which
was an incidental bug in the old string-replace path.
Closes the high-severity CodeQL alert on PR head 08235625.
This commit is contained in:
parent
e25e3c5697
commit
fa3840cf6d
1 changed files with 13 additions and 5 deletions
|
|
@ -29,11 +29,19 @@ def needs_fstring(cmd: str) -> bool:
|
|||
|
||||
def github_blob_to_raw(url: str) -> str:
|
||||
"""Convert GitHub blob URL to raw URL."""
|
||||
# https://github.com/user/repo/blob/branch/path -> https://raw.githubusercontent.com/user/repo/branch/path
|
||||
if "github.com" in url and "/blob/" in url:
|
||||
url = url.replace("github.com", "raw.githubusercontent.com")
|
||||
url = url.replace("/blob/", "/")
|
||||
return url
|
||||
# https://github.com/user/repo/blob/branch/path
|
||||
# -> https://raw.githubusercontent.com/user/repo/branch/path
|
||||
# Compare the parsed host exactly (not as a substring) so a URL
|
||||
# like https://attacker.example.com/github.com/blob/... does NOT
|
||||
# get rewritten to a github raw URL. Closes CodeQL alert
|
||||
# py/incomplete-url-substring-sanitization.
|
||||
parsed = urllib.parse.urlparse(url)
|
||||
if parsed.netloc != "github.com" or "/blob/" not in parsed.path:
|
||||
return url
|
||||
new_path = parsed.path.replace("/blob/", "/", 1)
|
||||
return urllib.parse.urlunparse(
|
||||
parsed._replace(netloc = "raw.githubusercontent.com", path = new_path)
|
||||
)
|
||||
|
||||
|
||||
def download_notebook(url: str) -> tuple[str, str]:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue