WordPress Author Enumeration Bot Probe Protection – Author ID, User ID

Home Forums BulletProof Security Pro WordPress Author Enumeration Bot Probe Protection – Author ID, User ID

This topic contains 6 replies, has 4 voices, and was last updated by Avatar of Brian Brian 8 months ago.

Viewing 7 posts - 1 through 7 (of 7 total)
  • Author
    Posts
  • #11090 Facebook Google Twitter Email Stumbleupon Digg reddit pinterest Myspace Delicious LinkedIn tumblr
    Avatar of AITpro Admin
    AITpro Admin
    Keymaster

    This WordPress Author Enumeration Bot Probe Protection Bonus Code protects against hacker Bot Probes looking for WordPress author enumeration (a numbered list of author ID’s / User ID’s) to exploit.  If you use the Query Strings below in your Browser’s address bar you will see the author / username associated with the author ID / User ID displayed in your Browser.  After adding this WordPress Author Enumeration Bot Probe Protection code you will no longer see the author ID / User ID displayed in your Browser and instead will see a standard WordPress 404 Error and the Query String for the author ID that you queried will be displayed in your Browser’s address bar.  What is especially nice about this code is that to the hacker bot it appears that this author ID does not exist without giving any clues that the author ID does actually exist on your website.

    Note:  This code does not work on a WordPress GWIOD (Giving WordPress Its Own Directory) website.  This issue is being looked into.

    Replace this Forum website’s domain URL with your actual website’s domain URL for testing.

    http://forum.ait-pro.com/?author=1
    http://forum.ait-pro.com/?author=2
    http://forum.ait-pro.com/?author=3

    1.  Copy this WordPress Author Enumeration Bot Probe Protection code below into this BPS Root Custom Code text box:  

    # WP AUTHOR ENUMERATION BOT PROBE PROTECTION
    # Redirects to author=999999 that does not actually exist
    # which results in a standard 404 error. To the hacker bot
    # it appears that this author does not exist without giving
    # any clues that the author does actually exist.
    
    RewriteCond %{QUERY_STRING} ^author=([0-9]){1,}$ [NC]
    RewriteRule ^(.*)$ $1?author=999999 [L]

    2.  Click the Save Root Custom Code button.

    3.  Go to the Security Modes page, click the Create secure.htaccess File AutoMagic button and activate Root folder BulletProof Mode again.

    #11100 Facebook Google Twitter Email Stumbleupon Digg reddit pinterest Myspace Delicious LinkedIn tumblr
    Avatar of Young Master
    Young Master
    Participant

    What if you have a website with more than 999999 users, then it means that that code will not work. Right? Or is there any other way for websites with more than 999999 users?

    #11102 Facebook Google Twitter Email Stumbleupon Digg reddit pinterest Myspace Delicious LinkedIn tumblr
    Avatar of AITpro Admin
    AITpro Admin
    Keymaster

    What would happen is that the redirect would actually work instead of causing a natural 404 error.  If a hacker bot query was made using /?author=999999 and author ID 999999 actually really exists then the author name / User name for user 999999 would be displayed.  If a website actually has 999999 user accounts and a hacker bot did ever actually query author ID 999999 then the site owner could change 999999 to 9999999, etc.

    #11229 Facebook Google Twitter Email Stumbleupon Digg reddit pinterest Myspace Delicious LinkedIn tumblr
    Avatar of Tim
    Tim
    Participant

    I implemented this on a site, worked perfectly. But it also dawned on me that a smart bot could just crawl our author archive links (which we have on posts), and pull the ID from the body class.

    My solution was to simply remove the author IDs from the body class via my theme’s functions.php. Note: If you use author-# for styling purposes, you can’t do this, but the author-username slug is also there for styling if needed.

    Hopefully this is ok to post here, as it’s not directly related to BPS Security, but I think it works nicely in conjunction with the .htaccess probe protection.

    function remove_author_id_from_body($classes)
    {
    	/* are we on an author archive page? */
    	if (is_author())
    	{
    		/* loop through all classes */
    		for($i=0;$i<count($classes);$i++)
    		{
    			/* find author ID, remove from array */
    			if (preg_match('/author-[0-9]/', $classes[$i]))
    			{
    				unset($classes[$i]);
    				break;
    			}
    		}
    	}
    	
    	return $classes;
    }
    add_filter('body_class', 'remove_author_id_from_body');
    #11231 Facebook Google Twitter Email Stumbleupon Digg reddit pinterest Myspace Delicious LinkedIn tumblr
    Avatar of AITpro Admin
    AITpro Admin
    Keymaster

    Yep we do something very similar on our sites.  ;)  Thanks for posting this code / info for other folks who should be doing the same thing and should use your code or similar code to do this same thing.  And we are looking at possible ways of blocking cURL or DOM scans in website source code.  ;)

    Also if folks want to additionally redirect Request URI’s to author links they can do something like this.

    http://wordpress.org/support/topic/what-file-permissions-are-needed-while-editing/page/2?replies=59#post-4877151

    RewriteCond %{QUERY_STRING} ^author=([0-9]){1,}$ [NC]
    RewriteRule ^(.*)$ $1?author=999999 [L]
    # Subfolder site Author URL redirect to Home page
    RedirectMatch 301 (?i)^/(.*)/author/(.*)$ http://www.example.com/subfolder-site/
    
    RewriteCond %{QUERY_STRING} ^author=([0-9]){1,}$ [NC]
    RewriteRule ^(.*)$ $1?author=999999 [L]
    # Root site Author URL redirect to Home page
    # On some web hosts the RedirectMatch rule above would need to be used even if the site is a root website
    RedirectMatch 301 (?i)^/author/(.*)$ http://www.example.com/
    #11262 Facebook Google Twitter Email Stumbleupon Digg reddit pinterest Myspace Delicious LinkedIn tumblr
    Avatar of Brian
    Brian
    Participant

    Great tip. There is also a plugin that does this – Display Name Author Permalink. Not sure if it also solves the problem Tim mentions?

    #11349 Facebook Google Twitter Email Stumbleupon Digg reddit pinterest Myspace Delicious LinkedIn tumblr
    Avatar of Brian
    Brian
    Participant

    The plugin above replaces the author permalink with the display name and generates a 404 if the name is called directly. Works nicely. Here’s the code. Would be nice if this could be done via the .htaccess code instead of the plugin (less chance for interruptions)?

    <?php
    /*
    Plugin Name: Display Name Author Permalink
    Plugin URI: http: //sivel.net/wordpress/display-name-author-permalink/
    Description: Replaces the username for author permalinks with the users display name. Returns a 404 if the author permalink using the actual username is used.
    Author: hallsofmontezuma, Matt Martz
    Author URI: http: //sivel.net
    Version: 1.1
    
    Copyright (c) 2009 Matt Martz (http: //sivel.net)
    Display Name Author Permalink is released under the GNU General Public License (GPL)
    http: //www.gnu.org/licenses/gpl-2.0.txt
    */
    
    class DisplayNameAuthorPermaLink {
    
    var $users = array();
    
    // Build an array of usernames and display names and increment duplicates for uniqueness
    function __construct() {
    $i = 1;
    foreach ( get_users() as $user ) {
    $display_name = $display_name = sanitize_title($user->display_name);
    if ( in_array(sanitize_title($user->display_name), $this->users) ) {
    $i++;
    $display_name .= "-$i";
    }
    $this->users[sanitize_title($user->user_login)] = $display_name;
    }
    add_action('pre_get_posts', array(&$this, 'switch_author'));
    add_filter('author_link', array(&$this, 'filter_author'), 10, 3);
    }
    // Switch the display name with the username so that we can populate the posts properly
    // If the username was used in the call do a 404 template redirection
    function switch_author() {
    if ( ! is_author() )
    return;
    $author_name = get_query_var('author_name');
    $key = array_search($author_name, $this->users);
    if ( $key ) {
    set_query_var('author_name', $key);
    $author = get_user_by('login', $key);
    set_query_var('author', $author->ID);
    } else {
    set_query_var('author_name', false);
    set_query_var('author', false);
    add_action('template_redirect', array(&$this, 'redirect_404'));
    }
    }
    
    // Replace the username in author links generated in the theme with the users display name
    function filter_author($link,$author_id,$author_nicename) {
    if ( array_key_exists($author_nicename, $this->users) )
    $link = str_replace($author_nicename,$this->users[$author_nicename], $link);
    return $link;
    }
    
    // redirect template to use 404 template
    function redirect_404() {
    include(get_404_template());
    die();
    }
    
    }
    
    // Instantiate the DisplayNameAuthorPermaLink class
    $DisplayNameAuthorPermaLink = new DisplayNameAuthorPermaLink();
Viewing 7 posts - 1 through 7 (of 7 total)

You must be logged in to reply to this topic.