PHP安全相关
我写这篇文章是作为以下书籍的总结之一。
- 体系的に学ぶ 安全なWebアプリケーションの作り方 第2版[固定版] 脆弱性が生まれる原理と対策の実践
Web应用程序的输入是干什么
在输入处理中,对输入值进行以下处理。
a. 文字编码的有效性验证 → 为了防范使用文字编码的攻击进行对策
b. 文字编码的转换 → 由于HTTP消息和程序内部使用的编码不同,需要进行自动编码转换
c. 输入值的有效性验证 → 作为安全的预防措施
对文字编码进行验证
在PHP中可以使用mb_check_encoding函数。
文字编码的转换
在PHP中,可以通过php.ini文件进行配置,选择自动转换或明确转换的方式。
输入值验证 (rù lì zhí
二进制安全和零字节攻击
二进制安全
无论输入值是什么样的字节序列,都能正确处理。
典型情况下,它指的是即使出现了值为零的字节(空字节,在PHP语言中表示为\ 0),也能正确处理。
在C语言、Unix和Windows的API中,将null字节视为字符串的结束符号,因此对null字节特殊处理。
使用C语言开发的PHP有一个函数,它将空字节作为字符串的终点,从而截断其后的部分。
这样的函数被称为非二进制安全函数。
避免进行ereg检查
这个函数在 PHP 5.3.0 版本被标记为不再推荐使用,并在 PHP 7.0.0 版本被删除。
<body>
<?php
$p = $_GET['p'];
if (ereg('^[0-9]+$', $p) === FALSE) {
die('整数値を入力してください');
}
echo $p;
?>
</body>
来源:从《系统学习安全Web应用程序的构建方法第2版(固定版):脆弱性产生的原理和应对实践》中。
对于这段代码,通过以下方式访问可避免ereg:
?p=1%00
被回避的原因
URL中含有%00。这表示为空字节,即空字符,因为ereg函数不是二进制安全的函数,它会在遇到非0字节时判断字符串已结束。
只需要使用二进制安全的函数来开发应用程序,就可以应对空指针引用问题,但这很困难。
因为规范上不允许参数中包含空字节,就像文件名一样。
为了达到这个目的,可以在应用程序的入口处使用倍纳奇安全来检查输入值的字节流,并且如果存在字节流,则将其视为错误的方法。
检查控制符
控制字是指通常不显示换行、制表符等不可见字符,其中包括了空字节。
文字数量的检查
应该检查所有参数的最大字符数。
这样做在安全方面会更加保险。
因为长字符串经常被用于攻击。
PHP的正则表达式
正则表达式对于输入值的验证非常方便。
匹配包含1至5个字符的英文字母和数字的正则表达式。
preg_match('/A[a-z0-9]{1,5}\z/ui',$p);
这段文字的来源是《体系的学习 安全的Web应用程序构建方法 第2版[固定版] 生产脆弱性的原理和对策实践》。
在某些情况下,可能不需要使用u修饰符。然而,由于正则表达式中的”.”可能导致意外结果,所以最好始终指定u修饰符。
我们用\A和\z来表示整体一致。
数据的开始由\A表示,数据的结尾由\z表示。
^和$表示行的开始和结尾,所以$可以匹配换行符。
因此,将^和$用作数据的开始和结尾可能会导致故障发生。
引用资料
- 体系的に学ぶ 安全なWebアプリケーションの作り方 第2版[固定版] 脆弱性が生まれる原理と対策の実践