Forms block fails to select/save a form — SecurityError reading senderForms
-
Forms block fails to select/save a form — SecurityError reading
senderForms on cross-origin iframe (v2.10.18)Plugin: Sender – Newsletter, SMS and Email Marketing Automation for
WooCommerce
Version: 2.10.18
File: includes/js/sender-forms-block.jsSummary
In the block editor, selecting a form in the Sender.net Form block throws
an uncaught SecurityError and the selection is never saved (the block
outputs no form). It reproduces on any page/post that also contains a
cross-origin iframe — e.g. a YouTube embed block, or an iframe injected by
another plugin (Google Site Kit, etc.).Console error
Uncaught SecurityError: Failed to read a named property ‘senderForms’ from
‘Window’:
Blocked a frame with origin “https://example.com” from accessing a
cross-origin frame.
at Array.forEach ()
at destroyForm (sender-forms-block.js:32)
at Object.onChange (sender-forms-block.js:54)Steps to reproduce
- Edit a page that contains a cross-origin iframe (e.g. a YouTube embed).
- Add the Sender.net Form block.
- Pick any form from the “Select Form” dropdown.
- → SecurityError is thrown; the dropdown reverts; saving produces no
form on the front end. Root cause
getEditorWindows() collects iframe windows, but its try/catch only guards
iframe.contentWindow — which does not throw for cross-origin frames. The
cross-origin window is therefore pushed into the list, and renderForm() /
destroyForm() then read editorWindow.senderForms on it without a guard,
which does throw:
function destroyForm(formHash) {
getEditorWindows().forEach(function (editorWindow) {
if (editorWindow.senderForms && …) { // ← throws on a
cross-origin window
Suggested fix
Wrap the property access in renderForm() and destroyForm() in try/catch
(or probe a property inside getEditorWindows() so cross-origin windows are
filtered out before use):
function destroyForm(formHash) {
getEditorWindows().forEach(function (editorWindow) {
try {
if (editorWindow.senderForms &&
typeof editorWindow.senderForms.destroy === 'function') {
editorWindow.senderForms.destroy(formHash);
}
} catch (e) { /* cross-origin editor frame — skip */ }
});
}
// same guard in renderForm()
Workaround (for other users hitting this)
Skip the block and place the form's embed div in a Custom HTML block
instead — this is exactly what the block compiles to, and universal.js
renders it:
You must be logged in to reply to this topic.