Bypass password protected posts via GET variable

The check for a post password happens (for some reason) inside get_the_content(), which seems legit, but actually mixes together two separate concerns. You were right with the statement that there is no way to work around get_the_content() displaying the password form. Here’s what the check for the password does in core in detail:

if ( empty( $post->post_password ) )
     return false;

if ( ! isset( $_COOKIE['wp-postpass_' . COOKIEHASH] ) )
     return true;

require_once ABSPATH . WPINC . '/class-phpass.php';
$hasher = new PasswordHash( 8, true );
$hash = wp_unslash( $_COOKIE[ 'wp-postpass_' . COOKIEHASH ] );
if ( 0 !== strpos( $hash, '$P$B' ) )
     return true;
return ! $hasher->CheckPassword( $post->post_password, $hash );

As you can see, the password gets check against a Cookie stored at the users machine.

To circumvent the post password, you will actually have to give the user explicit permission by setting this cookie. Core does it the following way:

setcookie(
    'wp-postpass_' . COOKIEHASH,
    $hasher->HashPassword( wp_unslash( $_POST['post_password'] ) ),
    $expire,
    COOKIEPATH
);

when you look at the_post_password(), which is used to retrieve the (plain text password), then you will find that it does nothing aside from escaping the argument for the users safety:

esc_attr( $post->post_password )

Now you can combine this and set the Cookie before you display the content in your template:

// Your custom check for the `$_GET` content
// …also check if there in fact is a password
// …and if the user is a repeated visitor, do not set the Cookie again
if (
        isset( $_GET['circumvent'] ) 
        and 'disable-pass' === $_GET['circumvent'] 
        and isset( $post->post_password )
        and ! isset( 'wp-postpass_'.COOKIEHASH )
    ) {
    // Finally we use the plain text password to set the Cookie
    // as if the user would have entered it into the password form
    setcookie(
        'wp-postpass_'.COOKIEHASH,
        $hasher->HashPassword( wp_unslash( esc_attr( $post->post_password ) ) ),
        $expire,
        COOKIEPATH
    );
}
// Now display the content:
the_content();

Additional information about Post Passwords in this article I wrote as much of this concept is known very little and you might want to account for some of those details.

Leave a Comment