==SQL 注入
SQL 注入是PHP应用中最常见的漏洞之一。事实上令人惊奇的是,开发者要同时犯两个错误才会引发一个SQL注入漏洞,一个是没有对输入的数据进行过滤(过滤输入),还有一个是没有对发送到数据库的数据进行转义(转义输出)。这两个重要的步骤缺一不可,需要同时加以特别关注以减少程序错误。
虽然两个步骤都不能省略,但只要实现其中的一个就能消除大多数的SQL注入风险。如果你只是过滤输入而没有转义输出,你很可能会遇到数据库错误(合法的数据也可能影响SQL查询的正确格式),但这也不可靠,合法的数据还可能改变SQL语句的行为。另一方面,如果你转义了输出,而没有过滤输入,就能保证数据不会影响SQL语句的格式,同时也防止了多种常见SQL注入攻击的方法。
关于SQL注入,不得不说的是现在大多虚拟主机都会把magic_quotes_gpc选项打开,在这种情况下所有的客户端GET和POST的数据都会自动进行addslashes处理,所以此时对字符串值的SQL注入是不可行的,但要防止对数字值的SQL注入,如用intval()等函数进行处理。但如果你编写的是通用软件,则需要读取服务器的magic_quotes_gpc后进行相应处理。
==会话劫持
最常见的针对会话的攻击手段是会话劫持。它是所有攻击者可以用来访问其它人的会话的手段的总称。所有这些手段的第一步都是取得一个合法的会话标识来伪装成合法用户,因此保证会话标识不被泄露非常重要。前面几节中关于会话暴露和固定的知识能帮助你保证会话标识只有服务器及合法用户才能知道。
把伪装过程变得更复杂的关键是加强验证。会话标识是验证的首要方法,同时你可以用其它数据来补充它。你可以用的所有数据只是在每个HTTP请求中的数据:
GET / HTTP/1.1 Host: abc.net User-Agent: Firefox/1.0 Accept: text/html, image/png, image/jpeg, image/gif, * / HTTP/1.1 Host: abc.net User-Agent: Firefox/1.0 Accept: text/html, image/png, image/jpeg, image/gif, * |
应该意识到请求的一致性,并把不一致的行为认为是可疑行为。例如,虽然User-Agent(发出本请求的浏览器类型)头部是可选的,但是只要是发出该头部的浏览器通常都不会变化它的值。如果你一个拥有1234的会话标识的用户在登录后一直用Mozilla Firfox浏览器,突然转换成了IE,这就比较可疑了。例如,此时你可以用要求输入密码方式来减轻风险,同时在误报时,这也对合法用户产生的冲击也比较小。你可以用下面的代码来检测User-Agent的一致性:
php session_start(); if (isset($_SESSION['HTTP_USER_AGENT'])) { if ($_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT'])) { exit; } } else { $_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']); } ?> |
在某些版本的IE浏览器中,用户正常访问一个网页和刷新一个网页时发出的Accept头部信息不同,因此Accept头部不能用来判断一致性。 确保User-Agent头部信息一致的确是有效的,但如果会话标识通过cookie传递,有道理认为,如果
攻击者能取得会话标识,他同时也能取得其它HTTP头部。由于cookie暴露与浏览器
漏洞或跨站脚本
漏洞相关,受害者需要访问
攻击者的
网站并暴露所有头部信息。所有
攻击者要做的只是重建头部以防止任何对头部信息一致性的检查。
比较好的方法是产生在URL中传递一个标记,可以认为这是第二种验证的形式。使用这个方法需要进行一些
编程工作,PHP中没有相应的功能。例如,假设标记保存在$token中,你需要把它包含在所有你的应用的内部链接中:
php $url = array(); $html = array(); $url['token'] = rawurlencode($token); $html['token'] = htmlentities($url['token'], ENT_QUOTES, 'UTF-8'); ?> Click Here |
为了更方便地管理这个传递过程,你可能会把整个请求串放在一个变量中。你可以把这个变量附加到所有链接后面,这样即便你一开始没有使用该技巧,今后还是可以很方便地对你的代码作出变化。 该标记需要包含不可预测的内容,即便是在
攻击者知道了受害者浏览器发出的HTTP头部的全部信息也不行。一种方法是生成一个随机串作为标记:
php $string = $_SERVER['HTTP_USER_AGENT']; $string .= 'SHIFLETT'; $token = md5($string); $_SESSION['token'] = $token; ?> |
当你使用随机串时(如SHIFLETT),对它进行预测是不现实的。此时,捕获标记将比预测标记更为方便,通过在URL中传递标记和在cookie中传递会话标识,
攻击时需要同时抓取它们二者。这样除非
攻击者能够察看受害者发往你的应用所有的HTTP请求原始信息才可以,因为在这种情况下所有内容都暴露了。这种
攻击方式实现起来非常困难(所以很罕见),要防止它需要使用SSL。
有专家警告不要依赖于检查User-Agent的一致性。这是因为服务器群集中的HTTP代理服务器会对User-Agent进行编辑,而本群集中的多个代理服务器在编辑该值时可能会不一致。
如果你不希望依赖于检查User-Agent的一致性。你可以生成一个随机的标记:
php $token = md5(uniqid(rand(), TRUE)); $_SESSION['token'] = $token; ?> |
这一方法的
安全性虽然是弱一些,但它更可靠。上面的两个方法都对防止会话劫持提供了强有力的手段。你需要做的是在
安全性和可靠性之间作出平衡。
上一页 [1] [2] [3]