编写PHP Web服务时的安全性?

时间:2010-06-02 21:01:24

标签: php web-services httpwebrequest

我是第一次用PHP编写Web服务并遇到了一些安全问题。

1)我打算在将密码写入数据库(或验证用户)之前使用md5()散列密码但我意识到要这样做,我必须以明文形式将密码传输到服务器并且在那里哈希。
因为这个我想到md5()用javascript客户端进行,然后在服务器上重新进行,但是如果javascript被禁用,那么用户无法登录,对吧?

2)我听说过任何操作只读时,你应该使用GET,但是如果它修改了数据库,你应该使用POST。是不是像GET一样透明,只是不在地址栏中?

2 个答案:

答案 0 :(得分:5)

通常不建议您实现自己的哈希图层。如果您只是为了学习目的而做一个非常小的网站,我肯定md5会没问题,但如果您要为更大的网站存储重要信息,您应该使用库,例如​​PHPass

感谢Jacco提供的PHPass代码片段:

require('PasswordHash.php');

$pwdHasher = new PasswordHash(8, FALSE);

// $hash is what you would store in your database
$hash = $pwdHasher->HashPassword( $password );

// $hash would be the $hashed stored in your database for this user
$checked = $pwdHasher->CheckPassword($password, $hash);
if ($checked) {
    echo 'password correct';
} else {
    echo 'wrong credentials';
}

如果你坚持自己做,你应该加密密码。请参阅http://phpsec.org/articles/2005/password-hashing.html

define('SALT_LENGTH', 9);

function generateHash($plainText, $salt = null)
{
    if ($salt === null)
    {
        $salt = substr(md5(uniqid(rand(), true)), 0, SALT_LENGTH);
    }
    else
    {
        $salt = substr($salt, 0, SALT_LENGTH);
    }

    return $salt . sha1($salt . $plainText);
}

GET和POST之间差异的原因是浏览器解释请求的方式。如上所述,Web爬网程序不会执行POST请求。但想象一下,您访问了网站http://example.com/deleteuser.php?userid=25上的某个页面,删除了一个讨厌的垃圾邮件发送者。然后关闭浏览器。下次你回来时,firefox重新打开那个页面,你很遗憾地删除了刚刚注册的用户!

GET与POST的另一个原因是对cross-site request forgeries的部分预防。如果您有一个在GET请求中注销用户的页面,则有人可能会将图像标记嵌入到评论或论坛帖子中,如<img src="http://example.com/logout.php" />,并且浏览器将被强制执行注销操作。因此,任何查看该页面的用户都将被注销,即使他们是管理员。

编辑:顺便说一下,你应该使用sha-256或bcrypt而不是md5,它已被破解(?)。

答案 1 :(得分:1)

  

1)我打算在将密码写入数据库(或验证用户)之前使用md5()散列密码但我意识到要这样做,我必须以明文形式将密码传输到服务器并且哈希吧。

     

因为这个我想到md5()用javascript客户端然后在服务器上重新进行,但是如果javascript被禁用,那么用户无法登录,对吧?

散列密码的重点是减少数据库暴露的后果。如果您在客户端哈希,则只需更改客户端必须发送的一个字符串以获取其他字符串。这毫无意义。

  

2)我听说过任何操作只读时,你应该使用GET,但是如果它修改了数据库,你应该使用POST。是不是像GET一样透明,只是不在地址栏中?

抓取工具(包括搜索引擎索引器)不会发出POST请求。浏览器通常会警告用户重新提交POST数据。

使用POST和GET来做正确的事情不是安全问题。