The Forminator Forms – Contact Form, Payment Form & Custom Form Builder plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the form_name parameter in all versions up to, and including, 1.50.2 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with administrator-level access, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page. The plugin allows admins to give form management permissions to lower level users, which could make this exploitable by users such as subscribers.
The Root cause is something that need a finesse of logic bug awareness: (This function in file /fields/html.php)
public function markup( $field, $views_obj ) {
$settings = $views_obj->model->settings;
$html = '';
$label = esc_html( self::get_property( 'field_label', $field ) );
$id = self::get_property( 'element_id', $field );
$form_id = false;
$html .= '<div class="forminator-field forminator-merge-tags" data-field="' . $id . '">';
if ( $label ) {
$html .= sprintf(
'<label class="forminator-label">%s</label>',
self::convert_markdown( $label )
);
}
// Check if form_id exist.
if ( isset( $settings['form_id'] ) ) {
$form_id = $settings['form_id'];
}
// To allow iframes in content.
add_filter( 'wp_kses_allowed_html', array( 'Forminator_Core', 'add_iframe_to_kses_allowed_html' ) );
$content = wp_kses_post( self::get_property( 'variations', $field ) ); // root cause here
remove_filter( 'wp_kses_allowed_html', array( 'Forminator_Core', 'add_iframe_to_kses_allowed_html' ) );
$html .= forminator_replace_variables(
$content,
$form_id
);
$html .= '</div>';
return $html;
}This code right here use a sanitize function (wp_kses_post) to protect XSS from lower privilege user, but the problem is, it sanitized before replacing variables. As the result, the attacker with appropriate privilege can use a valid HTML tags to bypass wp_kses_post and inject the JavaScript payload into the variables in order to trigger XSS.
Attacker with Edit Form privilege can insert a HTML in HTML field look like this
<iframe src="{form_name}"></iframe>And then change the form_name to
javascript:alert(1) or javascript:<Payload>| Score | Severity | Version | Vector String |
|---|---|---|---|
| 4.4 | MEDIUM | 3.1 | CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:C/C:L/I:L/A:N |
In my opinion, this bug here although doesn’t have great serverity, but it requires finesse of awareness in logic and code review, as you can see with just a small mistake between two lines of code and it create a vulnerability.

If you vibe with this kind of research and want to support more digging, you can donate and support me. I appreciate with your contributing.
╰(°▽°)╯