I have a website for which we are trying to be discreet about the fact that we are using WordPress. What steps can we take to make it less obvious?

EDIT- Important security note:

Please understand that doing this perfectly is impossible as per Mark's answer, so don't rely on this as a security measure.

  • 6
    Why would you want to hide that you're using Wordpress? – Wadih M. Sep 10 '10 at 16:24
  • 14
    @Wadih: Because I was told to – Casebash Sep 11 '10 at 11:47
  • 5
    That's security by obscurity. If they really want, someone can correlate the behavior of page generations and prove that it's running on a wordpress engine. – Wadih M. Sep 20 '10 at 16:57
  • 28
    @Wadih M. - "Security by Obscurity" is not the only reason for this. One of my clients wants the same but they want it because they want to be able to sell their hosted services to clients who would balk it paying top dollar if they thought "Heck, they are just using WordPress." So it's a branding/perception game, not a security one, at least for my client. – MikeSchinkel Oct 24 '10 at 7:25
  • 2
    Six years on so many sites are using WordPress, no-one is going to believe you anyway. ;-) – cjbj Aug 22 '16 at 12:33

13 Answers 13

up vote 123 down vote accepted

The biggest WordPress giveaways are between the <head> </head> tags.

Example WordPress head content output by The Twentyten Theme and how to remove:

<link rel="profile" href="http://gmpg.org/xfn/11" /> 

Remove directly from header.php

 <link rel="stylesheet" type="text/css" media="all" href="http://example.com/wp-content/themes/twentyten/style.css" /> 

Hide WordPress by calling your stylesheet from another location and change the wp-content directory. WordPress requires your theme to include some basic information at the top of style.css (style.css must be in the themes root directory). You will need to create an alternate CSS and call it from your head. WordPress does not require you to use the themes style.css it only requires it to be in the themes directory.

Remove directly from header.php

<link rel="alternate" type="application/rss+xml" title="Example Blog &raquo; Feed" href="http://example.com/feed/" /> 
<link rel="alternate" type="application/rss+xml" title="Example Blog &raquo; Comments Feed" href="http://example.com/comments/feed/" />    
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://example.com/xmlrpc.php?rsd" /> 
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://example.com/wp-includes/wlwmanifest.xml" /> 
<link rel='index' title='Example Blog' href='http://example.com/' /> 
<meta name="generator" content="WordPress 3.1-alpha" /> 

To remove these extra links you can add a filter to functions.php

// remove junk from head
remove_action('wp_head', 'rsd_link');
remove_action('wp_head', 'wp_generator');
remove_action('wp_head', 'feed_links', 2);
remove_action('wp_head', 'index_rel_link');
remove_action('wp_head', 'wlwmanifest_link');
remove_action('wp_head', 'feed_links_extra', 3);
remove_action('wp_head', 'start_post_rel_link', 10, 0);
remove_action('wp_head', 'parent_post_rel_link', 10, 0);
remove_action('wp_head', 'adjacent_posts_rel_link', 10, 0);

You can change your plugin directory and your wp-content directory in your wp-config.php file but you could have some problems if your theme or any plugins do not use the proper method to call files.

define( 'WP_CONTENT_DIR', $_SERVER['DOCUMENT_ROOT'] . '/new-wp-content' );

Set WP_CONTENT_URL to the full URI of this directory (no trailing slash), e.g.

define( 'WP_CONTENT_URL', 'http://example/new-wp-content');

Optional Set WP_PLUGIN_DIR to the full local path of this directory (no trailing slash), e.g.

define( 'WP_PLUGIN_DIR', $_SERVER['DOCUMENT_ROOT'] . '/new-wp-content/new-plugins' );

Set WP_PLUGIN_URL to the full URI of this directory (no trailing slash), e.g.

define( 'WP_PLUGIN_URL', 'http://example/new-wp-content/new-plugins');

PLUGINS

Be aware that some plugins like Akismat, All in One SEO, W3-Total-Cache, Super Cache, and many others add comments to the HTML output. Most are easy to modify to remove the comments but your changes will be overwritten anytime the plugins get updated.

wp-includes

The wp-includes directory holds jquery and various other js files that themes or plugins will call using wp_enqueue_script(). To change this you will need to deregister the default WordPress scripts and register the new location. Add to functions.php:

function my_init() {
    if (!is_admin()) {
        // comment out the next two lines to load the local copy of jQuery
        wp_deregister_script('jquery');
        wp_register_script('jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js', false, '1.3.2');
        wp_enqueue_script('jquery');
    }
}
add_action('init', 'my_init');

This will need to be done with each script used by your theme or plugins.

  • Chris_O: Great answer! You should probably add too that if they use plugins or themes many of these are easily identified; i.e. if someone is using the akismet plugin or all-in-one-seo then it's still a pretty dead giveaway by someone who knows what they are look for. – MikeSchinkel Sep 8 '10 at 17:02
  • @MikeSchinkel True, but at the same time, so are wp-includes and wp-admin; with the exception that you can't change either of those, nor can you hide them without limiting the functionality of the site. – John P Bloch Sep 8 '10 at 20:28
  • @John P Bloch: Definitely, however I wouldn't have said but, I would have said and. :) – MikeSchinkel Sep 9 '10 at 0:44
  • 3
    @MikeSchinkel: for wp-admin and wp-includes you can do some stuff via apache access control, so to make those paths inexistent for other users then the admin, e.g. leading to a standard 404. – hakre Sep 9 '10 at 1:59
  • @Chris_O: Checkout register_theme_directory(), I think it's great to hide the theme dir out of the "wp-content" directory. – hakre Sep 10 '10 at 16:50

One bit that is often missed - delete readme.html in WordPress root. It not only identifies installation as WP but also has precise version. And don't forget to repeat on updates.

Related Question: Prevent access or auto-delete readme.html, license.txt, wp-config-sample.php

I've always used the Roots Theme method.
But applying it to those ThemeJungle's out there is usually a big headache.

So, started to play with the WP_CONTENT_* constants. Which I believe is a much less error prone method and this is what I have working right now:

safari activity window
/m is the uploads folder, /t is the themes folder and /t/t is the active theme folder. The site is not complex, so few assets loaded...


WP_CONTENTLESS

wp-config.php

Setting wp-content to the root (/public_html/) of the site.

/** 
 Inside WP_CONTENT, the following folders should exist: 
 /languages , /mu-plugins , /plugins , /themes , /upgrade , /uploads  

 The WP_CONTENT_* definitions bellow REMOVE the existence of the /wp-content folder 
 and makes its contents reside in the ROOT of your site

 UTTERMOST attention is necessary when doing file maintenance activities in the server (i.e.: WP upgrades, new Webmaster...), 
 as the Themes and Plugins folders are meant to be renamed to /t and /p (serious candidates for unthoughful removal)

 PLEASE note:
 - we change the Plugins folder in WP_PLUGIN_* definitions
 - the Themes folder is changed by a MustUse Plugin 
   (/mu-plugins/set-extra-themes-folder.php)
 - the Uploads folder is changed in WordPress settings page 
   (http://example.com/wp-admin/options-media.php)
 - the hardcode path to be used in WP_CONTENT_DIR and WP_PLUGIN_DIR can be checked using an action inside the set-extra-themes-folder Plugin (check the comments in this file)
*/
define( 'WP_CONTENT_DIR', '/www/htdocs/username/public_html' );
define( 'WP_CONTENT_URL', 'http://www.example.com' );

define( 'WP_PLUGIN_DIR', '/www/htdocs/username/public_html/p' );
define( 'WP_PLUGIN_URL', 'http://www.example.com/p' );

I've asked about it in [wp-hackers] - Any drawbacks in setting WP_CONTENT_DIR (and URL) to DOCUMENT_ROOT?, where John Blackbourn1, Mike Little2 and Otto3 were kindly enough as to advise:

1
I've had this structure active on a site for the last 18 months and haven't seen any problems. As with any change to the location of the content directory, you'll need to double check any plugins you add to the site don't assume that the content directory is at wp-content.

2
There are discussions around the net the $_SERVER['DOCUMENT_ROOT'] may be susceptible to hacking. In which case this is extremely dangerous because there are lots of places that require() or include() WP_CONTENT_DIR . 'something';

3
There are cases where the content in $_SERVER can be perfectly safe, but for security purposes, it is better to always treat it as untrusted data. For this specific case, hardcode the directory.


A New Themes Folder

/mu-plugins/set-extra-themes-folder.php

As there's no WP_THEMES_* constants, we need the function register_theme_directory() to "Register a directory that contains themes."
Tried to set the extra directory to the root but the results are funny (i.e.: it doesn't work).

<?php
/*
    Plugin Name: Set Extra Themes Folder
    Version: 1.0
    Description: Allows the directory - http://example.com/t - to be used as an extra theme's directory
    Plugin URI: http://wordpress.stackexchange.com/questions/1507
    Author: brasofilo
    Author URI: http://rodbuaiz.com
*/


/**
 * Remove the comment from the following line to know the correct path to put in register_theme_diretory()
*/
//add_action( 'admin_head', 'brsfl_alert_directory_path' );

function brsfl_alert_directory_path()
{
    echo '<script type="text/javascript">
        alert("Directory: '.$_SERVER['DOCUMENT_ROOT'].'");
    </script>';
}


/**
 * The following will enable the directory "t" to be used as an EXTRA Themes directory
*/
register_theme_directory( '/www/htdocs/username/public_html/t' );


/**
 * De-registering default scripts in wp-includes for CDN ones
*/
add_action('init', 'brsfl_init_scripts');

function brsfl_init_scripts() 
{
    if ( !is_admin() ) 
    {
        wp_deregister_script( 'jquery' );
        wp_deregister_script( 'swfobject' );
        wp_register_script( 'jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js', false, '1.7.1' );
        wp_register_script( 'swfobject', 'https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js', false, null, true );
        wp_enqueue_script( 'jquery' );
        wp_enqueue_script( 'swfobject' );
    }
}

Uploads Folder

/wp-admin/options-media.php

Instead of http://example.com/uploads, it'll be http://example.com/m.
Unchecking Organize my uploads into... will give a WPless appearance to the assets URLs.
If the site is live, a search/replace must be done in the database and files must be moved around.
uploads folder settings


Plugins and Head Content

Refer to Cris_O Answer in this Q&A.


Readme.html

Refer to Rarst Answer in this Q&A.


Other Steps

As usual, ThemeJungle themes may prompt specific hacks in the theme.
Like... TimThumb not working (!!!lol!!!).

You can have WordPress on one server and scrape your content from another only including the content you need.

If you need RSS your would have to do the same with that.

Effectively it would be like serving static pages from a proxy or CDN, but only the bits you want to serve. You could then also just use a javascript based comment system such as Disqus.

Really low resource use, becaue here are no databases on the server serving the content.

  • @AndyBeard - That's very much an interesting idea, but it would require lots of development time to get something workable. Or do you know of an open source project where somebody has already done this? – MikeSchinkel Oct 24 '10 at 7:27
  • 3
    Here is one solution wordpress.org/extend/plugins/really-static - there are a few others – AndyBeard Oct 24 '10 at 14:56

The only valid answer: IMPOSSIBLE

So many high voted answers.... time to set the record straight. Well, the truth is that it is virtually impossible and even if it is,life is probably too short to put an effort into it. Any answer, that promotes steps to hide WP is just a waste of your time and will mislead you thinking that you are hiding your WP (that is absurd).

1) The problem is not the obvious wp-* urls, the generator meta etc. The hard problems are with patterns that are associated with wordpress that an home grown system will not bother to implement like author pages, year,month,day pages, use p=nnn as a valid parameter, have comment form with the wordpress comment class, structure and link names, and then there is the self promotion of the caching plugins and yoast SEO and probably many other plugins that you see only when you inspect the HTML itself.

2) There are other uncounted methods that shows the existence of WP (and you can't beat that):

  • Even the php response-header (as noted by Dan Gayle below my answer) returns the specific WP header.

  • Anyone can just query any of tens root .php files: site.com/wp-cron.php or site.com/xmlrpc.php (or etc, which you cant hide) and the header answer will be 200 instead of 404 not found.

  • anyone can check has json endpoints to get WP specific answer.

  • Inside the page HTML, many of .css or .js file has a specific phrases, that clearly refers to WP.

  • Inside the page HTML, its easy to find the elements/css classes, like <div class="entry-content post-14"... or etc (which is a direct hint that used structure is of WP)

  • Inside the page HTML, you will easily see the uploads folder, or even if you rename that with hardcoding, then the date part like uploads/2018/05/image.jpg (or even image-315x225.jpg) shows the typical WP structure.

  • as many sites now are built using MultiSite, it uses i.e. /site/2 in links...

  • ping to any plugins/themes readme (all of them contains), like plugin-name/readme.txt, returning status 200.

  • and many, many, many other things that you (or even professionals) will be unable to hide and will just waste your days!


conclusion

And even if you put the effort into cleaning up everything indicating that this is a wordpress, you might need to redo or at least recheck after every plugin or core upgrade. Life is just too short for that.

You might mislead some diletants, but you can't hide from a good inspector. If this is done as a security measure then it is security by obscurity which is always wrong, and if you are just ashamed of using wordpress, then let me tell you something - no one cares, and even the very few that do probably will not know how to figure it out by themself.

The only thing you should care, is that you protect WP as much as you can and monitor it's regular updates.

  • the only correct answer, i wanted to post that. I've downvoted all other answers, as they are just misleading, time-wasting tryout to achieve the impossible and nonsense goal. If you allow me, i will add 2 cents within your answer. – T.Todua Oct 13 at 17:56
  • sure, go ahead. – Mark Kaplun Oct 14 at 0:02
  • I also voted this up. It wasting time hiding wp just for security by obscurity. It's not only not going to work, but it could also potentially break functionality done wrong. – Remzi Cavdar Oct 24 at 18:18

You can create your custom address to login to your blog. By not using the classic “myblog.com/wp-admin” path to get to your dashboard This page will help you with creating stealth logins, this is also good for security measures.

So the ppl who append wp-admin to your blog, won't be able to guess :)

In addition to the above, you need to lock down access to the various wp* files and directories. If someone wanted to see if you were running WP they could guess to see if you had wp-settings.php or if they could access some directory. Returning a 403 isn't sufficient because it tells the user that the resource exists; they just don't have access to it.

I'm not an apache expert so I asked this question over on serverfault.

Don't forget that a lot of the http header information that is sent along with your request can identify your site as running on WordPress. For example, if you check the headers on the following sites, it's obvious:

$ curl -I http://www.rollingstones.com/
Server: WP Engine/5.0

$ curl -I http://www.mattcutts.com
X-Powered-By: W3 Total Cache/0.9.1.3

$ curl -I http://blogs.reuters.com/us/
WP-Super-Cache: Served supercache file from PHP

Some of those are set by the server, some are set by plugins, so there's no one way for me to say how to remove 100% of them, but if you're using PHP 5.3 you can use

header_remove("X-Foo"); (http://www.php.net/manual/en/function.header-remove.php)

to remove a known PHP header before your content is being shoved out. I can't say for a certainty where to place this (maybe someone else can pitch in with that info), but it's probably safe to put it at the very top of your index.php BEFORE any content that is sent to the browser.

This can be hard to achieve if you are new to php and mod_rewrite. I suggest so you check with the section of my response. Or try it yourself, you can use something like this to hide the wp-content/plugins path structure:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^modules/(.*) /wp-content/plugins/$1 [L,QSA]
</IfModule>

This will change the path to /modules . Use something similar for other structure, you may need some advanced rewrites, see http://httpd.apache.org/docs/current/mod/mod_rewrite.html for additional mod_rewrite information's.

If prefer something out of the box, there are few nice plugins, some commercial, also free at WordPress repository, i suggest to try WP Hide & Security Enhancer. This include lot's of things and help to change pretty much everything to make your WordPress unrecognizable. Here are some features of the code:

  • Custom Admin Url
  • Custom Admin Url
  • Block default admin Url
  • Block any direct folder access to completely hide the structure
  • Custom wp-login.php filename
  • Block default wp-login.php
  • Block default wp-signup.php
  • Block XML-RPC API
  • New XML-RPC path
  • Adjustable theme url
  • New child Theme url
  • Change theme style file name
  • Custom wp-include
  • Block default wp-include paths
  • Block defalt wp-content
  • Custom plugins urls
  • Individual plugin url change
  • Block default plugins paths
  • New upload url
  • Block default upload urls
  • Remove wordpress version
  • Meta Generator block
  • Disble the emoji and required javascript code
  • Remove pingback tag
  • Remove wlwmanifest Meta
  • Remove rsd_link Meta
  • Remove wpemoji

and many more..

I don't want to repeat the coding options since they have been exhaustively covered, the other option I know that works is using a plugin that hides wp. I have used this plugin before to satisfactory standards. Its called hide my WordPress.

Most answers concentrate on obscuring WordPress in the source code of a page, but even before that WP has already given itself away in the http header of a standard installation. Just try your own site on a site like web-sniffer (pretend to be IE 6 and ask for a http 1.0 header) and you will see that among the returns is:

<http://www.example.com/wp-json/>; rel="https://api.w.org/"

The latter is a link to the Wordpress.org API. It's there since the REST API was included in WP 4.4. You can remove it with this line right at the beginning of your functions.php:

remove_action( 'template_redirect', 'rest_output_link_header', 11, 0 );

Many plugins, like Jetpack for its shortlinks, may also insert links in the http header. They can do so, because WP has an HTTP API, which allows you to manipulate headers. You could use this interface to remove all header settings by plugins if you add your action late enough in the process.

Finally, you may use .htaccess header interface to intercept anything WP is doing. For instance, you can prevent any Link headers to be sent by including this line:

<IfModule mod_headers.c>
Header unset Link
</IfModule>

You can customize a theme to exclude all the WordPress information. Also remove meta widget and any widget that would output information about the platform.

Personally, I prefer to show my gratitude by displaying that I am using WordPress.

  • 17
    Gratitude is nice, but it doesn't answer the core question. – ZaMoose Sep 8 '10 at 16:46

You can Use plugin WPS Hide Login.
You login to your wordpress using wp-admin. But you can change wp-admin to custom using this plugin.

Example:

Before: http://example.com/wp-admin
After: http://example.com/custom-text-to-login

protected by fuxia Jun 1 '12 at 0:39

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.