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:
2026-09-26 19:13:58 +02:00
co-authored by Claude Opus 5.5
parent 0f23192873
commit 7d0837be6c
3 changed files with 65 additions and 1 deletions
@@ -38,6 +38,17 @@ class PostWriter
private const META_DENIED = 'Keine Berechtigung, dieses Feld zu ändern.';
/**
* Divi markup in raw content (security M1): the block delimiters WordPress' block parser accepts
* for divi/* blocks (Divi's BlockParser extends it: "<!--", whitespace, optional "/", lower-case
* "wp:divi/") and Divi 4 shortcodes. Such content would bypass the builder-only gates of the Divi
* tools (rulings S7/S26); other block markup stays allowed and goes through WordPress' kses.
*/
private const DIVI_MARKUP = '~<!--\s+/?wp:divi/|\[/?et_pb_~';
private const DIVI_MARKUP_HINT = 'Divi-Inhalte über `divi` (lit-content-create) bzw. die lit-divi-*-Tools '
. '(lit-divi-insert, lit-divi-update, lit-divi-move, lit-divi-delete) ändern.';
/** wp_insert_post() ignores an empty page_template; this value selects the default template. */
public const DEFAULT_TEMPLATE = 'default';
@@ -55,7 +66,11 @@ class PostWriter
public static function inputProperties(): array
{
return [
'content' => ['type' => 'string', 'description' => 'HTML bzw. Block-Markup (nicht für Divi-Inhalte).'],
'content' => [
'type' => 'string',
'description' => 'HTML bzw. Block-Markup; Divi-Markup wird abgelehnt (Divi-Inhalte über divi '
. 'bei lit-content-create bzw. die lit-divi-* Tools).',
],
'excerpt' => ['type' => 'string'],
'slug' => ['type' => 'string'],
'parent' => ['type' => 'integer', 'minimum' => 0],
@@ -86,6 +101,9 @@ class PostWriter
public function prepare(string $postType, array $input, bool $isCreate): array|WP_Error
{
$errors = [];
if (is_string($input['content'] ?? null) && preg_match(self::DIVI_MARKUP, $input['content']) === 1) {
$errors['content'] = 'Divi-Markup ist in content nicht erlaubt.';
}
$fields = $this->validator->validate(
$this->schema->fields($postType),
@@ -114,6 +132,12 @@ class PostWriter
];
$errors = array_merge($errors, array_filter($checks, static fn (?string $error): bool => $error !== null));
if (isset($errors['content'])) {
$message = 'Eingaben sind ungültig; nichts wurde gespeichert.';
return Errors::invalidInput($message, $errors, self::DIVI_MARKUP_HINT);
}
if ($errors !== []) {
return Errors::invalidInput('Eingaben sind ungültig; nichts wurde gespeichert.', $errors);
}