The following is an analysis of how WordPress applications can be impacted by each of the OWASP Top 10 vulnerabilities discussed in the previous section. Much of the following research originates from work carried out by the Wordfence team, as well as a number of other security researchers specialising in this field.

  1. SQL Injection
  2. Broken Authentication
  3. Sensitive data exposure
  4. XML External Entities (XXE)
  5. Broken Access control
  6. Security misconfigurations
  7. Cross Site Scripting (XSS)
  8. Insecure Deserialization
  9. Using Components with known vulnerabilities
  10. Insufficient logging and monitoring

1.    SQL Injection

(See here for further details on the OWASP Top 10 vulnerabilities page)

In 2015, one of the researchers at Defiant, Matt Berry, discovered a SQL injection vulnerability (Number 1 in the OWASP Top 10 vulnerabilities) in the popular WooCommerce plugin. This plugin gives e-commerce functionality to WordPress sites and is installed on millions of WordPress sites.

WooCommerce were contacted and a fix was released before the vulnerability was disclosed to the public, under the responsible disclosure policy.

The specific issue was a SQL injection vulnerability in the admin panel within the Tax Settings page of WooCommerce. The key of the ‘tax_rate_country’ POST parameter was passed unescaped into a SQL insert statement. i.e.:

tax_rate_country[(SELECT SLEEP(10))] – This would cause the MySQL server to sleep for 10 seconds.

This vulnerability required either a Shop Manager or Admin user account and so would have needed to be combined with an XSS attack in order to be exploited.

(Wordfence, 2015)

2.    Broken Authentication

(See here for further details on the OWASP Top 10 vulnerabilities page)

In February 2018, we observed attackers using “credential stuffing”, using stolen usernames and passwords from data breaches and using them to try to log in to WordPress sites directly. The Wordfence response was to update the plugin to prevent users from using passwords that had previously been breached.

(Wordfence, 2018)

This group of attackers were observed to use compromised credentials to access wordpress.com accounts, and to install malicious plugins via the “Jetpack” plugin.

Hackers have compromised various organizations over the years, and harvested account details from them. Many of these compromises are documented by Troy Hunt on http://haveibeenpwned.com. The details often include usernames or email addresses, along with hashed versions of passwords and sometimes plain-text passwords. These compromised accounts are often leaked publicly or bought and sold by malicious actors. 

Hackers are well aware that users often do not follow best practice and use different passwords for each account, so for example, the damage of the “LinkedIn” compromise goes further than a hacker being able to update the CV for a particular user. They know that, often, users will use the same username, password and email address for other accounts for more high value targets.

If a hacker is able to use compromised credentials to log in to WordPress.com and install malicious plugins on a WordPress site, they could hijack the site and, for example, carry out a cryptojacking attack. 

Because of the small number of login attempts these attackers make, standard brute-force login protection is not enough to block these kinds of attacks. The frequency of these attacks sees them rate near the top of the OWASP Top 10 vulnerabilities.

3.    Sensitive Data Exposure

(See here for further details on the OWASP Top 10 vulnerabilities page)

As mentioned in section 3, it is important that as little sensitive data is stored on any online system as possible. This applies to all websites and CMS, and not just WordPress. The advice from WooCommerce, the largest provider to WordPress ecommerce systems, in relation to this is: “Exporting and archiving completed orders to secure storage. The less data stored on your website, the less exposure you have — and the fewer customers you need to notify in the event of a breach.”

(Automattic, 2018)

This is useful advice. Even if the site is kept up to date and secured as much as it is possible for the site owner to do so, this does not cover issues with the hosting provider. Again, as mentioned in the section relating to security misconfigurations, there have been many instances where the databases of hundreds of WordPress websites have been compromised due to vulnerabilities in the infrastructure of hosting providers. Any compromise of a WordPress e-commerce site would result in the potential exposure of sensitive customer details, for which the site owner would ultimately be responsible. The use of restrictive permissions on files like the wp-config.php file would mitigate some of these infrastructure failures, however the less customer data that is stored online, the better. Any site owners operating e-commerce systems would be well advised to employ regular penetration tests of their site to ensure it is secure. This is in fact a requirement of PCI-DSS compliance.

WordPress already implements a number of security features as standard, including the use of MD5 hashed passwords stored in the database, and the use of salting.

Whilst not specifically related to WordPress, there has also been a concerted move by the industry to encourage site owners to implement HTTPS as standard due to this entry in the OWASP Top 10 vulnerabilities. For example, from July 2018 when Chrome 68 was released, every website that is not running HTTPS is now labelled as “not secure” in the address bar.

4.    XXE Vulnerability

(See here for further details on the OWASP Top 10 vulnerabilities page)

Whilst not limited to WordPress, this vulnerability affected PHP applications, including WordPress. This was classed as a severe WordPress vulnerability which was left without being patched for around a year and had the potential to disrupt all WordPress sites.

It was disclosed at the BSides conference in Manchester in 2018 by Secarma researcher Sam Thomas. He implied that the bug permits attackers to exploit the WordPress PHP framework, resulting in a full system compromise.

If the WordPress site permitted the upload of files, like image formats, then attackers could upload specially developed thumbnail files and then trigger a file operation through the “phar://” stream wrapper. This would then trigger eXternal Entity (XXE — XML) and Server-Side Request Forgery (SSRF) flaws which “had the potential to cause unserialization in the platform’s code”. The original result of this vulnerability would likely just be the disclosure of sensitive information, however it could act as a path to more serious consequences.

The vulnerability was within the wp_get_attachment_thumb_file function in /wpincludes/post.php. When attackers were able to gain control of a parameter used in the “file_exists” call,” the bug could be triggered.

In this case, unserialization occurs when serialized variables are converted back into PHP values. When autoloading is in place, this can result in code being loaded and executed, an avenue attackers may exploit in order to compromise PHP-based frameworks.

(Osborne, 2018)

5.    Broken Access Controls

(See here for further details on the OWASP Top 10 vulnerabilities page)

In November 2018, the popular plugin WP GDPR Compliance was removed from the WordPress repository. The developers released version 1.4.3 the following day which patched multiple critical vulnerabilities. The plugin was then reinstated in the WordPress repository and has over 100,000 active installs. 

The vulnerabilities allowed unauthenticated attackers to achieve privilege escalation, allowing them to further infect vulnerable sites.

The plugin was able to carry out a number of actions via the WordPress admin-ajax.php functionality, including making the sort of data access requests and deletion requests required by GDPR. Unpatched versions of the WP GDPR Compliance plugin (up to and including version 1.4.2) failed to carry out checks when executing the save_setting action to make these configuration changes. Hackers were able to submit arbitrary options and values, with the input fields stored in the options table of the WordPress application’s database.

In addition to this update of the wp_options table, the plugin carried out a do_action() call with the relevant option name and value. This was then used to trigger arbitrary WordPress actions.

The Wordfence Site Security Team (SST) discovered high numbers of live sites infected through this attack vector in 2018. In most of these cases, new administrator accounts were being created on the impacted sites by setting the users_can_register option to 1, and changing the default_role of new users to “administrator”. The hackers were then able to simply fill out the form at /wp-login.php?action=register which created an administrator user that allowed them to log in with full privileges. Once they had administrator access to the site,  they were then able to hide their tracks and install backdoors or webshell plugins to further infect the site. 

In many of the cases seen by the team, the username t2trollherten was used as the administrator login. In many cases, webshells named wp-cache.php were also uploaded. 

(Wordfence, 2018)

6.    Security Misconfigurations

(See here for further details on the OWASP Top 10 vulnerabilities page)

At Defiant, the term “Service Vulnerability” is used to describe any issue with a technology service that represents an exploitable security risk for its users. This term was coined in response to the growing trend of security issues relating to this entry in the OWASP Top 10 vulnerabilities for those problems discovered by our team in commercial services, with many of them being WordPress hosting providers.

In particular, throughout 2017, we started to see an increasing number of similar cases from three service providers. Research carried out by members of the team, including the SST Team Lead at the time, Brad Haas, led to the discovery of a critical vulnerability affecting the customers of those services. The companies in question were:

  • Hostway (and its other brands including Gate, Netnation, Domainpeople, and rebranded services for Qwest/Centurylink)
  • Momentous Corp. (includes Rebel and Internic.ca)
  • Paragon Group (includes Vidahost, TSOHost, Webfaction and others)

We saw different groups of customers all experiencing similar issues. The symptoms generally progressed as follows:

  • The customers were locked out of their administrator account and a user from an unknown IP address had logged into it.
  • New administrator accounts were then created for their site. 
  • Finally, the attackers started to compromise the sites further, adding malware, spam, or adding scripts to the database to redirect visitors to malicious sites, potentially infecting the computers of those users.

Whilst we had a great deal of forensic information for many of these attacks, we were unable to pinpoint the cause of these infections for some time. We were able to configure logging for some of these sites, so when they were reinfected (which happened quite regularly), we were able to examine the web access logs for the time of the reinfection, but were unable to see anything that might explain how these administrator accounts were being altered. We also checked for maliciously created cron jobs and FTP logs that might explain these reinfections, but without success.

As we could see no signs of the change to the administrator credentials being made via the WordPress front end, we decided that the most likely avenue was through direct compromise of the database. With access to the database, a hacker can change the WordPress credentials or add content, like malicious scripts causing redirects, without leaving any trace in the web access logs for the site.

Most web hosts limit access to the database server to users that are logged into their hosting control panel. Applications like phpMyAdmin are often used to administer MySQL databases, which sometimes require a second layer of authentication once logged into the hosting account. Obviously, web applications like WordPress also need to be able to connect to the database, but they still need the database credentials to do this. WordPress sites store that username and password in the wp-config.php file.

On shared hosting services, companies will use one server to host potentially hundreds of websites, with each customer getting an account on the server. Their site’s files belong to that account. Every file and folder has both a user and a group as the owners, with file permissions controlling who can do what to files and folders. If files do not have the correct permissions set, this can cause serious security issues.

For example, if you set your website directory to be world-writeable, then any other user on the server would be able to create files or directories in it. Similarly, if the website directory and wp-config.php file are both world-readable, then any other user can read the contents of wp-config.php, which include the database credentials for the site.

In filesystems like this, if a user has read access to a directory then they can list the contents of that directory. If the user doesn’t have read permission but does have traverse permission, then they can work with files or subdirectories in that directory, as long as they know the names and have the relevant permissions on them. For example, in a home directory, the server will not tell you what subdirectories are located in it, like /home/giles for example, but if you know that a user “giles” exists on the server then you can probably guess that there is a “giles” directory in /home. If you have access to it, then you can still work with it as long as you have the traverse permission on the /home directory.

Hosting companies will often use network file servers to host their customers’ data. This allows them to add more storage as required without impacting on the running of the server itself. Previously, hosting companies might just have a number of fixed disks assigned to a server, however as user’s sites got bigger and they required more disk space, the server’s filesystems would end up being filled. One way of achieving this is to use a Network File System (NFS) for customers’ files. One of the common denominators between the customers that were suffering from these attacks was that the websites were running on servers with networked file systems. The three hosting platforms mentioned earlier were all using NFS, and had variations on the same problem. The Defiant researchers discovered that there were three conditions that existed and combined to make the platforms vulnerable:

  1. Customer files were stored on a shared file system (in this case, NFS).
  2. All directories in the shared file system were world-traversable, and customer files were world-readable by default.
  3. The full path to a customer’s website directory was public or could be guessed.

The vulnerable hosting platforms all stored their customers’ files on a shared file system, with the topmost directory owned by the server root account. It was not set as world-readable, so regular user accounts were not able to list their contents, however all directories were world-traversable.

At some point, the hackers realised that, whilst they couldn’t list the contents of the directory where customer accounts were stored, they could guess the names of the directories containing those files. This then allowed them to use one hacked site to read the contents of the wp-config.php file for all other accounts on that server.

In the example of Hostway, which operated under a few different names, like Gridhost, the site files were located in a directory structure like this:

/home/14/23/1012314/web

The /home folder contained many directories which followed the same numerical naming convention. In this example, the folder 1012314 and everything in it belonged to the user and the directories above it belonged to the server root account.

If the hackers had compromised the site in directory 1012314, and tried to list the contents of /home, they would not have the relevant permissions to do this. They would also not have permission to view the contents of /home/14 or /home/14/23. At some point, they realised that all the customer directory names followed this pattern:

/home/XX/YY/ZZZYYXX/web

XX and YY are two-digit numbers, and ZZZ is a three-digit number. From the compromised site in 1012314, the hackers would have been able to run a script to try all possible combinations, listing files in each path. For example, the script might start with listing the contents of /home/00/00/0000000, then /home/00/00/0010000, etc. If no directory existed in those locations then the result would be a “no such file or directory” error, otherwise it would list the contents of the other customers web directory.

Through this method, the hackers were able to list the contents of all other sites on the same server. If the website was a WordPress site, then they could read wp-config.php and obtain the database credentials for that site. With access to a legitimate site with that hosting service, they would then also be able to use phpMyAdmin to gain full database control for the site.

This allowed the hackers to compromise hundreds of WordPress sites and nothing would ever appear in the logs of the other sites.

(Wordfence, 2019)

7.    Cross-Site Scripting (XSS)

(See here for further details on the OWASP Top 10 vulnerabilities page)

Analysis by the Wordfence research team looked at plugin vulnerabilities reported in 1,599 WordPress plugins over a 14-month period. The results, displayed in figure 4.1 below, show that Cross-Site Scripting vulnerabilities are by far the most common of the OWASP Top 10 vulnerabilities affecting WordPress plugins.

Figure 4.1 – Percentage of WordPress Plugins Affected by Specific Vulnerabilities

As indicated by the graph, XSS vulnerabilities account for nearly 47% of all vulnerabilities affecting WordPress plugins, so helping developers to prevent them writing vulnerable code would improve the security of most WordPress sites.

As mentioned earlier, the primary way to prevent XSS attacks is through the validation and sanitisation of user input. There are a number of ways this can be achieved when developing plugins or themes for WordPress.

(Wordfence, 2017)

Using Functions to Validate User Input

In programming, validation is the process of confirming that any data that is sent to the application is of the type that is expected. It ensures that user input does not contain anything that is “unreasonable, unnecessary or malicious”. It is still necessary to sanitise or escape user input, as it is sometimes possible for malicious data to evade some validation functions.

The kinds of constraint used by PHP and JavaScript in WordPress applications are similar to those used by most programming languages, and might include confirming that user input:

  • Is data an integer (0 to 9 digits only).
  • Is data a float with a decimal point allowed (0 to 9 and . character).
  • Is data numbers and dashes e.g. a credit card date field.
  • Is data a string with numbers, letters, spaces and punctuation only.
  • Is data one of a limited number of options that can be selected e.g. ‘option1’, ‘option2’, ‘option3’.

Using Regular Expressions for Validation

The PHP function preg_match() can be used to validate data. When doing this, it is important to match the whole string by using the caret ^ character to anchor at the start of the expression and the dollar sign $ at the end. This prevents the regular expression from just matching a subsection of the string and will ensure that the entire string is validated.

Without including these anchors in a regular expression, an attacker could include some valid data along with their malicious input to fool the application into thinking that the entire input is legitimate.

PHP Built-In Sanitisation and Escaping Functions

The following are examples of PHP functions that can be used to validate that user input is correct:

  • is_numeric()
  • preg_match()
  • in_array()
  • filter_var()

For a variety of reasons, filter_var(), included in PHP since version 5.2 is the most recommended function for validation. 

WordPress API Sanitisation Functions

WordPress includes a range of sanitization functions that are designed for specific use cases. A few examples can be seen in Figure 4.2

Figure 4.2 – WordPress API Sanitization Functions

FUNCTIONOUTPUTCOMMENTS
esc_html(‘<tag> & text’);&lt;tag&gt; &amp; textEscape HTML for safe browser output. [docs]
esc_url(‘http://example.com/<script>alert(“TEST”);</script>’);http://example.com/scriptalert(TEST);/scriptEscape URLs to make them safe for output as text or HTML attributes. [docs]
esc_js(‘alert(“1”);’);alert(&quot;1&quot;);Escapes JavaScript to make it safe for inline HTML use e.g. in onclick handler. [docs]
esc_attr(‘attr-<>&\’”name’);attr-&lt;&gt;&amp;&#039;&quot;nameUse to escape HTML attributes e.g. alt, title, value, etc. [docs]
esc_textarea(‘Text <tag> & text’);Text &lt;tag&gt; &amp; textEscapes text for output in <textarea> element. [docs]

WordPress API Escaping Functions

WordPress also includes escaping functions for general use. Figure 4.3 contains a few example functions.

Figure 4.3 – WordPress API Escaping Functions

FUNCTIONOUTPUTDESCRIPTION
absint(‘-123ABC’)123Sanitizes positive integers. [docs]
sanitize_email(“!#$%^&*()__+=-{}|\][:\”\’;<>?/.,[email protected]”)!#$%^&*__+=-{}|’?/[email protected]Sanitizes email addresses. [docs]
sanitize_file_name(‘.-_/path/to/file–name.txt’);pathtofile-name.txtSanitizes filenames. [docs]
sanitize_html_class(‘[email protected]#$%^&*()-name_here.’);class-name_hereSanitizes CSS class names. [docs]
sanitize_key(‘[email protected]#$%^&*()<>,.?/’);key-nameSanitizes keys for associative arrays. [docs]

The use of The HTTPONLY Flag

In September 2002, Microsoft released Service Pack 1 (SP1) for the (at the time) popular Internet Explorer browser. Prior to this, cookies were accessible to both web servers and to JavaScript when a browser made a request. This meant that, prior to SP1, scripts running in a browser on a particular website could read all of the cookies that had been set by that website. This allowed any malicious scripts to read the cookies and send the data to remote locations controlled by the attackers. Hackers could therefore use XSS vulnerabilities to steal information stored in those cookies. For example, if a user was signed into a specific website, the hackers would be able to connect as that user. 

The SP1 release in 2002 provided the optional HttpOnly flag that could be used when a cookie was set. This prevented those cookies from being read by JavaScript. This feature was quickly adopted by other browsers and is now supported by all major browsers. This is also the method used by WordPress to prevent XSS vulnerabilities allowing hackers to steal sensitive data from cookies. Also, changing a user’s password in WordPress also invalidates all user cookies immediately, should a breach be suspected.

(Wordfence, 2019)

Recent Examples of XSS Vulnerabilities in WordPress Plugins

In October 2019, research by Matt Berry of Wordfence discovered an XSS vulnerability in the SyntaxHighlighter Evolved Plugin. This plugin had in excess of 40,000 installations at the time of discovery, and was in fact in use by Wordfence to highlight code samples in blog posts. It was also in use on wordpress.com sites (Incidentally, Matt received a $300 Bug Bounty from Automattic for the discovery. The plugin’s developer, Alex Mills died of leukaemia earlier in 2019. Matt donated the reward to an organisation that had been involved in Alex’s treatment). Matt described the vulnerability as follows:

“SyntaxHighlighter will, by default, create links for URLs within the shortcode body. The URL regex is loose enough where a javascript:// psuedo-protocol can be used to execute JavaScript when clicked. SyntaxHighlighter will process shortcodes in post comments, so an unauthenticated user can submit shortcodes containing an XSS payload. The XSS payload is then rendered within the comments section of the post, and the comments moderation page in WP Admin.”

(Wordfence, 2019)

8.    Insecure Deserialisation

(See here for further details on the OWASP Top 10 vulnerabilities page)

Whilst not limited to WordPress, a PHP bug related to data deserialization was discovered by a security researcher in February 2017. The bug was then reported to the WordPress team on 28 February, 2017 was not addressed for some time after that, possibly as they deemed it to be very low risk, and possibly as it relates to PHP as a whole and not just WordPress. The vulnerability is in the way PHP converts objects into strings and back into PHP objects again, a process known as serialization and deserialization. It is used by programming languages to move data between differing servers, services, or apps.

Issues with the way PHP carries out this process have been known to be vulnerable since at least 2009, when German security researcher Stefan Esser documented the first attack. 

This particular vulnerability was discovered by Sam Thomas, a security researcher with Secarma Labs. He revealed a new way of using PHP’s deserialization process to achieve code execution on servers and apps. The technique relied on attackers having the ability to upload malformed data to a server. This data would be malformed in such a way as to allow a call on the PHP “phar://” stream wrapper. This eventually chained together various operations that granted the attacker the ability to execute malicious code.

When applied to WordPress, this bug affected the thumbnail processing functions. Exploiting the flaw required an attacker to have the ability to upload a malformed image on the platform.

(Wei, 2018)

9.    Using Components with Known Vulnerabilities

(See here for further details on the OWASP Top 10 vulnerabilities page)

There are many examples of web developers or designers using components with known vulnerabilities to create WordPress sites, so this entry in the OWASP Top 10 vulnerabilities is regularly seen in the wild. There are various tools that developers can use to determine whether plugins or themes are safe to use. For example, WordPress maintains a repository of plugins and themes for developers to use. If any security issues are discovered in these components then they can be removed from the repository until a fix has been released. Many plugins and themes are available from third party developers that are not in the repository, however there is very little oversight over the security of these components. When putting together a security report, the Wordfence team provide details over whether the plugins and themes in use for a site are in the repository, and also whether the component is being actively developed. If there have been no updates to a component for some time, they can be deemed to be “abandoned” and therefore less trustworthy.

WP-VCD Infections

The team at Defiant have been aware of a long-running campaign against WordPress sites that is known as WP-VCD. The team have seen many almost identical infections using the same code and intrusion vector. The malware has been known about for at least the past two years and was found to have been spread through “nulled” or pirated WordPress themes. The first infection in the wild was found in February 2017. The rates of infection have been increasing every week since August 2019.

Nulled themes are a problem for WordPress developers and site owners. They occur when legitimate, premium themes or plugins are altered to remove any licensing or copyright protection and resold, or given away for free download by other disreputable websites. This gives the malicious owners of these sites the opportunity to infect the components with their own backdoors or malware. As web developers and designers are downloading paid-for themes for free and then installing them on their own sites, they can be said to be infecting their own sites.

This particular WP-VCD infection itself was spread through a network of related sites, and then propagated itself to other sites and themes on the same hosting account. The organisation behind this infection implemented a sophisticated “Command and Control” infrastructure to ensure that the infection remained persistent on the sites without drawing too much attention. The organisation used the infection to generate income from two main activities. Firstly, they used the infected sites to carry out “Black-Hat SEO”, where they manipulated the search engine results for sites of their choice. For example, Figure 4.4 shows a Google search for a specific theme which has been pirated, where the malicious download site often ranks more highly than the legitimate download site. In the screenshot below, the first two natural listings are for downloadfreethemes.co which has been associated with distributing WP-VCD infected themes.

Figure 4.4 – Google Search for a Specific Nulled Theme

Secondly, the malicious actors have also been injecting malvertising code into infected sites, causing potentially dangerous pop-ups or redirects. 

The infection is relatively simple and does not rely on code obfuscation to evade detection. In most cases, either a class.plugin-modules.php​ or class.theme-modules.php​ was added, depending on whether it is a nulled theme or plugin that is being installed. Upon activation, the malware looks for installed themes on the site and infects the functions.php with malware in the header. The malware takes the form of a backdoor. The deployer script takes the MD% checksum of the site URL, and the WordPress AUTH_SALT constant and uses these to generate a password to access the backdoor. This prevents other hackers being able to use the backdoor. The deployer script also overwrites the last modified timestamp of the functions.php files to set it to what it was originally to hide the fact that the changes have been made to the file.

Once infected, the malware calls back to the hacker’s “Command and Control” servers with details of the password created previously. This allows the hackers to monitor new infections and interact with these sites as required. At the time of writing, the Command and Control server in use is at krilns.com, however there have been several hundred domains used over the course of this campaign.

After registration with the Command and Control server, the malware navigates up in the file system looking for additional WordPress sites to infect. It creates a file in wp-includes – wp-vcd.php and modifies the wp-post.php file to run the code in wp-vcd.php every time a page loads.

Once all this is complete, the deployer script deletes itself, hiding its tracks. The malware then listens to the command and control server for instructions, allowing the hackers to deploy malicious code to all of the sites in its control. As mentioned, this could be to cause malicious redirects or pop-ups, or carrying out Blackhat SEO techniques.

(Veenstra, 2019)

Supply Chain Attacks

Another potential issue affecting WordPress plugins and themes is what is referred to as “Supply Chain Attacks”. This is where the ownership of legitimate components are purchased by malicious actors and the development of these components taken over by them. This allows them to add malicious code, including backdoors into the plugin or theme. When site owners update their plugins to the latest version, these backdoors or malware are secretly added to their site without their knowledge.

In September 2017, Defiant CEO Mark Maunder wrote extensively on the subject of a specific malicious actor that was carrying out a Supply Chain Attack using a number of plugins. The first to be discussed was a plugin called “Display Widgets”. The final three releases of that plugin contained a backdoor that allowed the author to publish any content, in this case spam content to sites that had the plugin installed.

The plugin was installed on 200,000 sites and was included in the WordPress repository, although over the summer of 2017 it was removed and readmitted to the repository four times.

The timeline of events showed that the plugin was sold by its owner on 21 June 2017 and the new owners quickly released a new version. The following day, a UK-based SEO consultant (David Law) wrote to WordPress.org to let them know that the plugin was installing additional code from a remote server. The plugin was removed from the repository, but later readmitted after version 2.6.1 was released on the 30 June. The new version contained malicious code held in a geolocation.php file, although this was not immediately discovered. This allowed the plugin author to post new content to any website running the plugin, also allowing them to update content and remove content. It also prevented users that were logged in to the site from viewing the malicious content, thus hiding itself from the site owners.

The plugin was removed from the repository after David Law again discovered that the plugin was logging data on user visits to a remote server. As the malware contained in geolocation.php had not yet been discovered, the plugin was readmitted to the repository once a new version had been released, removing the logging of user visit data.

It wasn’t until 23 July that it was discovered that the plugin was injecting spam content into sites. The WordPress.org plugin team again removed the plugin from the repository the following day.

A new version of the plugin was released on 2 September, which included a bug fix to the malicious code. This indicated that the developers were actively maintaining the malicious aspects of the geolocation.php file and understood what it was doing.

Users continued to report that spam injections were appearing on their sites, however communication from the plugin authors attempted to justify this. In a variety of messages, they told users that the latest versions had fixed the issue and that the continuing issue might be related to caching on the user’s side. They also implied that the plugin’s use in conjunction with other specific plugins could cause a vulnerability that was allowing sites to be compromised, but that this only affected around 100 sites in total. This was not true. The code was a backdoor, giving the author access to publish content on websites using the plugin. It in no way required other plugins to work.

As mentioned, Defiant carried out a great deal of research into this particular attack, with CEO Mark Maunder speaking to the original author of the plugin – Stephanie Wells. She was very helpful, and indicated that they had sold the Display Widgets plugin to “Mason Soiza” for $15,000. 

(Maunder, 2017)

The research showed that Soiza had gone through the same process of acquiring a number of other plugins and using them in a similar way. These included wp-slimstat, finance-calculator-with-application-form and 404-to-301. The same malicious actor was later a part of investigations by the BBC’s Panorama programme and The Times into his ownership of online pharmaceutical companies. 

Their plugins have been permanently removed from the WordPress repository, however there will be many other malware authors carrying out similar activities.

(Wordfence, 2019)

In a similar situation to the Display Widget plugin scandal, another UK-based development team carried out unethical activities in their plugin and theme development. Pipdig develop a theme popular with fashion bloggers. They provide a companion plugin known as the Pipdig Power Pack (P3) plugin. In March 2019, Mikey Veenstra of Defiant started investigating suspicious behaviour in this plugin. A UK-based developer, Jem Turner, also happened to be looking into this suspicious activity in parallel. A user of this plugin had contacted Defiant with concerns that the plugin seemed to give Pipdig the ability to grant themselves administrator access to sites where the plugin was installed, and also allowed them to completely destroy those sites by deleting the database. This plugin was installed on between 10,000 and 15,000 sites.

The code was analysed by Defiant and this functionality was confirmed. For example, the code clearly contacted the Pipdig servers on an hourly basis to check the contents of a specific file on their servers. If the URL of the site in question was present in that file, the database would be dropped completely. It was also confirmed that the plugin would automatically deactivate plugins from a list defined by Pipdig, some of which are very commonly used, without alerting the user that this was happening.

Jem Turner, also investigating this plugin, discovered the following code in the plugin:

This code claimed to be checking the CDN cache. In fact, it was sending an HTTP GET request to the URL listed in the id39dqm3c0_license_h.txt file. The URL listed in this file was a competitor of Pipdig. The effect was that all sites where this plugin was installed were sending regular GET requests to a competitor’s site, causing a Distributed DoS. The competitor, when contacted, commented:

“I actually had huge trouble with my web host and they explained that my admin-ajax.php file was under some kind of attack [..] I can confirm that I have never given pipdig any permissions to make requests to my servers. Nor was I ever in a partnership or any sort of contact with them.”

Their host was able to provide web access logs which showed these connections hitting their site from thousands of IP addresses.

In addition to these unethical activities, the plugin was also changing content throughout the sites to benefit the plugin developers. For example, this code is slightly obfuscated and changes any references to “Blogerize” (a beginners blogging service) to advertise their own services:

(Turner, 2019)

Pipdig were contacted for comment and initially responded that the drop database function had been introduced to combat piracy. They did not comment on the obfuscated coding practices or admin access functionality. They then started to try to hide the unethical activity. They did this by:

  • They removed the file containing the URL of their competitor, as well as other suspicious files from their server.
  • They released undocumented updates to the plugin to remove the malicious code.
  • They modified the dates on changelog entries.
  • They removed the bitbucket repository containing the historical evidence of their code changes – luckily, backups had been taken by researchers.

They then released a series of updated comments on the situation. This included an update to their initial response regarding the destruction of the database. In it they said:

“The function is in place to reset a site back to defaults, however it is only activated after being in touch with the site owner.”

The problem with this is that in doing so, the entire database is deleted and the next visitor to the site is prompted to set up a site from scratch and can install themselves as administrator. If the site owner does not have a database backup then they will have lost their site completely.

The company were also not able to satisfactorily explain the code used to carry out a DDoS against their competitor.

The story was also covered in the media by The Register (Nichols, 2019).

Despite all this, a number of the users of this theme defended the plugin developers and continued to use the theme, highlighting the importance of not using components with known vulnerabilities or malicious code.

Abandoned Themes and Plugins

Theme and plugins that have been abandoned by their developer are an ongoing issue for those creating WordPress sites. As a part of the Wordfence analysis, the components installed on a site are checked to confirm whether they are still being actively developed. If not, there could be known or unknown vulnerabilities that will not be patched. It is advised that any abandoned components are removed or replaced to prevent WordPress sites owners from being exposed to this entry in the OWASP Top 10 vulnerabilities.

10.  Insufficient Logging and Monitoring

(See here for further details on the OWASP Top 10 vulnerabilities page)

When analysing a WordPress site for infection, having web access logs for the time of the infection is essential in confirming the intrusion vector. Unfortunately, some hosting providers do not give access to these logs, making them vulnerable to this entry in the top 10 OWASP vulnerabilities. For example, in some of the cheaper packages offered by GoDaddy, they will only provide access to web access logs with a court order. Other hosting providers will only provide access to logs for the past few days or up to a month. It is often possible to enable log rotation in some hosting accounts, which compresses and archives logs on a periodic basis, giving access to logs dating back months or years. Unfortunately, many hacks go unnoticed for some time, meaning that even if logging is enabled, there are often no logs available for the time of the attack. It is sometimes possible to make assumptions on the intrusion vector based on the malware found. For example, in the wp-vcd infection mentioned earlier, should the wp-vcp.php files be discovered, it can be assumed that the intrusion vector will have been through the use of a nulled theme or plugin.

Whilst it will often be possible to obtain access logs, error logs are not always as easy to obtain from a hosting provider. Fortunately, it is possible to enable debug logging in WordPress by setting configuration options in the wp-config.php file. This can help in diagnosing issues with the site and highlighting any possible infection.

In terms of monitoring, Wordfence provides monitoring and alerting that can help site owners respond to possible attacks. The options are configurable and can provide email alerts indicating both successful or failed logins. It also stores details and locations of logins to help determine any patterns of login failures. The plugin will also allow live traffic analysis to help determine whether any attacks are in progress and allow them to be blocked.

Back to Part 3 – the full list of OWASP Top 10 vulnerabilities.

On to Part 5 – Providing Customers with a Clean WordPress site

Part 4 – OWASP Top 10 Vulnerabilities Affecting WordPress Applications