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的正则表达式

正则表达式对于输入值的验证非常方便。

関数説明perg文字エンコーディングがUTF-8の場合のみ日本語が使えるmb_ereg様々な文字エンコーディングに使える

匹配包含1至5个字符的英文字母和数字的正则表达式。

preg_match('/A[a-z0-9]{1,5}\z/ui',$p);

这段文字的来源是《体系的学习 安全的Web应用程序构建方法 第2版[固定版] 生产脆弱性的原理和对策实践》。

名前説明u修飾子UTF-8エンコーディングであることを示す。i修飾子大文字小文字を区別しない

在某些情况下,可能不需要使用u修饰符。然而,由于正则表达式中的”.”可能导致意外结果,所以最好始终指定u修饰符。

我们用\A和\z来表示整体一致。

数据的开始由\A表示,数据的结尾由\z表示。
^和$表示行的开始和结尾,所以$可以匹配换行符。
因此,将^和$用作数据的开始和结尾可能会导致故障发生。

引用资料

    体系的に学ぶ 安全なWebアプリケーションの作り方 第2版[固定版] 脆弱性が生まれる原理と対策の実践
广告
将在 10 秒后关闭
bannerAds