Harden web_fetch SSRF and tool-renderer XSS guards - #1513
Open
daiv-agent[bot] wants to merge 1 commit into
Open
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.
This change hardens two security boundaries: the
web_fetchmiddleware's SSRF protection now resolves DNS to catch rebinding and non-dotted IP encodings, and the chat tool-body renderer escapes quotes and gates non-http(s) URLs so attacker-controlled URLs cannot become script sinks in the DOM.Key Changes:
_ip_is_blockedindaiv/automation/agent/middlewares/web_fetch.py, which unwraps v4-mapped/v4-compatible IPv6 addresses before checking private/loopback/link-local/reserved/multicast._resolved_addresses_are_blocked, which resolves hostnames viaasyncio.to_thread(socket.getaddrinfo)and blocks if any resolved address is internal — closing the DNS-rebinding gap and catching decimal/hex/octal IPv4 encodings the literal fast path treats as hostnames._fetch_url_textnow checks both the string fast path and the resolver on every request (including redirects), and rejects cross-host redirects to non-http(s) schemes before theLocationheader is embedded in the<redirect_url>tag.daiv/chat/static/chat/js/tool-renderers.js,escapeHtmlnow also escapes double and single quotes, andexternalLinkrenders onlyhttp:/https:URLs as anchors —javascript:/data:URLs become plain escaped text spans.toolBodyHTMLnow routes its output throughwindow.DOMPurify.sanitize(withFORBID_TAGSforstyle/form/input/button/iframe/object/embed) as the final security boundary before it feedsx-html.tests/unit_tests/automation/agent/middlewares/test_web_fetch_ssrf.pycases (DNS-rebind to loopback/link-local/v4-mapped/unique-local, public pass-through, non-http(s) redirect blocking, same-host re-resolution) and newtests/unit_tests/chat/test_tool_renderers_xss.py+tool_renderers_driver.pythat run the realtool-renderers.jsunder node.💡 Instructions for the reviewer: