'wordpress_logged_in'쿠키에서 사용자 이름 제거


9

엄격한 보안 조치를 취한 고객과 협력하고 있습니다. 보안 검토를 마친 후 로그인 한 쿠키에 저장된 사용자 이름 (예 :

wordpress_logged_in[username]|[hash]

제거해야하는 것입니다. 이것이 로그인 시스템의 필수 부분이므로이를 제거하고 세션을 유지하는 방법을 잘 모르겠습니다.

답변:


10

짧은 소개

WP 소스 코드를 살펴본 후에 해결책을 찾았습니다 ...

워드 프레스는 인증 쿠키를 설정하고 파싱하기 위해 두 가지 기능을 사용합니다.

  • wp_generate_auth_cookie
  • wp_parse_auth_cookie

에서 필터가있다 wp_generate_auth_cookie라고 auth_cookie당신은 아마 쿠키의 내용을 변경하는 데 사용할 수있는,하지만 더 필터 내부가 없다 wp_parse_auth_cookie,하지만 ...

이 두 함수는 모두 pluggable.php에 정의되어 있습니다. 즉, 자체 구현을 작성하고 기본 기능을 덮어 쓸 수 있습니다.

해결책

  1. 나만의 플러그인을 작성하십시오 (더 나은 인증 쿠키라고합시다).
  2. 이 플러그인 내에서 자신 wp_generate_auth_cookie과 wp_parse_auth_cookie기능을 구현하십시오 .
  3. 플러그인을 활성화하십시오.

이러한 기능의 샘플 구현 (원래 버전을 기반으로 함)은 아래에서 찾을 수 있습니다.

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;

이 함수들의 내 버전은로 대체 user_login됩니다 user_id. 그러나 더 복잡한 것으로 바꾸려면 좋은 시작이되어야합니다 (예 : 사용자 특정 해시 또는 이와 유사한 것).


좋은 대답입니다. 현상금 기간의 마지막 날까지 기다립니다. :)
— Anonymous Platypus 5

더 이상이 솔루션이 필요하지 않으므로 테스트하지는 않지만이를 수락 할 것입니다. 당신은 분명히 시스템의 루트에 파고 들기 위해 많은 노력을 기울였습니다. 나는 노력에 감사합니다 :)
— phatskat

1
이 방법은 좋은 방법이지만 더 이상 보호 할 수 없음을 알아야합니다. 사용자 이름은 사용자 ID로 대체되지만에 대한 요청을 통해 사용자 ID에서 사용자 이름을 가져올 수 있습니다.이 요청 example.com?author=123은와 같은 URL로 정식 리디렉션을 수행합니다 example.com/author/john.
— John Blackbourn

1
@john 은주의 깊게 읽으십시오. 앞에서 언급했듯이 userID 대신 쿠키에 임의의 해시를 저장하는 것이 훨씬 안전합니다.
— Krzysiek Dróżdż
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.