Conversation
download_with_limit (gui.py) and translate() (high_level.py) fetched caller-supplied URLs server-side with no scheme or address validation, so a user could make the server request loopback, private-range, or link-local (cloud metadata) addresses and other internal services; the core path also followed redirects. When the target returned a PDF its content was returned to the caller. Add assert_public_http_url (require http/https and a globally-routable resolved address) and fetch_public_url (redirects re-validated per hop) in high_level.py, and apply both to the two URL-fetch sinks.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1188.
Problem
download_with_limit(pdf2zh/gui.py) andtranslate()(pdf2zh/high_level.py) fetch caller-supplied URLs server-side with no scheme/address validation, so a user can make the server request loopback, private-range, or link-local (cloud metadata) addresses and other internal services.high_levelalso follows redirects, so a public URL can bounce to an internal one. PDF responses are translated and returned to the caller.Change
assert_public_http_url(url)inhigh_level.py: require anhttp/httpsscheme and that every address the host resolves to is globally routable (rejects loopback, private, link-local, reserved, and IPv4-mapped forms).fetch_public_url(url, **kwargs): disables automatic redirects and re-validates each hop before following it.high_level.translatenow usesfetch_public_url;gui.download_with_limitcallsassert_public_http_urland follows redirects with the same re-validating loop.Python's
ipaddressalready treats NAT64/6to4 transition forms as non-global, so no extra unwrapping is needed. Legitimate public PDF links (including ones that redirect) keep working.