Hide once & for all the only file that handles logins – wp-login.php

I’ve tried to solve this issue for months now, every solution I’ve found is not working properly or is just easy to pass.

Rules:

Read More
  • Users can login, register, use lost password etc on front-end – got that covered!
  • Every direct access to wp-admin, admin, wp-login, login should show 404 or redirect to home

What I’ve tried & failed (maybe did something wrong) or think of trying:

  • Copy-paste & rename wp-login.php, then use wp_login and wp_login_url to make all those actions thro this file – not sure if other WP functionalities need “wp-login.php” to work properly

  • Make a function to functions.php that checks if “secret string” is added to the end of URL, redirect others or show 404

  • Just ordinary redirect

  • Tried different plugins

  • Read & tried atleast 50 .htaccess codes found online (not kidding)

Problems I’ve had:

  • Ordinary redirection: unable to login or logout

  • How all plugins have worked: only hides wp-login.php, you can still use login, admin & wp-admin

  • .htaccess outcomes so far: added “link” only redirects to wp-login.php but by all means doesn’t hide it, change it or replace wp-login with the new “link” in URL


What almost worked:

//Don't Let Users To Login Page
function example_simple_query_string_protection_for_login_page() {

   //Secret string
   $QS = '?secret=1';

   $theRequest = 'https://' . $_SERVER['SERVER_NAME'] . '/' . 'wp-login.php' . '?'. $_SERVER['QUERY_STRING'];

  if ( site_url('/wp-login.php').$QS == $theRequest ) {
      //Shows WP login page
  } 

  else {
      //Redirects to home page
      header( 'Location: https://' . $_SERVER['SERVER_NAME'] . '/' );

      //Shows 404 - Doesn't work as expected!!
      //include( get_query_template( '404' ) );
  }
}

 add_action('login_head', 'example_simple_query_string_protection_for_login_page');

Problems with it:

  • Didn’t find any good online solution how to force “real” 404!
  • User doesn’t get redirected if he/she goes to wp-admin or admin – instead he/she gets 403 Forbidden errror and ugly WP restricted access screen!

My code that handles this but doesn’t work for some reason:

//Disable wp-admin For Non-Admins If Not Running AJAX Or Updating User Data
function disable_wp_admin_for_non_admins() {
  if ( !current_user_can('manage_options') &&  $_SERVER['DOING_AJAX'] != '/wp-admin/admin-ajax.php' && !ajax_add_remove_favorites() && !ajax_update_user_profile_function() ) {
    wp_redirect( home_url() ); 
    exit;
  }
}
add_action('admin_init', 'disable_wp_admin_for_non_admins');

QUESTIONS: need only 1 that works!

  • Would copy-paste-rename wp-login theoretically work Or does other functions need that name?
  • Once and for all, can you achieve what I want with .htaccess?
  • How to get my code to work? (show 404 and don’t show 403 to logged in users)
  • Is there any other solution that would work but Im not aware of it?

Related posts

2 comments

  1. I had to throw a 404 error on another project recently. Not sure of the best filter/action to wrap this in, but I used parse_request.

    add_action('parse_request', 'prevent_wp_login_access');
    
    function prevent_wp_login_access() 
    {
        global $wp_query;
    
        //check to see if the page is wp-login.php
        //if so
        //force 404
        $wp_query->set_404();
        status_header(404);
        require TEMPLATEPATH.'/404.php';
        exit;
    }
    

    You could also try wrapping it in the init action, and throwing your own header() if the $wp_query object is not available yet.

    Just a thought.

  2. I have tested the following for preventing access to wp-login.php. It accounts for logouts as well, so shouldn’t give you an issues. Not sure if it will play nicely with other aspects of WP.

    add_action('init', 'prevent_wp_login_access');
    
    function prevent_wp_login_access() 
    {
        global $pagenow;
    
        if( isset($_GET['action']) && $_GET['action'] == 'logout' )
            return;
    
        if( 'wp-login.php' == $pagenow ) {
            wp_redirect( get_option('siteurl') );
            exit;
        }
    
    }
    

Comments are closed.