Remove hidden spam links from WordPress
Saturday, July 11th, 2009 12:28 am
Categories: Blog.
While working on a client’s site today, I had my first encounter with a nasty little hack that WordPress can be vulnerable to – hidden spam links injected into your site’s content.
Because the links are hidden, the only way to discover them is if you search for them or happen to come across them as you edit your posts through the HTML editor.
What are Hidden Spam Links?
They look like this:
<div style="display:none"><a href="http://link-to-spam-site-here">Dowload movies</a></div>
The trick is in the section: “style=”display:none” – This hides the links from viewers, but reveals them to search engines. Once these spammers get hundreds of links to their sites, they are able to rank much higher in the search engine results.
Why Hidden Spam Links Are Bad for Your Site
Links coming to your site are good for Page Rank, an algorithm that Google and other search engines use to decide how relavant your site is. The opposite end of that is that Links leaving your site, pointing to other sites pass that Page Rank on and out of your site. In order to enhance the SEO strength of your site, you can tell the search engines to ignore links leaving your site using rel=”external nofollow” like this:
<a href="http://google.com" rel="external nofollow"></a>
What these spam links do is inject hidden links that will steal Page Rank from your site. You won’t know it because they are hidden.
What’s even worse is that Google will see you hiding links to ‘bad neighborhood’ sites, associating you with them and really harming your search engine rankings, leading to a potentially serious drop in traffic. The sites these links lead to are things like viagra, cialis, different prescription drugs, and movie downloads sometimes even porn. These are not sites you want search engines associating with your site.
Removing the Hidden Spam Links
In the admin section, edit your posts and use the search box to find some of those spammy words: viagra, cialis, movie downloads, etc. This should give you some results if you have hidden links. Edit these posts using the html editor and look for anything with that ‘style=”display:none”‘ and delete it.
If you find any results however, chances are that many of your posts are infected. If you have been blogging for a while and have even 50 posts, it would take hours to go through all of them through the Admin section. Luckily there is a faster way to do this using the database.
Only edit the database if you have done this before. You need to use something like PhpMyAdmin to access and edit the database. If you don’t know what any of this means, then you should avoid this part of the instructions.
Remember to backup your database and export a copy of your WordPress xml before editing the database directly.
To find the hidden links, you can run an SQL query, looking for that “display:hidden” phrase anywhere in the content of any of your posts.
SELECT * FROM wp_posts WHERE post_content LIKE '%"display:none"%'
My results had over 50 infected posts and I found that the spammers are very smart in another way – the links don’t repeat themselves. If they were all the same, I could run a search and replace on the entire database and it would take all of a few seconds. But they switch things up enough that once the posts were listed, I had to go one by one removing the offending links. Doing this through PhpMyAdmin was the only way to make sure I found all of them and it works a lot quicker than editing through WordPress anyway.
Improving Damaged Search Rankings
If your site has been like this for a while or if you have noticed an unexplained drop in search engine traffic, you should take care of removing the links, then resubmit your site to the search engines. Here is a link to Google reconsideration. Once they see that you have a legitimate site, everything should return to normal.
Making sure WordPress is Secure
You should optimize your WordPress installation and make sure all the best WordPress plugins are in place.
If you haven’t already done it, remove the ‘admin’ user then change passwords on other users in case they were exposed.
Protect the ‘wp-config.php’ file and ‘wp-admin/install.php’ file by adding this to your .htaccess file:
# PROTECT install.php <files install.php> Order Allow,Deny Deny from all Satisfy all </files> # protect wpconfig.php <files wp-config.php> Order deny,allow deny from all </files>
More advanced WordPress Security Tips
Everything I have described above is just the beginning. You can try these as well:


A good article, it made me think about some of the bugs there might be in my wordpress blog.. Thanks for posting this!
Thank you for this good article.
Happened to my site as well and I had so many to fix I had to write a script to strip them out, which was hard given how they are all different!
Hey, This has been happening to me for the past two months, and after doing everything, and going through every suggestion I’ve found and having no time to post what my site’s is about in the first place
I’ve got the ‘every 48 hr. fix’ going on. I want the permanent fix, but I have a few quick questions regarding your suggestions. Will you e-mail me at my submitted e-mail? PLEASE??
Have you looked at the users that have signed up for your site? If you have any unknown or questionable users you may want to delete them and try disabling the ability for people to sign up until you figure this out.
Hey Marty,
Thanks for this post. You seem to be the only place I can find info on how to scrub these hidden links from my database. One problem…the piece of search code for MySQL that you provided isn’t working in my version the database. I looked at the MySQL site, but that stuff is like to Chinese to me…I’m a beginner. Can you advise what the proper query terms would be for MySQL 5.0? You’d be a life saver! Thanks!
-M
Hi Marlee,
I am not sure what the problem is or what the solution would be without seeing your db. But, to be honest, I am not a MySQL master anyway. I am able to find the answers I need to most issues and wanted to pass this one on but I wouldn’t know the answer to that off the top of my head. Sorry ;(
No prob! Thanks Marty. If I find out, I’ll post it.