• PHP安全性


    一、防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、另一种解决方法是加验证码(最重要的)

     

  • 相关阅读:
    Html列表分页算法
    .Net分布式锁
    Net中的常见的关键字
    C# 操作windows服务[启动、停止、卸载、安装]
    虚拟机设置静态IP与配置网络
    WebService服务介绍与调用
    StackService.Redis 应用
    Centos+Redis 集群
    浏览器LocalStroage使用
    WCF与WebService的区别(转)
  • 原文地址:https://www.cnblogs.com/zst062102/p/5661073.html
Copyright © 2020-2023  润新知