当一个变量从表单传入到php,需要查询mysql的话,需要进行处理。
举例:
unsafevariable= u n s a f e v a r i a b l e = _POST[‘user_input’];
mysqli_query(“INSERT INTO table (column) VALUES (‘” . $unsafe_variable . “’)”);
用户可以输入诸如 : value’); DROP TABLE table;– ,SQL语句就变成这样了:
INSERT INTO table (column) VALUES(‘value’); DROP TABLE table;–’)
执行的结果就是table表被删掉了。
这是一种常见的sql注入方法,那么在程序中,应该怎样预防呢?
2.1.魔术引用 (推荐指数3)
addslashes()与stripslashes()是功能相反的函数。
addslashes()用于对变量中的’ ” 和NULL添加斜杠,用于避免传入sql语句的参数格式错误,同时如果有人注入子查询,通过加可以将参数解释为内容,而非执行语句,避免被mysql执行。
不过,addslashes()添加的只在php中使用,并不会写入mysql中。
那么,tripslashes()的作用是将加了的php变量去掉,由于不会写入mysql中,所以从mysql查询出来的内容不需要再tripslashes()。
在防注入方面,addslashes()可以防止掉大多数的注入,但是此函数并不会检查变量的编码,当使用例如中文gbk的时候,由于长度比较长 ,会将某些gbk编码解释成两个ascii编码,造成新的注入风险(俗称宽字节注入)。见下面2。
如果从网页表单、php、mysql都使用utf8编码,则没有这个问题。
基于此函数的风险,并不建议使用,推荐使用下面3中的方法。
https://segmentfault.com/q/10
2.2 mysql_real_escape_string
由于addslashes()不检测字符集,所以有宽字节注入风险,所以php中添加了这个函数。
这个函数本来是mysql的扩展,但是由于存在宽字节的问题,php基于mysql的扩展开发了此函数。
gbk宽字符漏洞导致的sql注入
https://www.91ri.org/8611.html
http://www.cnblogs.com/suihui…
mysql_real_escape_chars()是mysql_escape_chars()的替代用法。
与addslashes()相比,不仅会将’ ” NOL(ascii的0)转义,还会把r n进行转义。同时会检测数据编码。
按php官方的描述,此函数可以安全的用于mysql。
此函数在使用时会使用于数据库连接(因为要检测字符集),并根据不同的字符集做不同的操作。如果当前连接不存在,刚会使用上一次的连接。
mysql_real_escape_string()防注入详解
此方法在php5.5后不被建议使用,在php7中废除。
参考:https://segmentfault.com/q/10
2.3 预处理查询 (Prepared Statements) (推荐指数5)
使用prepared statements(预处理语句)和参数化的查询,可以有效的防止sql注入。
为什么预处理和参数化查询可以防止sql注入呢?
在传统的写法中,sql查询语句在程序中拼接,防注入(加斜杠)是在php中处理的,然后就发语句发送到mysql中,mysql其实没有太好的办法对传进来的语句判断哪些是正常的,哪些是恶意的,所以直接查询的方法都有被注入的风险。
在mysql5.1后,提供了类似于jdbc的预处理-参数化查询。它的查询方法是:
2.3.1先预发送一个sql模板过去
2.3.2再向mysql发送需要查询的参数
就好像填空题一样,不管参数怎么注入,mysql都能知道这是变量,不会做语义解析,起到防注入的效果,这是在mysql中完成的。
这里通俗的讲,就像是SQL注入一样,XSS攻击也可以算是对HTML和JS的一种注入。你本来希望得到是从用户那得到一段有用的文本文字,但用户提交给你的却是别有用心的可执行javascript或者其他脚本,当你再把这些提交的内容显示到页面上时,xss攻击就发生了。
2.1 PHP htmlentities()
函数 htmlentities()
函数把字符转换为 HTML 实体。语法为htmlentities(string,flags,character-set,double_encode)
实例把一些字符转换成HTML实体
$str = "Jane & 'Tarzan'";
echo htmlentities($str, ENT_COMPAT); // Will only convert double quotes
echo "
";
echo htmlentities($str, ENT_QUOTES); // Converts double and single quotes
echo "
";
echo htmlentities($str, ENT_NOQUOTES); // Does not convert any quotes
?>
上面代码的 HTML 输出如下(查看源代码):
Jane & ‘Tarzan’
Jane & ‘Tarzan’
Jane & ‘Tarzan’
上面代码的浏览器输出如下
Jane & ‘Tarzan’
Jane & ‘Tarzan’
Jane & ‘Tarzan’
cookie里面一般有自动登录信息和session_id,就算对cookie里面的内容全部加了密,cookie的信息一但被别人通过XSS攻击获取后也一样等同于把自己的帐号密码给了别人。
对cookie进行IP绑定,(当然也可以获取用户客户端更多的其它信息进行同时绑定)可以根据用户的IP来判断这个cookie**是不是来原始授权用户**。
优点:大多数场景下可使被XSS攻击盗取的cookie失效。缺点:由于IP存在多台电脑共用的可能,对绑定做不到十分精细。
代码案例如下
用户设置了自动登录时保存自动登录信息:
$auto=I('post.auto');//用户设置了自动登录
if(!empty($auto)){
cookie('auto',encrypt(serialize($data)));//将登录信息保存到cookie,其中$data里含有加密后的帐号,密码,和用户的IP,这里的cookie已在全局中设置过期日期为一周
}
用户关闭浏览器再次访问网站时,进行自动登录
if (!is_login()) {//是否未登录状态?
$auth=cookie('auto');
if(!empty($auth)){//是否未有自动登录cookie?
$data=unserialize(decrypt($auth));
if(!empty($data) && !empty($data['username']) && !empty($data['password']) && !empty($data['last_login_ip'])){
$user=M('Member')->where(array('username'=>$data['username'],'password'=>$data['password']))->find();
if(!empty($user['id'])&&($user['last_login_ip']==get_client_ip())){//cookie帐号密码是否有效?//IP来源是否相同?
login_session($user['id'], $user['username'], $data['last_login_ip']);//用户自动登录成功
}
}
}
}
为iframe的增加的sandbox属性,可以防止不信任的Web页面执行某些操作.相信这个方法以后会被广泛使用