Repository navigation
Conversation
Page-supplied @context URLs were loaded with file_get_contents, which bypasses the crawler and the URL policy and follows redirects. Pass an offline document loader that serves a bundled schema.org vocabulary and refuses every other remote document.
Vitorinox
commented
Oct 20, 2026
Vitorinox
left a comment
Collaborator
Author
There was a problem hiding this comment.
@markfullmer Since you reviewed #579, would you mind taking a look at this one? It closes the remaining SSRF path from #573: JSON-LD @context URLs were fetched with file_get_contents, bypassing the crawler and UrlPolicy.
cc @karthi-the-hacker, as the reporter of #573. Thanks!
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.
Summary
JSON-LD expansion loaded a page-supplied
@contextwithfile_get_contents(FileGetContentsLoader). That request never went through the crawler orUrlPolicy, and it followed redirects, so a context URL was an SSRF path left open by #573 / #579. Extraction also depended on the network for ordinary schema.org contexts.LinkedDatanow passes an explicitdocumentLoaderinto eachML\JsonLDcall. The globalJsonLD::setDefaultDocumentLoader()is not changed, so host applications keep their own loader.The loader performs no network or filesystem I/O:
http/httpscontexts onschema.org,www.schema.org, andschema.googleapis.com— with or without a trailing slash,.jsonld, ordocs/jsonldcontext.json— are answered with a bundled{"@context":{"@vocab":"http://schema.org/"}}.JsonLdException.LinkedDataalready catches that, so extraction continues with the rest of the page.Existing fixtures are unchanged, including Tumblr
publishedTimeof2017-09-14 10:20:35. The test-onlyhttp/httpsstream wrapper added in #579 (tests/SchemaOrgContext.php) is removed; the suite passes without it.Tests
@contextpoints athttp://127.0.0.1/...on a localphp -Sserver that records hits makes no request. The same URL is followed (including the redirect) byFileGetContentsLoader.www.schema.org, andschema.googleapis.comcontext URL variants still resolvedatePublished.@contextleave the HTML title intact and do not fatal.PHPUnit passes on PHP 7.4, 8.3, 8.4, and 8.5. PHPStan (level max, strict rules) is clean.