Merge pull request #221 from copenhagentruckwash/fix-system-search-associations-vulnerability
Prevent association expansion from bypassing own-only access
This commit is contained in:
@@ -207,25 +207,28 @@ class system_search_service
|
|||||||
$activeTypes,
|
$activeTypes,
|
||||||
$this->associationEntityTypes()
|
$this->associationEntityTypes()
|
||||||
));
|
));
|
||||||
foreach ($customerNumbers as $customerNumber) {
|
$associationTypes = array_values(array_diff($associationTypes, $ownOnlyTypes));
|
||||||
$associated = $this->executeLexicalSearch(
|
if (!empty($associationTypes)) {
|
||||||
$associationTypes,
|
foreach ($customerNumbers as $customerNumber) {
|
||||||
[(string)$customerNumber],
|
$associated = $this->executeLexicalSearch(
|
||||||
[],
|
$associationTypes,
|
||||||
$ownOnlyTypes,
|
[(string)$customerNumber],
|
||||||
$ownCustomerNumber,
|
[],
|
||||||
$permissionsCatalogAll,
|
$ownOnlyTypes,
|
||||||
$permissionsCatalogOwn,
|
$ownCustomerNumber,
|
||||||
$moduleConfigVisibility,
|
$permissionsCatalogAll,
|
||||||
[$customerNumber]
|
$permissionsCatalogOwn,
|
||||||
);
|
$moduleConfigVisibility,
|
||||||
foreach ($associated as &$item) {
|
[$customerNumber]
|
||||||
if (!isset($item['association_reason'])) {
|
);
|
||||||
$item['association_reason'] = 'customer:' . $customerNumber;
|
foreach ($associated as &$item) {
|
||||||
|
if (!isset($item['association_reason'])) {
|
||||||
|
$item['association_reason'] = 'customer:' . $customerNumber;
|
||||||
|
}
|
||||||
|
$item['score'] = max((int)$item['score'], 35);
|
||||||
}
|
}
|
||||||
$item['score'] = max((int)$item['score'], 35);
|
$initialResults = $this->mergeResults($initialResults, $associated);
|
||||||
}
|
}
|
||||||
$initialResults = $this->mergeResults($initialResults, $associated);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -385,6 +385,30 @@ it('caps AI-driven expanded terms to prevent query amplification', function ():
|
|||||||
expect($maxLen)->toBeLessThanOrEqual(64);
|
expect($maxLen)->toBeLessThanOrEqual(64);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not expand associations for own-only entity types', function (): void {
|
||||||
|
$parser = new FakeSystemSearchIntentParser();
|
||||||
|
$service = new TestableSystemSearchService($parser, [
|
||||||
|
[[
|
||||||
|
'entity_type' => 'customers',
|
||||||
|
'entity_id' => '10',
|
||||||
|
'title' => 'Acme',
|
||||||
|
'customer_number' => 1234,
|
||||||
|
'score' => 80,
|
||||||
|
]],
|
||||||
|
[],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$service->search([
|
||||||
|
'query' => 'acme',
|
||||||
|
'allowed_types' => ['customers', 'orders'],
|
||||||
|
'own_only_types' => ['orders'],
|
||||||
|
'own_customer_number' => 4444,
|
||||||
|
'include_associations' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(count($service->lexicalCalls))->toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
it('expands danish discount wording into lexical discount synonyms', function (): void {
|
it('expands danish discount wording into lexical discount synonyms', function (): void {
|
||||||
$parser = new FakeSystemSearchIntentParser();
|
$parser = new FakeSystemSearchIntentParser();
|
||||||
$service = new TestableSystemSearchService($parser, [[
|
$service = new TestableSystemSearchService($parser, [[
|
||||||
|
|||||||
Reference in New Issue
Block a user