正确的方法来防止空字节注入与HTML/Javascript/PHP文本框


Correct method to prevent null byte injection with HTML/Javascript/PHP text box

我目前正在为一个web应用程序创建一个Javascript/HTML/PHP注册表单。我想使它尽可能安全,并且正在阅读空字节注入PHP。为了防止这样的事情,我是否正确地认为,我不需要允许特殊字符(空字节字符),如%&£#@?!等,从被选择作为密码时,用户注册?

用户输入他们的用户名和密码到两个HTML文本框,我有用户名检查我的数据库(与php脚本)与onBlur事件的用户名文本框,检查,看看用户名是否已经在数据库中使用,如果是,然后它禁用"注册"按钮,并提醒用户的问题。

我想对密码文本框做类似的事情。如果用户输入一个特殊字符的密码(例如,"我的密码!"),那么我想禁用"注册"按钮,并通知他们,密码必须只包含字母和数字。

这是防止空字节注入的正确方法吗?或者在PHP文件中允许特殊字符出现在密码中并进行某种检查是否同样安全?提前感谢您的帮助!

作为CW发布,因为它不是一个答案。@emily:要么他们修复了它(在PHP7上测试),要么评论是错误的:

php > echo password_hash("123'0456", PASSWORD_BCRYPT);
$2y$10$UQ7o/1ggpeqQYQaAPDQUxeAq0vPFJCenBJEzDFkcFXirrz6HC7N9.
php > var_dump( password_verify("123'0456", '$2y$10$UQ7o/1ggpeqQYQaAPDQUxeAq0vPFJCenBJEzDFkcFXirrz6HC7N9.'));
bool(true)
php > var_dump( password_verify("123", '$2y$10$UQ7o/1ggpeqQYQaAPDQUxeAq0vPFJCenBJEzDFkcFXirrz6HC7N9.'));
bool(false)

回复Marc B的帖子,难道你还不需要小心吗?看看如果我们使用'000作为NULL字节信号(PHP v7)会发生什么。

php > echo password_hash("123'000456", PASSWORD_BCRYPT);
$2y$10$GNQS2Wxj.L/5WukaOJEcxeOwgIgzug5BvCVvyVJOAUTkpfW2HiclO
php > var_dump( password_verify("123'000456", '$2y$10$GNQS2Wxj.L/5WukaOJEcxeOwgIgzug5BvCVvyVJOAUTkpfW2HiclO'));
bool(true)
php > var_dump( password_verify("123", '$2y$10$GNQS2Wxj.L/5WukaOJEcxeOwgIgzug5BvCVvyVJOAUTkpfW2HiclO'));
bool(true)
php > var_dump( password_verify("123'000NothingMattersPastTheNull!", '$2y$10$GNQS2Wxj.L/5WukaOJEcxeOwgIgzug5BvCVvyVJOAUTkpfW2HiclO'));
bool(true)

就我个人而言,当使用password_hash()/bcrypt时,我对密码进行了消毒,以包含大写字母和小写字母,所有数字都加上。!$^&*()[]@-_+,最多72个字符。这对于我的应用来说是完全没问题的,它不是存储核导弹代码。如果你在互联网上寻求答案,那么你可能不是在从事危及生命的信息的存储工作,所以上面的消毒措施可能也对你有用,你可以无视那些末日贩子告诉你的,你在冒着生命危险,到处说"你在减少熵!"

我很乐意使用我定义的字符集制作一个长度在8到72个字符之间的密码,并将password_hash()提供给"蛮力密码"竞赛,安全的是,它将需要一些严肃的高端硬件和大量时间来找到碰撞。将以上内容混合到良好的系统安全性中,通过TLS传输所有信息并防止其他常见问题,如使用准备好的语句进行注入攻击等,这样您就可以很好地拥有足够的安全性来阻止除了最确定的,国家赞助的活动之外的所有活动。