防御SQL注入和XSS攻击
无意苦争春 竹子熊 2017.7.28
防御SQL注入
sql注入是网站开发常见的安全漏洞之一,其产生的原因是开发人员未对用户输入的数据进行过滤就拼接到sql语句中执行,导致用户输入的一些特殊字符破坏可原有SQL语句的逻辑,造成数据泄漏,被篡改,删除等危险的后果.
在此前的项目中,操作数据库使用MYSQLi扩展的预处理机制,将sql语句和数据分离,从本质上避免了SQL注入问题的发生.需要注意的是,如果开发人员仍然使用拼接SQL语句的方式,则SQL注入问题依然会发生,如下列代码所示.
//下列代码存在SQL注入问题 $name$_POST['name']; $result=mysqli_query($link,"SELECT * FROM `admin` WHERE `name`=`$name`");
上述代码将来自外部的数据name数据直接拼接到sql语句中,如果用户输入了单引号,则会将原有的SQL语句中的单引号闭合,然后用户就可以将自己输入的内容当成SQL语句执行,如下所示.
//假设用户输入" 'or 1='1",SQL语句将变成 SELECT * `admin`WHERE `name` ='' or 1='1'
将用户输入的攻击代码拼接到sql语句后,原有的逻辑就被破坏了,此时就会通过or条件查询出admin表中的所有记录,造成了数据的泄漏.
接下来改进上述代码,通过MYSQLi预处理的机制将SQL与数据分开发送,代码如下.
//接收变量 $name=$_POST['name']; //预处理方式执行SQL $stmt=mysqli_prepare($link,'SELECT * FROM `admin` WHERE `name`=?'); mysqli_stmt_bind_param($stmt,'s',$name); mysqli_stmt_execute($stmt); $result=mysqli_stmt_get_result($stmt);
经过上述修改后,即可防御sql注入问题,
防御XSS攻击
跨站脚本攻击(Cross Site scripting XSS)产生的原因是将来自用户输入的数据未经过滤就拼接到HTML页面中,造成攻击者可以通过输入Javascript代码来盗取网站用户的Cookie.由于Cookie在网站中承载着用户登录信息的作用,一旦Cookie被盗取,攻击者就得到了受害用户登录后的权限,从而造成一系列危险的后果.
在防御XSS攻击时,对于普通的文本数据,使用htmlspecialchars()是最好的方法,该函数可以将转义字符串中的双引号,尖括号等特殊字符,但需要注意的是,默认情况下,单引号不会被转义,例如,以下代码就存在XSS漏洞.
//接收来自用户输入的数据 $name=htmlspecialchars($_POST['name']); //拼接到HTML中 echo "<input type="text" value='$name'/>";
在上述代码中.由于用户可以输入单引号,因此可以通过单引号闭合原有的value属性,然后在后面可以添加事件属性如onclick,从而通过这种方式来注入Javascript代码,如下所示.
//假设用户输入" ' onclick='alert(document.cookie) ",输出结果为 <input type="text" value='' onclick='alert(document.cookie)'/>
当上述代码背浏览器执行后,攻击者注入的Javascript代码就会运行,这样威胁网站和用户的安全.
用于 XSS攻击的主要目的是盗取Cookie,因此可以为项目最关键的PHPSESSID这个Cookie设置HttpOnly属性.通过设置该属性可以阻止Javascript访问该Cookie.在php.ini中可以设置是否开启session时自动为PHPSESSID设置HttpOnly属性,也可以通过ini_set()函数临时修改配置,具体代码如下.
//保存在浏览器端的PHPSESSID设置HttpOnly ini_set('session.cookie_httponly',1); //开启Session session_start();
上述代码在开启Session前通过ini_set()函数动态修改PHP的环境配置,此修改只对本项目在运行周期内时有效,并不影响php.ini中的原有设置.