CF7 shortcode (nd_options_cf7) strips data-* attributes from form
-
Hi,I’m one of the developers at Friendly Captcha where we build the Friendly Captcha WordPress plugin. A mutual customer reported our captcha widget breaking on a Contact Form 7 form embedded via <code data-inline-code=””>[nd_options_cf7].
The cause is in <a class=”inline-flex h-[1.41em] max-w-full items-center gap-[0.33em] rounded-[0.5em] px-[0.5em] font-medium align-middle border text-[12px] border-[color-mix(in_oklab,var(–context-chip-accent)_34%,var(–contrast-border))] bg-[color-mix(in_oklab,var(–context-chip-accent)_11%,transparent)] text-[color-mix(in_oklab,var(–context-chip-accent)_22%,var(–contrast-foreground))] [–context-chip-accent:oklch(0.62_0.11_215)] chat-markdown-file-link cursor-pointer transition-colors hover:bg-accent/70 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/70″ data-markdown-copy=”
shortcodes/custom/cf7/index.php” data-base-ui-tooltip-trigger=”” data-slot=”tooltip-trigger” href=”/Users/merlin/.t3/worktrees/friendly-captcha-wordpress/t3code-c4959faf/shortcodes/custom/cf7/index.php” id=”base-ui-_r_1pru_”><span class=”truncate leading-tight”>index.php</span>: after rendering <code data-inline-code=””>[contact-form-7], the whole output goes through <code data-inline-code=””>wp_kses() with a custom allowlist. That allowlist permits only <code data-inline-code=””>id, <code data-inline-code=””>class, <code data-inline-code=””>style, <code data-inline-code=””>lang, <code data-inline-code=””>dir and <code data-inline-code=””>aria-hidden on <code data-inline-code=””>div, and doesn’t include <code data-inline-code=””>select, <code data-inline-code=””>option, <code data-inline-code=””>button, <code data-inline-code=””>a, <code data-inline-code=””>fieldset or <code data-inline-code=””>noscript. As a result, CF7 forms rendered through this shortcode lose:- all <code data-inline-code=””>data-* attributes, which breaks every captcha widget configured through data attributes (Friendly Captcha, Cloudflare Turnstile, hCaptcha)
- dropdown fields entirely (<code data-inline-code=””>select/<code data-inline-code=””>option)
- input attributes like <code data-inline-code=””>placeholder, <code data-inline-code=””>required, <code data-inline-code=””>min, <code data-inline-code=””>max, <code data-inline-code=””>accept, <code data-inline-code=””>multiple and <code data-inline-code=””>checked
- <code data-inline-code=””>noscript fallbacks
CF7 already sanitizes its own form markup, so it shouldn’t need a second pass. Would you consider escaping the shortcode’s own attributes individually (<code data-inline-code=””>esc_attr()/<code data-inline-code=””>esc_html() on title, class, label color, and so on) and leaving the <code data-inline-code=””>do_shortcode(‘[contact-form-7 …]’) output out of the <code data-inline-code=””>wp_kses() call? Alternatively, using CF7’s own allowlist via <code data-inline-code=””>wpcf7_kses_allowed_html() would keep form fields and data attributes intact.
Thanks!
You must be logged in to reply to this topic.