Rimozione del nome utente dal cookie "wordpress_logged_in"


9

Sto lavorando con un cliente con alcune rigide misure di sicurezza. Dopo essere stato sottoposto a revisione di sicurezza, ci è stato comunicato che il nome utente memorizzato nel cookie di accesso, ad es

wordpress_logged_in[username]|[hash]

è qualcosa che deve essere rimosso. Poiché questa è una parte integrante del sistema di accesso, non sono sicuro di come rimuoverlo e mantenere comunque la sessione.

Risposte:


10

Breve introduzione

Dopo una rapida occhiata al codice sorgente di WP, penso di aver trovato la soluzione ...

WordPress utilizza due funzioni per impostare e analizzare i cookie di autenticazione:

  • wp_generate_auth_cookie
  • wp_parse_auth_cookie

C'è un filtro in wp_generate_auth_cookiechiamato auth_cookieche probabilmente potresti usare per cambiare il contenuto dei cookie, ma non c'è filtro all'interno wp_parse_auth_cookie, ma ...

Entrambe queste funzioni sono definite in pluggable.php, il che significa che è possibile scrivere le proprie implementazioni per loro e sovrascrivere quelle predefinite.

Soluzione

  1. Scrivi il tuo plugin (chiamiamolo Better Auth Cookie)
  2. Implementa le tue wp_generate_auth_cookiee le wp_parse_auth_cookiefunzioni all'interno di questo plugin.
  3. Attiva il tuo plugin.

Di seguito puoi trovare la mia implementazione di esempio (basata fortemente sulle versioni originali) di queste funzioni:

if ( !function_exists('wp_generate_auth_cookie') ) :
/**
 * Generate authentication cookie contents.
 *
 * @since 2.5.0
 *
 * @param int $user_id User ID
 * @param int $expiration Cookie expiration in seconds
 * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in
 * @param string $token User's session token to use for this cookie
 * @return string Authentication cookie contents. Empty string if user does not exist.
 */
function wp_generate_auth_cookie( $user_id, $expiration, $scheme = 'auth', $token = '' ) {
    $user = get_userdata($user_id);
    if ( ! $user ) {
        return '';
    }

    if ( ! $token ) {
        $manager = WP_Session_Tokens::get_instance( $user_id );
        $token = $manager->create( $expiration );
    }

    $pass_frag = substr($user->user_pass, 8, 4);

    $key = wp_hash( $user->user_login . '|' . $pass_frag . '|' . $expiration . '|' . $token, $scheme );

    // If ext/hash is not present, compat.php's hash_hmac() does not support sha256.
    $algo = function_exists( 'hash' ) ? 'sha256' : 'sha1';
    $hash = hash_hmac( $algo, $user->user_login . '|' . $expiration . '|' . $token, $key );

    $cookie = $user_id . '|' . $expiration . '|' . $token . '|' . $hash;

    /**
     * Filter the authentication cookie.
     *
     * @since 2.5.0
     *
     * @param string $cookie     Authentication cookie.
     * @param int    $user_id    User ID.
     * @param int    $expiration Authentication cookie expiration in seconds.
     * @param string $scheme     Cookie scheme used. Accepts 'auth', 'secure_auth', or 'logged_in'.
     * @param string $token      User's session token used.
     */
    return apply_filters( 'auth_cookie', $cookie, $user_id, $expiration, $scheme, $token );
}
endif;


if ( !function_exists('wp_parse_auth_cookie') ) :
/**
 * Parse a cookie into its components
 *
 * @since 2.7.0
 *
 * @param string $cookie
 * @param string $scheme Optional. The cookie scheme to use: auth, secure_auth, or logged_in
 * @return array Authentication cookie components
 */
function wp_parse_auth_cookie($cookie = '', $scheme = '') {
    if ( empty($cookie) ) {
        switch ($scheme){
            case 'auth':
                $cookie_name = AUTH_COOKIE;
                break;
            case 'secure_auth':
                $cookie_name = SECURE_AUTH_COOKIE;
                break;
            case "logged_in":
                $cookie_name = LOGGED_IN_COOKIE;
                break;
            default:
                if ( is_ssl() ) {
                    $cookie_name = SECURE_AUTH_COOKIE;
                    $scheme = 'secure_auth';
                } else {
                    $cookie_name = AUTH_COOKIE;
                    $scheme = 'auth';
                }
        }

        if ( empty($_COOKIE[$cookie_name]) )
            return false;
        $cookie = $_COOKIE[$cookie_name];
    }

    $cookie_elements = explode('|', $cookie);
    if ( count( $cookie_elements ) !== 4 ) {
        return false;
    }

    list( $user_id, $expiration, $token, $hmac ) = $cookie_elements;

    $user = get_userdata($user_id);
    $username = ( ! $user ) ? '' : $user->user_login;

    return compact( 'username', 'expiration', 'token', 'hmac', 'scheme' );
}
endif;

La mia versione di queste funzioni sostituisce user_logincon user_id. Ma dovrebbe essere un buon inizio per cambiarlo in qualcosa di ancora più complesso (ad es. Hash specifico dell'utente o qualcosa del genere).


Bella risposta. Anche se aspetterò fino all'ultimo giorno del mio periodo di ricompensa. :)
Platypus anonimo l'

Accetterò questo, anche se non lo testerò perché non ho più bisogno di questa soluzione. Hai chiaramente fatto molti sforzi per scavare alla radice del sistema, lo apprezzo molto :)
phatskat,

1
Sebbene questo approccio sia valido, dovresti essere consapevole che non offre più protezione. Il nome utente viene sostituito con l'ID utente, ma il nome utente può essere ottenuto dall'ID utente tramite una richiesta a example.com?author=123, che esegue un reindirizzamento canonico a un URL come example.com/author/john.
John Blackbourn,

1
@john leggi attentamente per favore. Ho già detto che puoi facilmente rendere molto più sicuro la memorizzazione di alcuni hash casuali nei cookie anziché nell'ID utente.
Krzysiek Dróżdż
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.