Skip to content

Security fixes#3749

Merged
bobvandevijver merged 9 commits into
6.1from
security-fixes
Jul 4, 2026
Merged

Security fixes#3749
bobvandevijver merged 9 commits into
6.1from
security-fixes

Conversation

@bobvandevijver

Copy link
Copy Markdown
Member

No description provided.

Vondry and others added 5 commits July 4, 2026 15:51
The Relation API resource is readable with `api:get` (PUBLIC_ACCESS) and
embeds both `fromContent` and `toContent`, but ContentExtension only
filtered the Content and Field resources. Anonymous users could
therefore enumerate relations involving unpublished, draft or viewless
content, leaking its existence, IDs and the relationship graph.

Apply the same published/non-viewless filter to Relation queries,
requiring both ends of the relation to be publicly visible. Add tests
asserting the collection and item queries constrain both ends; they fail
if the filter is removed.
Bind content-type slugs as query parameters instead of interpolating
them into raw SQL strings. The split() helper now returns an array of
slugs bound via ArrayParameterType::STRING rather than a pre-quoted SQL
fragment.

Add regression tests proving the slugs are passed as bound parameters
and never reach the SQL string.
The /embed endpoint fetched any user-supplied URL server-side via the
embed library after only a CSRF check, with the same SSRF exposure as
the upload-from-URL endpoint. Guard it with UrlSafetyChecker before the
fetch.

Add controller tests for both /embed and /upload-url asserting that
internal/private/metadata hosts and disallowed schemes are rejected with
a 400. These tests fail if the UrlSafetyChecker guard is removed.
The /upload-url endpoint fetched any user-supplied URL server-side via
Filesystem::copy() after only a format/scheme check, allowing requests
to internal services and cloud metadata endpoints (e.g. 169.254.169.254).

Add UrlSafetyChecker, which rejects non-http(s) schemes and any URL whose
host resolves to a private, reserved, loopback or link-local address
(including IPv4-mapped IPv6), and call it before fetching the URL.

Add unit tests covering allowed public URLs and blocked schemes, private
ranges, loopback, link-local/metadata and malformed input.
Copilot AI review requested due to automatic review settings July 4, 2026 14:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces several security hardening changes across URL-fetching endpoints, SQL query construction, API filtering, and authentication redirects, with accompanying PHPUnit coverage.

Changes:

  • Add SSRF protection via a new UrlSafetyChecker and enforce it in async upload-from-URL and embed endpoints.
  • Prevent SQL injection in ListFormatHelper by switching to bound parameters (including array parameters for IN (...)).
  • Tighten public Relation API exposure by filtering out relations where either end is unpublished/viewless; and mitigate open redirect on login failure redirects.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/php/Utils/UrlSafetyCheckerTest.php Adds unit tests for allowed/blocked URLs and malformed inputs.
tests/php/Utils/ListFormatHelperTest.php Verifies content type slugs are bound as parameters (no interpolation).
tests/php/Controller/Backend/Async/UploadControllerTest.php Ensures unsafe URLs are rejected before any fetch in upload-from-URL.
tests/php/Controller/Backend/Async/EmbedControllerTest.php Ensures unsafe URLs are rejected before any server-side embed fetch.
tests/php/Api/ContentExtensionTest.php Asserts Relation queries constrain both ends to published content.
src/Utils/UrlSafetyChecker.php Introduces SSRF guard validating scheme + resolved IP public-ness.
src/Utils/ListFormatHelper.php Switches to parameterized SQL (including array params for IN).
src/Security/LoginFormAuthenticator.php Replaces referer-based redirect on failure; uses HttpUtils for success redirect creation.
src/Controller/Backend/Async/UploadController.php Enforces SSRF guard prior to copying remote content.
src/Controller/Backend/Async/EmbedController.php Enforces SSRF guard prior to fetching embed metadata.
src/Api/Extensions/ContentExtension.php Filters Relation API results to avoid leaking unpublished/viewless endpoints.
phpstan-baseline.php Updates baseline ignores.
composer.json Adds an api-platform/core conflict bound and pins ECS dev dependency version.
CHANGELOG.md Documents the security fixes in the 6.1.4 release notes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/Utils/UrlSafetyChecker.php Outdated
mb_trim is not yet available in PHP 8.2

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@bobvandevijver bobvandevijver merged commit c5a2c2f into 6.1 Jul 4, 2026
33 of 35 checks passed
@bobvandevijver bobvandevijver deleted the security-fixes branch July 4, 2026 14:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants