第3部分 PHP安全编程规范(9-12)

PHP内置过滤函数 (9.2)

1 SQL注入过滤函数 P175

  • addslashes()
  • mysql_real_escape_string()
  • mysql_escape_string()

它们的作用都是给字符串添加反斜杠 \ 来转义掉单引号 '、双引号 "、反斜杠 \ 以及空字符 NULL

addslashes()和mysql_escape_string()直接在敏感字符前加反斜杠,可能会存在宽字节注入绕过的问题,而mysql_real_escape_string()函数会考虑当前连接数据库的字符集编码,安全性更好,推荐使用。

2 XSS过滤函数 P176

  • htmlspecialchars()
  • strip_tags()

htmlspecialchars()函数的作用是直接将字符串中的特殊字符转化成HTML实体编码,如 & 转换成 &amp;" 转换成 &quot;' 转换成 &#039;< 转换成 &lt;> 转换成 &gt; ,可以抵御大多数XSS攻击。

strip_tags()函数用来去掉HTML及PHP标记,比如 <h1>XXXXXXXXXX</h1> 转换成 XXXXXXXXXX

3 命令执行过滤函数 P176

  • escapeshellcmd()
  • escapeshellarg()

escapeshellcmd()过滤字符:

&;|`*?~<>^()[]{}$\%
\x0A、\xFF
'"(仅在不成对的时候被转义)

escapeshellcmd()过滤方式:Windows在这些字符前面加上一个 ^ 符号。Linux在这些字符前面加上反斜杠 \

escapeshellarg() 给所有参数加上一对双引号,强制为字符串。

加密算法 (10)

什么是加密 P177

加密是指将明文直接可见的数据以特定的算法进行混淆,以保证数据的安全掩蔽性

加密一直是一个很热的话题,在密码学中占很大一块比例,目前常见的加密算法可以分为对称加密、非对称加密以及单向加密(哈希算法),这些加密算法大量运用在各种系统和应用中。

对称加密 (10.1)

在对称加密算法中常用的算法有DES、3DES、TDEA、Blowfish、RC2、RC4、RC5、IDEA、SKIPJACK、AES

  • 3DES
  • AES

非对称加密 (10.2)

  • RSA

单向加密/哈希算法 (10.3)

单向加密也就是不可逆算法,常见的有MD系列(MD4MD5)和sha1sha192sha256等。因为存在不可逆的性质,所以这类哈希算法通常用来保存密码和做数字签名。

王小云教授提出了密码哈希函数碰撞攻击理论,即模差分比特分析法,破解了包括MD5、SHA-1在内的5个国际通用哈希函数算法。

  • MD5
  • sha1

国内加密算法

(书上没有)

国家商用密码管理办公室制定了一系列的密码标准,包括SM1(SCB2)、SM2、SM3、SM4、SM7、SM9、祖冲之算法(ZUC)等等。

对称算法:SM1,SM4,SM7,祖冲之算法(ZUC)

非对称算法: SM2,SM9

哈希算法:SM3

验证码 (11.1) P187

验证码可以解决很多业务安全问题,比如撞库、垃圾注册,等等,可谓防御业务风险必备神器。

验证码有图片验证码、滑动验证码、短信/邮箱/电话、二维码等分类。

  • 图片验证码
  • 滑动验证码
  • 短信/邮箱/电话
  • 二维码

据保守估计起码有80%以上的验证码是存在可以爆破和简单识别的问题,设计一个有效的验证码尤为重要。

用户登录 (11.2)

用户登录是最常见的一个功能,登录就意味着权限授予,如果攻击者能任意登录管理员的账号,也就拥有了管理员的权限,更多的访问权限就能带来更多的安全问题,所以在登录的安全尤为重要。通常登录功能有以下几个需要关注的点。

撞库漏洞 P192

撞库漏洞是指登录口没有做登录次数限制,导致可以使用不同的用户及密码进行不断的登录尝试,以遍历用户密码,也可以理解为登录爆破。

撞库漏洞有以下3种情况:

  • 用户名和密码错误次数都无限制。这种情况是早期比较常见的,可以载入用户名和密码字典对登录口不断进行请求尝试。
  • 单时间段内用户的密码错误次数限制。之前有个“锁QQ”的茬儿,说的是QQ登录密码连续错误次数30次,就会被锁定QQ,就有人利用这个问题不断地去锁定别人的QQ。这种方式是基于账号可信认证,密码错误次数存在限制,认证的是账号。所以这种情况也是可以撞库的,只要我们有一个用户名列表,爆破完一个密码还不能登录就换一个用户,或者干脆基于社工库的密码来撞。
  • 单时间段内IP登录错误次数限制。比较典型的是discuz,就是基于IP来限制登录,当一个IP登录5次后还没有成功登录,则会被禁止该IP登录,不过discuz获取的是Client-IP存在绕过的问题。这种防御撞库的手段存在一个误杀的问题,如果出口IP里面还有一个大内网,比如企业网、学校网,这时候就会误杀其他用户。

针对撞库漏洞比较好的解决方案是使用登录验证码多因素认证,登录验证码有很多种,选择安全的验证方式也很关键,因为目前网络上还有专门提供人工打码的服务平台。

用户注册 (11.3) P194

淘宝有专门的风控团队,垃圾注册一直是比较头疼的问题,目前像贴吧、论坛、微博以及大部分的娱乐应用都有一些评论和投票功能,通过这些功能可以传播广告或者刷排名,于是就出现了商业机会,一些人开始写自动化注册机去发广告,导致社区质量下降,大部分的网站都是需要登录才能使用这些功能的,而登录的前提是有账号,所以注册账号这块拦截掉注册机是最好的防御点。

机器注册已经被拦截得差不多,现在恶意注册的诈骗团伙已经以低价向学生提供兼职注册服务,由学生人工注册账号,填写验证码。对于这样的注册方式,就只有用大数据来分析注册账号的电脑、IP以及注册人行为去防控。在注册这方面,淘宝已经加入了滑动人机识别,并且效果非常不错。

对于用户注册,需要有以下几个安全设计思路:

  • 设计验证码
  • 采集用户机器唯一识别码,拦截短时间内多次注册。
  • 根据账号格式自学习识别垃圾账号
  • 防止SQL注入漏洞XSS漏洞(常见)。

充值支付 (11.7) P200

关于支付漏洞主要有四种,分别是客户端可修改单价、总价和购买数量以及利用时间差多次购买,这里不再反复介绍,针对这四种情况的主要应对手法是:

  • 保证数据可信,商品单价及总价不可从客户端获取。
  • 购买数量不能小于等于0,也不能超过上限值65535(书上没有)。
  • 账户支付锁定机制,当一个支付操作开始就应该立马锁定当前账户,不能同时两个后端请求对余额进行操作。

远程地址访问 SSRF (11.9) P202

Wordpress、phpcmsd等众多应用都有访问远程地址获取资源的功能,这个功能产生的漏洞叫做SSRF(Server-Side Request Forgery),我们在QQ消息中发送网页链接的时候,会显示出网页的标题和部分内容,这就说明腾讯的服务器有去访问我们发送的这个链接,那如果腾讯没有做地址限制,我们在聊天框里面发送一个腾讯内网的一个地址,那它再去访问的时候我们就能知道这是一个内网的什么系统,造成信息泄露,甚至内网漏洞利用。

这类漏洞防御看起来好像没有什么难度,只要限制填写就可以,但是大部分厂商修复的时候应该不会考虑到短地址的问题,所以在修复之后仍然可以通过生成短链接来利用,建议修复的时候注意这点。

(以下内容书上没有)

  • SSRF是指服务器端请求伪造漏洞
  • SSRF攻击的目标一般是从外网无法访问的内部系统
  • SSRF可以对外网服务器所在的内网进行扫描

文件管理 (11.10) P205

文件管理功能本身就是一个高危功能,可以直接对服务器中的文件进行操作,包括上传、下载、修改、删除,如果权限管理不当,可能导致被黑客直接利用该功能写入webshell,实际上目前大多数上传webshell的方式确实是利用了文件操作功能。

一个文件管理功能为了保证安全,在满足业务需求的情况下,设计的时候应该遵循以下几个点:

  • 禁止写入脚本可在服务器端执行的文件。比如服务器能解析PHP,那么在设计文件管理这个功能的时候,就需要限制不能操作PHP扩展名的文件和PHP标签的代码。为什么说连代码标签也要限制?因为前端页面的都套用了HTML模板,大多是直接包含了HTML文件,如果我们直接在模板文件中插入PHP代码,最终也能执行。
  • 限制文件管理功能操作的目录。通常需要被管理的文件只有模板文件以及图片文件,所以我们可以在文件管理功能上限制只能操作这两个目录,目录不能从客户端提交,直接在代码中设置好即可,如果实在需要进行目录跳转的话,一定要禁止提交 ../ 以及 \.. ,避免越权操作其他目录。
  • 限制文件管理功能访问权限。之前我们已经说到文件管理功能本身就是一个非常敏感的功能,虽然是一个正常的功能,但是已经有一点后门的性质,所以对于这个功能的访问权限一定要进行严格的控制。
  • 禁止上传特殊字符文件名的文件。大多数应用都会对上传的文件进行展示,特别是对外开发的网盘类应用,这时候就要注意对上传的文件名进行检查,禁止文件名中有尖括号、单双引号等特殊字符,避免攻击者用文件名来进行XSS攻击。

文件/数据库备份 (11.13) P207

网站源码备份和数据库备份是非常常见的一个功能,也是非常容易出现安全问题的一个功能。

通常文件和数据库备份功能容易出现的问题有如下几种情况:

  • 未授权访问和越权访问。未授权访问体现在这个备份功能直接在不登录或登录验证存在漏洞的情况下可以直接使用,以及存在CSRF漏洞可以直接劫持管理员账号进行备份,discuz的CSRF备份数据漏洞就是非常好的一个例子。
  • 备份文件名可预测。备份文件名要么是备份的时候人工设置的,要么是自动生成的,如果是人工设置的,在使用完这个功能后可能存在忘记删除备份文件,导致恶意用户可以利用枚举的方式扫描到这个备份包。而自动生成则可能存在生成的文件名比较弱的问题,比如生成的文件名为当前日期,只要简单遍历下即可扫描到,非常不可靠。
  • 生成的文件可利用Web中间件解析漏洞执行代码。渗透测试中写入webshell经常会用到Web中间件的解析漏洞,而当备份功能可以自定义文件名的时候,只要在数据库中写入PHP代码,然后在IIS下时,利用数据库备份功能生成类似 1.asp;.jpg 文件名的文件,到Apache的下就备份成文件名为 1.php.zip 这样的文件,就可以直接执行我们在数据库中插入的代码。

针对如上的分析,我们来总结一下怎么设计备份功能:

  • 进行权限控制,由于备份功能是一个非常高危敏感的功能,一定要限制高权限才能使用。
  • 文件名随机生成,不可预测,可以把当前时间戳加上6位以上字母和数字随机生成的字符串进行md5来做为文件名。

用户登录限制 (12.5) P218

基于纵深防御的思想,假设前面所说的后台地址已经泄露,假设密码被社会工程学等方式窃取到,这种情况下我们就要考虑在登录这一层设置障碍,即使攻击者拿到密码也无法登录,想实现这一效果该怎么做呢,是做信誉体系?自动识别好人和坏人?这种方式很有效果,但是实现起来太庞大,一般的公司没有这样的数据基础去做件事,所以用代码来简单实现最简单的策略如下所示:

  • 限制登录ip。只能固定ip访问,或者说公司内网访问,在外网需要访问的时候拨VPN即可。
  • 双因素认证。限制内网IP是相对安全的,但是还不够安全,因为攻击者有很大 的可能已经通过其他途径进入到内网,所以就需要用到双因素认证手段,比如手机验证码动态令牌都是非常有效的方式,我们在渗透测试的时候经常遇到这种情况:拿到密码之后要双因素认证才能登录。

敏感操作多因素验证 (12.9) P222

多因素验证在很多操作中都适用,特别是敏感的操作,从业务逻辑上来说,不仅仅是后台的登录、修改配置等操作才算敏感,同样前台用户进行个人操作的时候也一样需要受到保护。

在阿里云进行诸如修改域名解析、修改服务器密码等操作时都需要验证手机短信,这样即使密码被泄露也无法进行这些敏感操作。

多因素认证从字面意思就可以理解,即添加多种验证方式,敏感操作多次验证权限,验证的方式有如下7种:

  • 手机短信验证码。
  • 手机语言验证码。
  • 手机App动态令牌。
  • 邮箱验证码。
  • 实体令牌卡。
  • 电子图片令牌卡。
  • 硬件令牌。

验证方式层出不穷,我们在使用的时候需要根据业务的保密程度来确定使用哪种方式,因为每种方式的用户体验不同。

网站安全防御 (12.10) P226

一个网站的应用安全防御应该包括对输入的特殊字符过滤输出过滤异常访问检测自身安全检测等等。

其中,自身安全检测方式有:木马查杀弱后台地址检测弱口令检测等等。