fix(data): prevent SSRF from untrusted KML/GeoJSON icon and GroundOverlay href - #1758
Open
herdiyana256 wants to merge 1 commit into
Open
fix(data): prevent SSRF from untrusted KML/GeoJSON icon and GroundOverlay href#1758herdiyana256 wants to merge 1 commit into
herdiyana256 wants to merge 1 commit into
Conversation
…rlay href Icon (IconStyle/Icon/href) and GroundOverlay (Icon/href) URLs are read from the parsed KML/GeoJSON document, which is frequently untrusted (downloaded, shared, or user-provided). UrlIconProvider.loadBitmapFromUrl fetched these URLs verbatim (URL(href).openConnection().connect()) with no validation, giving a crafted document an SSRF primitive against loopback, link-local (169.254.169.254 metadata), and private-network hosts reachable from the device. The existing KmlUrlSanitizer interface was never invoked anywhere (dead code) and could not be injected through KmlLayer/GeoJsonLayer, so there was no protection by default. - Add DefaultKmlUrlSanitizer: allows only http/https whose host does not resolve to a loopback/any-local/link-local/site-local/multicast address; blocks otherwise. - UrlIconProvider now applies a KmlUrlSanitizer (secure default) before every fetch and disables auto-redirects to stop redirect-based SSRF bypass. Callers may pass a custom sanitizer, or null to opt out. Public icon URLs are unaffected. - Add hermetic unit tests for the sanitizer.
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.
Summary
Icon and GroundOverlay
<href>URLs are read from the parsed KML/GeoJSON document and fetched without any validation, giving a crafted (untrusted) document a Server-Side Request Forgery (SSRF) primitive.Style/IconStyle/Icon/href→KmlStyle.iconUrlGroundOverlay/Icon/href→KmlGroundOverlay.imageUrlBoth flow to
UrlIconProvider.loadBitmapFromUrl, which did:A malicious KML/GeoJSON (downloaded, shared, or user-provided) can therefore make the app issue requests to loopback, link-local (
169.254.169.254metadata), and private-network hosts reachable from the device.HttpURLConnectionalso follows redirects by default, so a public-looking href can302to an internal target.The
KmlUrlSanitizerinterface exists butsanitizeUrl(...)is never called anywhere in the codebase (dead code), andKmlLayer/GeoJsonLayerhard-codeUrlIconProvider()with no way to inject one — so there was no protection by default and no way for a developer to add one.Reproduction (network sequence is verbatim from
loadBitmapFromUrl)A KML with
<Icon><href>http://127.0.0.1:8474/INTERNAL</href></Icon>(or a169.254.169.254/ RFC1918 host) causes a real request to that host; a redirector href is followed to the internal target. Confirmed against a local listener that logged the inbound requests.Fix
DefaultKmlUrlSanitizer(new): allows onlyhttp/httpswhose host does not resolve to a loopback / any-local / link-local / site-local (RFC 1918) / multicast address; returnsnull(block) otherwise. Public icon/overlay URLs are unaffected.UrlIconProvidernow applies aKmlUrlSanitizer(secure default) before every fetch — blocked URLs issue no request — and setsinstanceFollowRedirects = falseto stop redirect-based bypass. Callers may pass a custom sanitizer, ornullto opt out.This makes the previously-dead
KmlUrlSanitizerfunctional and the default behavior secure, without changing the publicKmlLayer/GeoJsonLayerAPI. Verified on a JVM: internal/metadata/RFC1918/redirector/file://hrefs are blocked with no request issued, while a public host still loads.Scope / notes