fix(audit L1): Schleifen-Rechteprüfung auf dem bereinigten Wert (sanitize_text_field-Umgehung) und mit sanitize_key-Lesart von enable/queryType
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
bd80ab1394
commit
71c2e03c9b
@@ -50,12 +50,14 @@ final class DiviWriterFixture
|
||||
public static function composition(
|
||||
DesignSystemReader $design,
|
||||
bool $unfiltered = false,
|
||||
?DynamicContentMap $registry = null
|
||||
?DynamicContentMap $registry = null,
|
||||
bool $listUsers = true,
|
||||
bool $readPrivate = true
|
||||
): DiviComposition {
|
||||
return new DiviComposition(
|
||||
self::modules(),
|
||||
$design,
|
||||
ComposeFixture::sanitizer($unfiltered),
|
||||
ComposeFixture::sanitizer($unfiltered, $listUsers, $readPrivate),
|
||||
ComposeFixture::media(),
|
||||
$registry ?? new DynamicContentMap()
|
||||
);
|
||||
@@ -106,7 +108,9 @@ final class DiviWriterFixture
|
||||
?GlobalEdits $globals = null,
|
||||
?ThemeBuilderEdits $themeBuilder = null,
|
||||
?SimilarSections $similar = null,
|
||||
?DynamicContentMap $registry = null
|
||||
?DynamicContentMap $registry = null,
|
||||
bool $listUsers = true,
|
||||
bool $readPrivate = true
|
||||
): DiviWriter {
|
||||
$design = self::designReader();
|
||||
|
||||
@@ -115,7 +119,7 @@ final class DiviWriterFixture
|
||||
self::saver($saved, $failures),
|
||||
self::log(),
|
||||
$design,
|
||||
self::composition($design, $unfiltered, $registry),
|
||||
self::composition($design, $unfiltered, $registry, $listUsers, $readPrivate),
|
||||
$globals,
|
||||
$themeBuilder,
|
||||
$similar
|
||||
|
||||
@@ -439,4 +439,45 @@ final class DiviLoopWriteTest extends DiviWriteAbilityTestCase
|
||||
self::assertStringContainsString('kann Daten eines anderen Objekts zeigen', $text);
|
||||
self::assertStringNotContainsString('zeigt sie dort leer', $text);
|
||||
}
|
||||
|
||||
/** @return array<string, array{array<string, mixed>, string}> */
|
||||
public static function disguisedLoops(): array
|
||||
{
|
||||
return [
|
||||
'enable with a space' => [['enable' => ' on', 'queryType' => 'user_roles'], 'list_users'],
|
||||
'enable with a tag' => [['enable' => 'o<x>n', 'queryType' => 'user_roles'], 'list_users'],
|
||||
'queryType with empty tags' => [['enable' => 'on', 'queryType' => 'user<b></b>_roles'], 'list_users'],
|
||||
'any via tag' => [
|
||||
['enable' => 'on', 'queryType' => 'post_types', 'subTypes' => [['value' => 'att<x>achment']]],
|
||||
'read_private_posts',
|
||||
],
|
||||
'empty subTypes' => [['enable' => 'on', 'queryType' => 'post_types', 'subTypes' => []], 'read_private_posts'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Audit L1 (re-review): the check runs on the value the sanitizer leaves – sanitize_text_field turns " on",
|
||||
* "o<x>n" or "user<b></b>_roles" into the values Divi acts on. Through insert and update.
|
||||
*
|
||||
* @dataProvider disguisedLoops
|
||||
* @param array<string, mixed> $loop
|
||||
*/
|
||||
public function testDisguisedLoopsAreRefusedWithoutTheRights(array $loop, string $right): void
|
||||
{
|
||||
$registry = self::registry();
|
||||
$this->writer = DiviWriterFixture::writer(
|
||||
$this->saved,
|
||||
registry: new DynamicContentMap(static fn (int $postId): array => $registry),
|
||||
listUsers: false,
|
||||
readPrivate: false
|
||||
);
|
||||
$attrs = ['module.advanced.loop' => ['desktop' => $loop]];
|
||||
|
||||
$inserted = $this->insertInto('s0.r0.c2', ['nodes' => [['type' => 'text', 'attrs' => $attrs, 'content' => 'x']]]);
|
||||
self::assertStringContainsString($right, self::problems($inserted));
|
||||
|
||||
$updated = $this->changeAll([['id' => 's0.r0.c2', 'attrs' => $attrs]]);
|
||||
self::assertStringContainsString($right, self::problems($updated));
|
||||
self::assertSame([], $this->saved);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user