'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_cookiewp_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.