Xóa tên người dùng khỏi cookie 'wordpress_logged_in'


9

Tôi đang làm việc với một khách hàng với một số biện pháp bảo mật nghiêm ngặt. Sau khi trải qua đánh giá bảo mật, chúng tôi đã được thông báo rằng tên người dùng được lưu trong cookie đã đăng nhập, vd

wordpress_logged_in[username]|[hash]

là một cái gì đó phải được loại bỏ. Vì đây là một phần không thể thiếu của hệ thống đăng nhập, tôi không chắc cách gỡ bỏ nó và vẫn duy trì phiên.

Câu trả lời:


10

Giới thiệu ngắn

Sau khi xem nhanh mã nguồn WP, tôi nghĩ rằng tôi đã tìm thấy giải pháp ...

WordPress sử dụng hai chức năng để đặt và phân tích cookie xác thực:

  • wp_generate_auth_cookie
  • wp_parse_auth_cookie

Có một bộ lọc wp_generate_auth_cookieđược gọi auth_cookiemà bạn có thể có thể sử dụng để thay đổi nội dung của cookie, nhưng không có bộ lọc bên trong wp_parse_auth_cookie, nhưng ...

Cả hai hàm này đều được định nghĩa trong pluggable.php, điều đó có nghĩa là bạn có thể viết các triển khai của riêng mình cho chúng và ghi đè lên các hàm mặc định.

Giải pháp

  1. Viết plugin của riêng bạn (hãy gọi nó là Cookie xác thực tốt hơn)
  2. Thực hiện của riêng bạn wp_generate_auth_cookievà các wp_parse_auth_cookiechức năng bên trong plugin này.
  3. Kích hoạt plugin của bạn.

Bạn có thể tìm thấy triển khai mẫu của tôi (dựa mạnh vào các phiên bản gốc) của các chức năng này bên dưới:

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;

Phiên bản của tôi của các chức năng này thay thế user_loginbằng user_id. Nhưng nó nên là một khởi đầu tốt để thay đổi nó thành một thứ thậm chí phức tạp hơn (tức là hàm băm cụ thể của người dùng, hoặc một cái gì đó như thế này).


Câu trả lời tốt đẹp. Mặc dù tôi sẽ đợi đến ngày cuối cùng của thời kỳ tiền thưởng. :)
Thú mỏ vịt ẩn danh

Tôi sẽ chấp nhận điều này, mặc dù tôi sẽ không thử nghiệm vì tôi không còn cần giải pháp này nữa. Bạn rõ ràng đã nỗ lực rất nhiều để đào sâu vào gốc của hệ thống, tôi đánh giá cao nỗ lực này :)
phatskat

1
Trong khi phương pháp này là một phương pháp tốt, bạn nên lưu ý rằng nó không còn được bảo vệ nữa. Tên người dùng được thay thế cho ID người dùng, nhưng tên người dùng có thể được lấy từ ID người dùng thông qua yêu cầu example.com?author=123, thực hiện chuyển hướng chính tắc đến một URL như example.com/author/john.
John Blackbourn

1
@john đọc kỹ nhé. Tôi đã đề cập, rằng bạn có thể dễ dàng làm cho nó an toàn hơn nhiều khi lưu trữ một số hàm băm ngẫu nhiên trong cookie thay vì userID.
Krzysiek Dróżdż
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.