Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Classes/EventListener/PageIndexer/FrontendGroupsModifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ public function __invoke(ModifyResolvedFrontendGroupsEvent $event): void
);
}

if ((int)$pageIndexerRequest->getParameter('pageUserGroup') > 0) {
if ((int)$pageIndexerRequest->getParameter('userGroup') > 0
&& (int)$pageIndexerRequest->getParameter('pageUserGroup') > 0
) {
$groups[] = (int)$pageIndexerRequest->getParameter('pageUserGroup');
}
$groupData = [];
Expand Down
15 changes: 15 additions & 0 deletions Classes/IndexQueue/PageIndexer.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,23 @@ public function index(Item $item): bool
);
}

$feGroupColumn = $GLOBALS['TCA']['pages']['ctrl']['enablecolumns']['fe_group'] ?? '';
$pageUserGroup = $feGroupColumn !== '' ? (int)($item->getRecord()[$feGroupColumn] ?? 0) : 0;
foreach ($systemLanguageUids as $systemLanguageUid) {
$contentAccessGroups = $this->getAccessGroupsFromContent($item, $systemLanguageUid);
if ($pageUserGroup > 0) {
// A page with fe_group restriction has no publicly-accessible content variants:
// remove group 0 (which may originate from global template CEs, not page content).
// Ensure the page's own group is in accessGroups so restricted-but-eligible users
// can still find the page in search results.
$contentAccessGroups = array_values(array_filter(
$contentAccessGroups,
static fn(int $group): bool => $group !== 0,
));
if (!in_array($pageUserGroup, $contentAccessGroups, true)) {
$contentAccessGroups[] = $pageUserGroup;
}
}
foreach ($contentAccessGroups as $userGroup) {
$this->indexPage($item, $systemLanguageUid, (int)$userGroup);
}
Expand Down
10 changes: 10 additions & 0 deletions Documentation/Releases/solr-release-13-1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ Releases 13.1

.. include:: HintAboutOutdatedChangelog.rst.txt

Release 13.1.2
==============

This is a bugfix release for TYPO3 13 LTS.

All Changes
-----------

* [BUGFIX] Prevent c:0 variant and content leakage on fe_group-restricted pages by @dkd-kaehm in `#4641 <https://github.com/TYPO3-Solr/ext-solr/pull/4641>`_

Release 13.1.1
==============

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"fe_groups",
,"uid","pid","title"
,1,1,"group 1"
"pages",
,"uid","pid","is_siteroot","doktype","slug","title","subtitle","crdate","tstamp","fe_group"
,2,1,0,1,"/protected_page","protected page","",1449151778,1449151778,1
"tt_content",
,"uid","pid","CType","header","bodytext","fe_group","sorting"
,11,"2","text","protected ce ","protected bodytext ",1,20
,20,"1","text","footer nav ce ","footer nav bodytext ",0,10
"sys_template",
,"uid","pid","root","clear","sorting","config"
,100,1,1,3,50,"
@import 'EXT:solr/Tests/Integration/Fixtures/sites_setup_and_data_set/Integration.setup.typoscript'

# Replicate what addSimpleFrontendRenderingToTypoScriptRendering adds in setUp()
page = PAGE
page.typeNum = 0
config.index_enable = 1
page.10 = CONTENT
page.10 {
table = tt_content
select.orderBy = sorting
select.where = colPos=0
renderObj = COA
renderObj {
10 = TEXT
10.field = bodytext
}
}
page.10.renderObj.5 = TEXT
page.10.renderObj.5.field = header
page.10.stdWrap.dataWrap = <!--TYPO3SEARCH_begin-->|<!--TYPO3SEARCH_end-->

# Simulates global template content (footer/nav) rendered outside TYPO3SEARCH markers.
# In production, such content from other pages causes UserGroupDetector to collect
# their fe_group values (often 0/empty), which triggers the c:0 indexing variant.
page.20 = CONTENT
page.20 {
table = tt_content
select.pidInList = 1
select.orderBy = sorting
select.where = colPos=0
renderObj = COA
renderObj {
10 = TEXT
10.field = bodytext
}
}
"
"tx_solr_indexqueue_item",
,"uid","root","item_type","item_uid","indexing_configuration","changed","indexed","has_indexing_properties","indexing_priority","indexed","errors"
,4711,1,"pages",2,"pages",1449151778,0,0,0,0,0
22 changes: 18 additions & 4 deletions Tests/Integration/IndexQueue/PageIndexerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public function canIndexPageWithAccessProtectedContentIntoSolr(
true,
);

self::assertEquals($expectedNumFound, $solrContent['response']['numFound'] ?? 0, 'Could not index documents into Solr');
self::assertEquals($expectedNumFound, $solrContent['response']['numFound'] ?? 0, 'Unexpected count of documents in Solr index.');
foreach ($expectedAccessFieldValues as $index => $expectedAccessFieldValue) {
self::assertEquals(
$expectedAccessFieldValue,
Expand Down Expand Up @@ -143,7 +143,7 @@ public static function canIndexPageWithAccessProtectedContentIntoSolrDataProvide
'fixture' => 'can_index_access_protected_page',
'expectedNumFound' => 1,
'expectedAccessFieldValues' => [
'2:1/c:0',
'2:1/c:1',
],
'expectedContents' => [
'public content of protected page',
Expand Down Expand Up @@ -171,7 +171,7 @@ public static function canIndexPageWithAccessProtectedContentIntoSolrDataProvide
'fixture' => 'can_index_access_protected_page_with_protected_contents',
'expectedNumFound' => 2,
'expectedAccessFieldValues' => [
'2:1/c:0',
'2:1/c:1',
'2:1/c:2',
],
'expectedContents' => [
Expand All @@ -187,7 +187,7 @@ public static function canIndexPageWithAccessProtectedContentIntoSolrDataProvide
'fixture' => 'can_index_access_protected_page_with_protected_contents',
'expectedNumFound' => 2,
'expectedAccessFieldValues' => [
'2:1/c:0',
'2:1/c:1',
'2:1/c:2',
],
'expectedContents' => [
Expand Down Expand Up @@ -232,6 +232,20 @@ public static function canIndexPageWithAccessProtectedContentIntoSolrDataProvide
'expectedNumFoundLoggedInUser' => 2,
];

yield 'protected page: c:0 must not contain same-group protected content (isolation bug)' => [
'fixture' => 'can_index_protected_page_with_public_and_same_group_protected_content',
'expectedNumFound' => 1,
'expectedAccessFieldValues' => [
'2:1/c:1',
],
'expectedContents' => [
'protected ce protected bodytext',
],
'expectedNumFoundAnonymousUser' => 0,
'userGroupToCheckAccessFilter' => '0,1',
'expectedNumFoundLoggedInUser' => 1,
];

yield 'page protected by extend to subpages' => [
'fixture' => 'can_index_sub_page_of_protected_page_with_extend_to_subpage',
'expectedNumFound' => 1,
Expand Down