fix(security): raw content refuses Divi markup (audit M1)
lit/content-create and lit/content-update refuse content containing the divi/* block delimiters WordPress' block parser accepts or Divi 4 shortcodes, so the builder-only gates (S7/S26) can't be bypassed. Other block markup stays allowed (normal kses). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -75,6 +75,42 @@ final class PostWriterTest extends TestCase
|
||||
return (string) self::errorFields($result)[$path];
|
||||
}
|
||||
|
||||
/**
|
||||
* Security M1: raw content must not introduce Divi layouts (the builder-only gates S7/S26 of
|
||||
* the Divi tools would not apply). Refused are exactly the delimiters WordPress' block parser
|
||||
* (and Divi's BlockParser, which extends it) accepts – "<!--" + whitespace + optional "/" +
|
||||
* lower-case "wp:divi/" – plus Divi 4 shortcodes; other block markup stays allowed (kses).
|
||||
*/
|
||||
public function testContentWithDiviMarkupIsRefusedOnCreateAndUpdate(): void
|
||||
{
|
||||
$writer = $this->writerWithoutFields();
|
||||
$refused = [
|
||||
'<!-- wp:divi/section --><!-- /wp:divi/section -->',
|
||||
"<p>x</p><!--\twp:divi/text {\"a\":1} /-->",
|
||||
"<!--\n\n/wp:divi/row -->",
|
||||
'[et_pb_section][/et_pb_section]',
|
||||
];
|
||||
foreach ($refused as $content) {
|
||||
foreach ([true, false] as $isCreate) {
|
||||
$result = $writer->prepare('page', ['content' => $content], $isCreate);
|
||||
$payload = self::assertToolError($result, 'validation_failed', $content);
|
||||
self::assertStringContainsString('Divi', self::errorFields($result)['content']);
|
||||
self::assertStringContainsString('`divi`', (string) $payload['hint']);
|
||||
self::assertStringContainsString('lit-divi-', (string) $payload['hint']);
|
||||
}
|
||||
}
|
||||
|
||||
$allowed = [
|
||||
'<!-- wp:paragraph --><p>Divi ist toll</p><!-- /wp:paragraph -->',
|
||||
'<!--wp:divi/text /-->',
|
||||
'<!-- WP:DIVI/text /-->',
|
||||
'<p>wp:divi/ im Text</p>',
|
||||
];
|
||||
foreach ($allowed as $content) {
|
||||
self::assertIsArray($writer->prepare('page', ['content' => $content], true), $content);
|
||||
}
|
||||
}
|
||||
|
||||
public function testParentMustBeAReadableNonDescendantEntryOfAHierarchicalType(): void
|
||||
{
|
||||
$writer = $this->writerWithoutFields();
|
||||
|
||||
Reference in New Issue
Block a user