fix(security): Divi-markup refusal sees content as storage will (ruling S52)

Control characters removed by kses (wp_kses_no_null: C0, \\0 sequences)
or ControlChars (DEL) could hide a divi/* delimiter or an et_pb shortcode
from the raw-input check. The shared DiviMarkup helper checks the raw
and the normalized form and now guards every raw-content path:
content-create/-update content and media-update description (attachment
post_content). MediaImporter logs import failures with scheme, host,
port and path only; uninstall.php lists the removed user meta.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
This commit is contained in:
2026-09-26 19:50:31 +02:00
co-authored by Claude Opus 5.5
parent b24d90d8b0
commit 99eda25452
10 changed files with 173 additions and 15 deletions
+20
View File
@@ -396,4 +396,24 @@ echo "$VIA_EXECUTE" | jq -e 'has("__error")' >/dev/null || fail "9b: lit/divi-in
echo "$VIA_EXECUTE" | grep -q 'not found' || fail "9b: expected ability not found: $VIA_EXECUTE"
pass "Divi read-only: content-create divi refused, content-create without divi works, divi-insert not executable"
# 9c: control characters cannot hide the markup (ruling S52) – as the user without unfiltered_html,
# on create, update and the attachment description.
wp option delete lit_mcp_exposure >/dev/null 2>&1 || true
[ "$ORIGINAL_EXPOSURE" = "__none__" ] || wp option update lit_mcp_exposure "$ORIGINAL_EXPOSURE" --format=json >/dev/null
ATTACHMENT_ID=$(wp eval 'echo wp_insert_attachment(["post_title" => "LIT Divi Anhang", "post_mime_type" => "image/png", "post_status" => "inherit"]);')
CREATED_POSTS+=("$ATTACHMENT_ID")
connect "$EDITOR_LOGIN"
for hidden in '<!--\u0000 wp:divi/text {\"a\":1} /-->' '<!-- wp:di\u0000vi/text /-->' '<!-- wp:divi\u0001/text /-->' '[et_\u0000pb_text]x[/et_pb_text]'; do
NUL_CREATE=$(tool lit-content-create "$(jq -cn --argjson c "\"$hidden\"" '{post_type: "page", title: "LIT Divi NUL", content: $c}')")
[ "$(error_code "$NUL_CREATE")" = "validation_failed" ] || fail "9c: create accepted hidden Divi markup $hidden: $NUL_CREATE"
NUL_REV=$(tool lit-content-get "{\"post_id\":$PLAIN_ID}" | jq -r '.rev')
NUL_UPDATE=$(tool lit-content-update "$(jq -cn --argjson id "$PLAIN_ID" --arg rev "$NUL_REV" --argjson c "\"$hidden\"" '{post_id: $id, rev: $rev, content: $c}')")
[ "$(error_code "$NUL_UPDATE")" = "validation_failed" ] || fail "9c: update accepted hidden Divi markup $hidden: $NUL_UPDATE"
NUL_MEDIA=$(ability lit/media-update "$(jq -cn --argjson id "$ATTACHMENT_ID" --argjson c "\"$hidden\"" '{items: [{id: $id, description: $c}]}')")
[ "$(error_code "$NUL_MEDIA")" = "validation_failed" ] || fail "9c: media description accepted hidden Divi markup $hidden: $NUL_MEDIA"
done
if content_of "$PLAIN_ID" | grep -q 'wp:divi'; then fail "9c: Divi markup reached the stored content"; fi
if content_of "$ATTACHMENT_ID" | grep -q 'wp:divi'; then fail "9c: Divi markup reached the attachment description"; fi
pass "control characters inside the Divi delimiter or shortcode refused (create, update, media description)"
finish