用usingPost方法检查POST变量,提升php站点安全性

单入口网站比多入口网站具备更高的统一性和安全性,你可以在入口处对来自浏览器的数据进行统一的验证。利用UrlRewrite技术实现的单入口PHP方法网上有大量文章可供参考,这里就不多说了。这篇文字还是多说说usingPost方法的设计和它提升PHP站点安全性的原理。
如下图,通过UrlRewrite把URL请求解析成对index.php的请求,在这一步可以实现对$_GET参数的限制。我设置的Web站只接收大小写字母、数字和小数点构成的url。这样SQL注入和XSS攻击都无法通过GET方法实现。根据我做的十余个网站的经验,GET方法传的资料一般都是简单的数字字母组合,比如列表的分页页码(数字),购物车操作用的MD5密钥等等。

这样一来,Web安全防范的的重点就在POST数据上了。用PHP对POST数据作安全验证可以说非常简单。有ctype函数库和preg正则函数的帮助。htmlspecialchars和mysql_real_escape_string让XSS和注入攻击也成为不可能的事情。我在公司时,每次谈到Web安全问题,常说的一句话是良好的安全意识比什么都重要。我现在依然保持这个观点。那么为什么还需要写usingPost函数呢?道理很简单,那就是减少犯错的可能性。
我经历的项目中,大量的Web安全漏洞都是在修改功能的时候被引入的。负责修改的人常常忘记对新增的POST变量做安全检查,尤其是当这个负责修改的程序员刚从烟雾缭绕的会议室出来,加夜班完成这个老板眼中极其重要的功能调整时,更容易“做到能用为止”。
usingPost的设计是让$_POST数组先声明才能使用。usingPost函数提供int,dec,hex,date,string,email,mobile几种数据类型的检查。调用的时候它会遍历声明列表,把没声明的或者类型不对的POST变量删掉。下面的例子中,接收字符串username、字符串nick、十进制整数gender、日期birth四个不同类型的POST变量。调用usingPost后,名称不相符的POST变量和数据类型不符合的都会自动被删除。

usingPost('username:string, nick:string, gender:dec, birth: date');
这样一来,usingPost会帮助验证POST变量。新增功能忘记验证的的变量会因为被usingPost删除而无法使用,Web安全得以更有效地保证。

介绍一下usingPost的数据类型

  • dec 十进制整数,只能是0-9的数字
  • hex 十六进制整数,可以是0-9的数字,大写或小写的a-f的字母
  • int 整数,包括上面的十进制和十六进制
  • date 日期,只接收YYYY-mm-dd的格式
  • email Email格式字符串,用正则验证
  • mobile 手机号码,仅用于中国,以13/15/18开头的11位十进制整数
  • string 字符串,不验证具体格式,用htmlspecialchars转义HTML格记
  • unsafe 不确保安全的原始类型,由程序员自己作安全验证

usingPost函数源码下载using.php.gzusing.php.bz2

Continue Reading