一、防sql注入
用户通过输入完整的字符,来和sql语句拼接成带有破坏性的sql语句,服务器执行该语句,造成破坏。
1使用mysql_real_escape_string()过滤数据,该方法在未来版本会淘汰
<body> <form action="chuli.php" method="post"> <div> <input type="test" name="uid"/> </div> <input type="submit" value="提交"/> </form> </body>
<?php include("../DBDA.class.php"); $db=new DBDA(); $uid=$_POST["uid"]; $uid=mysql_real_escape_string($uid);//过滤数据,但是以后会移除该方法 $sql="select * from user where uid='{$uid}'"; echo $sql; var_dump($db->Query($sql));
2、使用PDO预处理语句
二、xss攻击
1、演示
<body> <form action="chuli.php" method="post"> <div> <input type="test" name="uid"/> </div> <input type="submit" value="提交"/> </form> </body> </html>
<?php include("../DBDA.class.php"); $db=new DBDA(); echo $_POST["uid"];
2、用户在表单里输入恶意的代码(主要是js代码),来破坏网站页面,例如不断刷新页面的js代码
解决方式为过滤字符串
3、防止一:php自带方法是使用htmlspecialchars()函数
4、防止二:写一个过滤输入内容的方法
function clean_xss(&$string, $low = False) { if (! is_array ( $string )) { $string = trim ( $string ); $string = strip_tags ( $string ); $string = htmlspecialchars ( $string ); if ($low) { return True; } $string = str_replace ( array ('"', "\", "'", "/", "..", "../", "./", "//" ), '', $string ); $no = '/%0[0-8bcef]/'; $string = preg_replace ( $no, '', $string ); $no = '/%1[0-9a-f]/'; $string = preg_replace ( $no, '', $string ); $no = '/[x00-x08x0Bx0Cx0E-x1Fx7F]+/S'; $string = preg_replace ( $no, '', $string ); return True; } $keys = array_keys ( $string ); foreach ( $keys as $key ) { clean_xss ( $string [$key] ); } }
$str = $_POST["uid"]; clean_xss($str); //如果你把这个注释掉,你就知道xss攻击的厉害了 echo $str;
//$str = 'phpddt.com<meta http-equiv="refresh" content="0;">';//将此代码输入到表单里,如果不使用clean_xss()方法,会造成不断刷新网页
三、CSRF攻击(跨站请求伪造,XSRS)
1、可以理解为攻击者盗用你的身份,以你的名义发送恶意请求
2、演示
例如,一个人员(uid=“lisi”)登陆账户,此用户进行转账或消费活动
<title>无标题文档</title> <?php session_start(); $_SESSION["uid"]="lisi"; ?> </head> <body> <form action="csrfcl.php" method="get"> <div><input type="text" name="qian"/></div> <input type="submit" value="提交"/> </form> </body>
后端处理代码
<?php session_start(); include("../DBDA.class.php"); $db = new DBDA(); if(empty($_SESSION["uid"])) { echo "未登录"; } else { $qian=$_REQUEST["qian"]; $sql="update login set account = account-{$qian} where username='{$_SESSION['uid']}'"; echo $sql; $db->Query($sql,1); }
这样操作下来是一个合理的流程。
但是,转账或消费完之后,不关闭此页面,将页面地址栏出的地址信息全部复制下来,例如:http://localhost/anquan/csrfcl.php?qian=100
再之后,自己新建一个页面,里面代码如下:
<body> <img src="http://localhost/anquan/csrfcl.php?qian=100"/> </body>
最后,刷新此页面,账户中的余额会发生变化。
3、以上讲解,表单是以get形式传值,如果表单以post形式提交,CSRF攻击将以以下形式进行
<?php session_start(); $_SESSION["uid"]="lisi"; ?> </head> <body> <form action="csrfcl.php" method="post"> <div><input type="text" name="qian"/></div> <input type="submit" value="提交"/> </form> </body>
<?php session_start(); include("../DBDA.class.php"); $db = new DBDA(); if(empty($_SESSION["uid"])) { echo "未登录"; } else { $qian=$_POST["qian"]; $sql="update login set account = account-{$qian} where username='{$_SESSION['uid']}'"; echo $sql; $db->Query($sql,1); }
以上操作和get形式差不多,只不过提交方式不同,所以攻击方式为新建一个没有session的表单
<body> <form action="csrfcl.php" method="post"> <div><input type="text" name="qian"/></div> <input type="submit" value="提交"/> </form> </body>
解决思路是让伪造的表单不能使用
4、解决方法是在前端表单进行加密
<?php session_start(); $_SESSION["uid"]="lisi"; $str=md5($_SESSION["uid"]);//加密 ?> </head> <body> <form action="csrfcl.php" method="post"> <input type="hidden" value="<?php echo $str ?>" name="xinxi"/>//隐藏的加密信息 <div><input type="text" name="qian"/></div> <input type="submit" value="提交"/> </form> </body>
后端服务器代码加密信息匹配
<?php session_start(); include("../DBDA.class.php"); $db = new DBDA(); if(empty($_SESSION["uid"])) { echo "未登录"; } else { $str=$_POST["xinxi"]; $ck=md5($_SESSION["uid"]); if($str=$ck) { $qian=$_POST["qian"]; $sql="update login set account = account-{$qian} where username='{$_SESSION['uid']}'"; echo $sql; $db->Query($sql,1); } }
5、另一种解决方法是加验证码(最重要的)