Ourren

关注技术,记录生活.

Wordpress 安全机制研究

| 留言

最近抽了点时间把wordpress最新版的源码翻了翻,记录一下其中的安全机制,BTW:wordpress源码看着真的很蛋疼。

1、认证模块 涉及到wordpress认证安全方面的主要有认证方式,密码保存方式。其中密码保存方式又分为安装时管理员密码生成和后台添加用户。 首先,wordpress采用的是cookie方式认证,cookie生成过程相对比较复杂,salt多次加密且不是简单的随机数salt,默认采用MD5,当然也可以采用sha。 [code lang=“php”] $pass_frag = substr($user->user_pass, 8, 4); $key = wp_hash($user->user_login . $pass_frag . ‘|’ . $expiration, $scheme);//salt:用户名.密码8-12位|cookie时长.auth $hash = hash_hmac(‘md5’, $user->user_login . ‘|’ . $expiration, $key);////md5($opad . pack($pack, md5($ipad . $data))); opad ipad 都是key异或后的值 $cookie = $user->user_login . ‘|’ . $expiration . ‘|’ . $hash;[/code] 详细流程:wp_set_auth_cookie–>wp_generate_auth_cookie–>hash_hmac–>_hash_hmac 函数源码如下: [code lang=“php”]function wp_generate_auth_cookie($user_id, $expiration, $scheme = ‘auth’) { $user = get_userdata($user_id);

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

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

$cookie = $user->user_login . '|' . $expiration . '|' . $hash;

return apply_filters('auth_cookie', $cookie, $user_id, $expiration, $scheme);

}

function hash_hmac($algo, $data, $key, $raw_output = false) { return hash_hmac($algo, $data, $key, $raw_output); }[/code] [code lang=“php”]function hash_hmac($algo, $data, $key, $raw_output = false) { $packs = array(‘md5’ => ‘H32’, ‘sha1’ => ‘H40’);

if ( !isset($packs[$algo]) )
    return false;

$pack = $packs[$algo];

if (strlen($key) > 64)
    $key = pack($pack, $algo($key));

$key = str_pad($key, 64, chr(0));

$ipad = (substr($key, 0, 64) ^ str_repeat(chr(0x36), 64));  //char(0x36)=6
$opad = (substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64));  //char(0x5c)=

$hmac = $algo($opad . pack($pack, $algo($ipad . $data)));

if ( $raw_output )
    return pack( $pack, $hmac );
return $hmac;

}[/code] 其次,安装时生成管理员密码时,采用的是salt md5加密。函数调用流程如下。 函数流程:wp_create_user–>wp_insert_user–>wp_hash_password–>HashPassword–>crypt_private

创建用户时采用的加密方式是一样的,但是实现上有点区别,创建用户后生成激活码,然后激活用户。 函数流程:current_user_can–>wpmu_signup_user–>wpmu_activate_signup–>wpmu_create_user–>wp_create_user–>wp_insert_user–>wp_hash_password

加密方式中重要的函数如下: [code lang=“php”]function wp_hash_password($password) { global $wp_hasher;

if ( empty($wp_hasher) ) {
    require_once( ABSPATH . 'wp-includes/class-phpass.php');
    // By default, use the portable hash from phpass
    $wp_hasher = new PasswordHash(8, TRUE);
}

return $wp_hasher->HashPassword($password);

}[/code] [code lang=“php”] function HashPassword($password) { $random = ‘’;

    if (CRYPT_BLOWFISH == 1 && !$this->portable_hashes) {
        $random = $this->get_random_bytes(16);
        $hash =
            crypt($password, $this->gensalt_blowfish($random));
        if (strlen($hash) == 60)
            return $hash;
    }

    if (CRYPT_EXT_DES == 1 && !$this->portable_hashes) {
        if (strlen($random) < 3)
            $random = $this->get_random_bytes(3);
        $hash =
            crypt($password, $this->gensalt_extended($random));
        if (strlen($hash) == 20)
            return $hash;
    }

    if (strlen($random) < 6)
        $random = $this->get_random_bytes(6);
    $hash =
        $this->crypt_private($password,
        $this->gensalt_private($random));
    if (strlen($hash) == 34)
        return $hash;

    # Returning '*' on error is safe here, but would _not_ be safe
    # in a crypt(3)-like function used _both_ for generating new
    # hashes and for validating passwords against existing hashes.
    return '*';
}[/code]

2、过滤模块 过滤模块这里主要想谈防注入、跨站、文件名攻击这几个方面。 首先看防注入方式,wordpress里面有地方会采用过滤后采用addslashes进行转义,但是有一个封装得比较好的转义方式是,采用vsprintf方式进行变量输入,然后过滤编码,最后通过判定mysql类型进行mysql_real_escape_string或者进行addslashes转义。 一个较为复杂的流程:select–>wpdb::prepare–>vsprintf–>escape_by_ref–>_real_escape–>mysql_real_escape_string/addslashes

其次防跨站方式采用了两种方式:普通文本过滤方式和富文本过滤方式。普通文本过滤方式采用htmlspecialchars进行过滤,富文本则采用自定义函数wp_specialchars_decode进行操作。 具体流程:esc_html–>_wp_specialchars–>htmlspecialchars/wp_specialchars_decode

最后文件名这块通过过滤文件名中的特殊字符和文件信息进行操作。 $special_chars = array(“?”, “[”, “]”, “/”, “\”, “=”, “<”, “>”, “:”, “;”, “,”, “‘”, “”“, ”&“, ”$“, ”#“, ”*“, ”(“, ”)“, ”|“, ”~“, ”`“, ”!“, ”{“, ”}“, chr(0));

3、其他 wordpress的Hook机制:http://www.mrmu.com.tw/2011/10/10/wordpress-hook/