Skip to content

[DEMO for #4641] Prevent c:0 variant and content leakage on fe_group-restricted pages#4642

Closed
dkd-kaehm wants to merge 1 commit into
TYPO3-Solr:release-13.1.xfrom
dkd-kaehm:ports/4559_Prevent_c_0_leakage_on-fe_group-restricted-pages.demo
Closed

[DEMO for #4641] Prevent c:0 variant and content leakage on fe_group-restricted pages#4642
dkd-kaehm wants to merge 1 commit into
TYPO3-Solr:release-13.1.xfrom
dkd-kaehm:ports/4559_Prevent_c_0_leakage_on-fe_group-restricted-pages.demo

Conversation

@dkd-kaehm

Copy link
Copy Markdown
Collaborator

Don't merge, it is a demo for #4641

The bug will be fixed in #4641.

…tricted pages

#### Add failing test for c:0/content-leakage bug on fe_group-restricted pages

Reproduces two interrelated bugs in the indexing sub-request pipeline
that cause access-protected pages to be indexed with incorrect Solr
documents:

- Bug 1 (PageIndexer::index): group 0 from global-template content
  reaches accessGroups and produces an unwanted c:0 variant, making
  the page findable without the required access group.
- Bug 2 (FrontendGroupsModifier): pageUserGroup is added unconditionally
  to the faked frontend groups, granting access to fe_group-restricted
  content during the c:0 sub-request and leaking protected content
  into the c:0 Solr document.

The fixture mirrors the production scenario: a protected page
(fe_group=1) with a protected CE (fe_group=1) alongside a footer/nav
CE (pid=1, fe_group=0) rendered via a second CONTENT object outside
the TYPO3SEARCH markers — the same shape global template content has
in production.

Files:
- Tests/Integration/IndexQueue/PageIndexerTest.php
  - Added data-provider yield "protected page: c:0 must not contain
    same-group protected content (isolation bug)" expecting only c:1.
- Tests/Integration/IndexQueue/Fixtures/can_index_protected_page_with_public_and_same_group_protected_content.csv
  - New fixture; sys_template inlined to render bodytext and include
    the second CONTENT object outside TYPO3SEARCH markers.

Currently fails as expected (numFound=2 instead of 1) — c:0 is created
in addition to c:1. Source fix follows; backport of 740ad63 from main.

Partially ports: TYPO3-Solr#4559
dkd-kaehm added a commit to dkd-kaehm/ext-solr that referenced this pull request May 8, 2026
…ed pages

#### Apply source fix and correct existing access-field assertions on protected pages

Fixes the two bugs reproduced by the previous commit and corrects three
existing data-provider yields that had been silently encoding the buggy
behaviour as expected.

- Bug 1 fix (PageIndexer::index): when the page has fe_group > 0, filter
  group 0 from accessGroups returned by findUserGroups — group 0 originates
  from global template content rendered during the sub-request, not from
  the page's own content — and ensure the page's own group is present so
  restricted-but-eligible users can still find the page in search results.
- Bug 2 fix (FrontendGroupsModifier): only fake pageUserGroup into the
  frontend groups when userGroup > 0. The c:0 sub-request must run with
  anonymous groups so fe_group-restricted content does not leak into the
  c:0 Solr document.

After the fix, the three previously '2:1/c:0' yields produce '2:1/c:1'
(the page's own group), which is the semantically correct access variant.

Files:
- Classes/IndexQueue/PageIndexer.php
  - In index(): read pageUserGroup from the page record (via
    enablecolumns.fe_group). For protected pages, filter group 0 from
    accessGroups and ensure pageUserGroup is in the list.
- Classes/EventListener/PageIndexer/FrontendGroupsModifier.php
  - Add a userGroup > 0 guard to the pageUserGroup faking block.
- Tests/Integration/IndexQueue/PageIndexerTest.php
  - Updated three data-provider yields ("protected page", "protected page
    with protected content", "translation of protected page with protected
    content"): expectedAccessFieldValues '2:1/c:0' -> '2:1/c:1'.

Verification:
  composer tests:integration -- --filter=PageIndexerTest
  -> 20 tests, 251 assertions, all green.

Partially ports: TYPO3-Solr#4559
Closes: TYPO3-Solr#4642
dkd-kaehm added a commit to dkd-kaehm/ext-solr that referenced this pull request May 8, 2026
…ed pages

Fixes two interrelated bugs in the page indexing flow that cause
access-protected pages to be indexed with incorrect Solr documents:

- Bug 1 (PageIndexer::index): the findUserGroups indexer request
  collects fe_group values from all content rendered for that
  request, including global-template content (footer/nav) which
  typically has fe_group=0. Group 0 then reaches accessGroups and
  triggers an unwanted c:0 variant via indexPage, making the page
  findable without the required access group. Group 0 is now
  filtered out when the page has fe_group > 0, and the page's own
  group is ensured to be present so restricted-but-eligible users
  can still find the page.
- Bug 2 (FrontendGroupsModifier): the event listener faked
  pageUserGroup into the frontend groups unconditionally. During
  the c:0 indexer request this granted access to fe_group-restricted
  content elements, leaking protected bodytext into the c:0 Solr
  document. pageUserGroup is now only faked in when userGroup > 0;
  the c:0 request runs with anonymous groups.

The new fixture mirrors the production scenario: a protected page
(fe_group=1) with a protected CE (fe_group=1) alongside a footer/nav
CE (pid=1, fe_group=0) rendered via a second CONTENT object outside
the TYPO3SEARCH markers — the same shape global template content has
in production. Three existing data-provider yields had been silently
encoding the bug as expected ('2:1/c:0' on a page with fe_group=1)
and are corrected to '2:1/c:1', the semantically correct access
variant.

Files:
- Classes/IndexQueue/PageIndexer.php
  - In index(): read pageUserGroup from the page record (via
    enablecolumns.fe_group). For protected pages, filter group 0
    from accessGroups and ensure pageUserGroup is in the list.
- Classes/EventListener/PageIndexer/FrontendGroupsModifier.php
  - Add a userGroup > 0 guard to the pageUserGroup faking block.
- Tests/Integration/IndexQueue/PageIndexerTest.php
  - Added data-provider yield "protected page: c:0 must not contain
    same-group protected content (isolation bug)" expecting only c:1.
  - Corrected three protected-page yields ("protected page",
    "protected page with protected content", "translation of
    protected page with protected content"):
    expectedAccessFieldValues '2:1/c:0' -> '2:1/c:1'.
- Tests/Integration/IndexQueue/Fixtures/can_index_protected_page_with_public_and_same_group_protected_content.csv
  - New fixture; sys_template inlined to render bodytext and
    include the second CONTENT object outside TYPO3SEARCH markers.

Partially ports: TYPO3-Solr#4559
Closes: TYPO3-Solr#4642
dkd-kaehm added a commit to dkd-kaehm/ext-solr that referenced this pull request May 8, 2026
…ed pages

Fixes two interrelated bugs in the page indexing flow that cause
access-protected pages to be indexed with incorrect Solr documents:

- Bug 1 (PageIndexer::index): the findUserGroups indexer request
  collects fe_group values from all content rendered for that
  request, including global-template content (footer/nav) which
  typically has fe_group=0. Group 0 then reaches accessGroups and
  triggers an unwanted c:0 variant via indexPage, making the page
  findable without the required access group. Group 0 is now
  filtered out when the page has fe_group > 0, and the page's own
  group is ensured to be present so restricted-but-eligible users
  can still find the page.
- Bug 2 (FrontendGroupsModifier): the event listener faked
  pageUserGroup into the frontend groups unconditionally. During
  the c:0 indexer request this granted access to fe_group-restricted
  content elements, leaking protected bodytext into the c:0 Solr
  document. pageUserGroup is now only faked in when userGroup > 0;
  the c:0 request runs with anonymous groups.

The new fixture mirrors the production scenario: a protected page
(fe_group=1) with a protected CE (fe_group=1) alongside a footer/nav
CE (pid=1, fe_group=0) rendered via a second CONTENT object outside
the TYPO3SEARCH markers — the same shape global template content has
in production. Three existing data-provider yields had been silently
encoding the bug as expected ('2:1/c:0' on a page with fe_group=1)
and are corrected to '2:1/c:1', the semantically correct access
variant.

Files:
- Classes/IndexQueue/PageIndexer.php
  - In index(): read pageUserGroup from the page record (via
    enablecolumns.fe_group). For protected pages, filter group 0
    from accessGroups and ensure pageUserGroup is in the list.
- Classes/EventListener/PageIndexer/FrontendGroupsModifier.php
  - Add a userGroup > 0 guard to the pageUserGroup faking block.
- Tests/Integration/IndexQueue/PageIndexerTest.php
  - Added data-provider yield "protected page: c:0 must not contain
    same-group protected content (isolation bug)" expecting only c:1.
  - Corrected three protected-page yields ("protected page",
    "protected page with protected content", "translation of
    protected page with protected content"):
    expectedAccessFieldValues '2:1/c:0' -> '2:1/c:1'.
- Tests/Integration/IndexQueue/Fixtures/can_index_protected_page_with_public_and_same_group_protected_content.csv
  - New fixture; sys_template inlined to render bodytext and
    include the second CONTENT object outside TYPO3SEARCH markers.
- Documentation/Releases/solr-release-13-1.rst
  - Added a Release 13.1.2 section with this fix as the first entry.

Partially ports: TYPO3-Solr#4559
Closes: TYPO3-Solr#4642
dkd-kaehm added a commit to dkd-kaehm/ext-solr that referenced this pull request May 20, 2026
…ed pages

Fixes two interrelated bugs in the page indexing flow that cause
access-protected pages to be indexed with incorrect Solr documents:

- Bug 1 (PageIndexer::index): the findUserGroups indexer request
  collects fe_group values from all content rendered for that
  request, including global-template content (footer/nav) which
  typically has fe_group=0. Group 0 then reaches accessGroups and
  triggers an unwanted c:0 variant via indexPage, making the page
  findable without the required access group. Group 0 is now
  filtered out when the page has fe_group > 0, and the page's own
  group is ensured to be present so restricted-but-eligible users
  can still find the page.
- Bug 2 (FrontendGroupsModifier): the event listener faked
  pageUserGroup into the frontend groups unconditionally. During
  the c:0 indexer request this granted access to fe_group-restricted
  content elements, leaking protected bodytext into the c:0 Solr
  document. pageUserGroup is now only faked in when userGroup > 0;
  the c:0 request runs with anonymous groups.

The new fixture mirrors the production scenario: a protected page
(fe_group=1) with a protected CE (fe_group=1) alongside a footer/nav
CE (pid=1, fe_group=0) rendered via a second CONTENT object outside
the TYPO3SEARCH markers — the same shape global template content has
in production. Three existing data-provider yields had been silently
encoding the bug as expected ('2:1/c:0' on a page with fe_group=1)
and are corrected to '2:1/c:1', the semantically correct access
variant.

Files:
- Classes/IndexQueue/PageIndexer.php
  - In index(): read pageUserGroup from the page record (via
    enablecolumns.fe_group). For protected pages, filter group 0
    from accessGroups and ensure pageUserGroup is in the list.
- Classes/EventListener/PageIndexer/FrontendGroupsModifier.php
  - Add a userGroup > 0 guard to the pageUserGroup faking block.
- Tests/Integration/IndexQueue/PageIndexerTest.php
  - Added data-provider yield "protected page: c:0 must not contain
    same-group protected content (isolation bug)" expecting only c:1.
  - Corrected three protected-page yields ("protected page",
    "protected page with protected content", "translation of
    protected page with protected content"):
    expectedAccessFieldValues '2:1/c:0' -> '2:1/c:1'.
- Tests/Integration/IndexQueue/Fixtures/can_index_protected_page_with_public_and_same_group_protected_content.csv
  - New fixture; sys_template inlined to render bodytext and
    include the second CONTENT object outside TYPO3SEARCH markers.
- Documentation/Releases/solr-release-13-1.rst
  - Added a Release 13.1.2 section with this fix as the first entry.

Partially ports: TYPO3-Solr#4559
Closes: TYPO3-Solr#4642
dkd-kaehm added a commit that referenced this pull request May 20, 2026
…ed pages

Fixes two interrelated bugs in the page indexing flow that cause
access-protected pages to be indexed with incorrect Solr documents:

- Bug 1 (PageIndexer::index): the findUserGroups indexer request
  collects fe_group values from all content rendered for that
  request, including global-template content (footer/nav) which
  typically has fe_group=0. Group 0 then reaches accessGroups and
  triggers an unwanted c:0 variant via indexPage, making the page
  findable without the required access group. Group 0 is now
  filtered out when the page has fe_group > 0, and the page's own
  group is ensured to be present so restricted-but-eligible users
  can still find the page.
- Bug 2 (FrontendGroupsModifier): the event listener faked
  pageUserGroup into the frontend groups unconditionally. During
  the c:0 indexer request this granted access to fe_group-restricted
  content elements, leaking protected bodytext into the c:0 Solr
  document. pageUserGroup is now only faked in when userGroup > 0;
  the c:0 request runs with anonymous groups.

The new fixture mirrors the production scenario: a protected page
(fe_group=1) with a protected CE (fe_group=1) alongside a footer/nav
CE (pid=1, fe_group=0) rendered via a second CONTENT object outside
the TYPO3SEARCH markers — the same shape global template content has
in production. Three existing data-provider yields had been silently
encoding the bug as expected ('2:1/c:0' on a page with fe_group=1)
and are corrected to '2:1/c:1', the semantically correct access
variant.

Files:
- Classes/IndexQueue/PageIndexer.php
  - In index(): read pageUserGroup from the page record (via
    enablecolumns.fe_group). For protected pages, filter group 0
    from accessGroups and ensure pageUserGroup is in the list.
- Classes/EventListener/PageIndexer/FrontendGroupsModifier.php
  - Add a userGroup > 0 guard to the pageUserGroup faking block.
- Tests/Integration/IndexQueue/PageIndexerTest.php
  - Added data-provider yield "protected page: c:0 must not contain
    same-group protected content (isolation bug)" expecting only c:1.
  - Corrected three protected-page yields ("protected page",
    "protected page with protected content", "translation of
    protected page with protected content"):
    expectedAccessFieldValues '2:1/c:0' -> '2:1/c:1'.
- Tests/Integration/IndexQueue/Fixtures/can_index_protected_page_with_public_and_same_group_protected_content.csv
  - New fixture; sys_template inlined to render bodytext and
    include the second CONTENT object outside TYPO3SEARCH markers.
- Documentation/Releases/solr-release-13-1.rst
  - Added a Release 13.1.2 section with this fix as the first entry.

Partially ports: #4559
Closes: #4642
@dkd-kaehm dkd-kaehm closed this May 20, 2026
@dkd-kaehm dkd-kaehm deleted the ports/4559_Prevent_c_0_leakage_on-fe_group-restricted-pages.demo branch May 20, 2026 10:27
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.

1 participant