fix: Task 1 review round 3 - re-check $variable marker after sanitizing, meta-key rule
Critical-1/S28: sanitizers that strip <x>, NUL or %XX could rebuild the $variable( marker after the raw check; every cleaned string (AttrWriter at every depth, VariableRef settings) is checked again. S29: custom_meta_ map names and *meta_key setting values obey META_KEY. Minor-2: malformed dynamic content maps fail with InvalidArgumentException. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -172,6 +172,26 @@ final class AttrWriterTest extends TestCase
|
||||
['desktop' => ['image' => ['url' => 'https://a.test/$variable({"type":"content","value":{"name":"post_title","settings":{}}})$']]],
|
||||
self::TEXT,
|
||||
];
|
||||
// S28: markers a real sanitizer rebuilds after the raw check (verified in DDEV).
|
||||
$reference = '({"type":"content","value":{"name":"post_title","settings":{"before":"<script>alert(1)</script>","after":""}}})$';
|
||||
$cases['tag-split marker in rich text'] = [
|
||||
'divi/text', 'content.innerContent', ['desktop' => '$variable<x>' . $reference], self::TEXT,
|
||||
];
|
||||
$cases['NUL-split marker in rich text'] = [
|
||||
'divi/text', 'content.innerContent', ['desktop' => '$variable' . chr(0) . $reference], self::TEXT,
|
||||
];
|
||||
$cases['octet-split marker in a text title'] = [
|
||||
'divi/heading', 'title.innerContent', ['desktop' => '$variable%41' . $reference], self::HEADING,
|
||||
];
|
||||
$cases['tag-split marker deep in a value'] = [
|
||||
'divi/text', 'module.decoration.background', ['desktop' => ['color' => '$variable<x>' . $reference]], self::TEXT,
|
||||
];
|
||||
$cases['sanitizer-built valid reference'] = [
|
||||
'divi/text',
|
||||
'content.innerContent',
|
||||
['desktop' => '$variable<x>({"type":"color","value":{"name":"gcid-a1b2","settings":{}}})$'],
|
||||
self::TEXT,
|
||||
];
|
||||
$cases['javascript via a reference in a URL field'] = [
|
||||
'divi/fullwidth-header',
|
||||
'buttonOne.innerContent',
|
||||
@@ -204,6 +224,21 @@ final class AttrWriterTest extends TestCase
|
||||
self::assertSame($attrs, $result['attrs']);
|
||||
}
|
||||
|
||||
/** S28: the split-marker rows carry no marker before sanitizing, but the sanitizer rebuilds one. */
|
||||
public function testSplitMarkersAreRebuiltBySanitizing(): void
|
||||
{
|
||||
$sanitizer = ComposeFixture::sanitizer();
|
||||
$rows = ['tag-split marker in rich text', 'NUL-split marker in rich text', 'octet-split marker in a text title',
|
||||
'tag-split marker deep in a value'];
|
||||
foreach (array_intersect_key(self::malicious(), array_flip($rows)) as $name => [, , $map]) {
|
||||
$raw = (string) json_encode($map, JSON_UNESCAPED_SLASHES);
|
||||
$value = is_array($map['desktop']) ? $map['desktop']['color'] : $map['desktop'];
|
||||
self::assertStringNotContainsString('$variable(', $value, $name);
|
||||
self::assertStringContainsString('$variable(', $sanitizer->text($value) . $sanitizer->html($value), $name . ' ' . $raw);
|
||||
}
|
||||
self::assertSame('$variable' . chr(0) . '(', substr(self::malicious()['NUL-split marker in rich text'][2]['desktop'], 0, 11));
|
||||
}
|
||||
|
||||
/** Ruling S21: an editor's script in before/after is cleaned out, the reference re-serialized. */
|
||||
public function testReferenceSettingsAreCleanedForEditors(): void
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user