美文网首页
SQL注入的理解及预防----MySQL

SQL注入的理解及预防----MySQL

作者: wandx | 来源:发表于2018-11-04 22:31 被阅读0次

    程序猿(媛)大神的话可以略过,不过有兴趣看到的话希望可以指点一二,在此谢过。技术小白可以加深印象的文章!
    现在不管什么网站,基本都是有用户的,必然要输入用户名和密码来登陆一些网站。那如果用户会一些编程的知识,有时候会“皮一下”,可能会对网站做一些攻击,例如SQL注入,XSS跨站(跨站脚本攻击),CSRF(跨站伪造请求攻击),COOKIE欺骗,DDOS攻击(分布式拒绝服务攻击),文件上传漏洞攻击等等,现在先讨论SQL注入攻击,下次再讨论其他攻击的方式!

    先来说说什么是SQL注入:

    SQL注入是一种比较常见的网络攻击方式之一,它是由程序员开发过程中代码不严谨(没有过滤敏感字符,绑定变量),导致攻击者可以通过sql语法,不择手段,而让其实现无账号登陆的效果,甚至可以对数据库进行篡改!

    以PHP+MySQL做的web站点为技术栈的前提,首先有数据库,而且其中一张表为用户的信息表,基本的字段(本文只说有用到的字段,且有数据)编号,用户名,密码等字段;

    <?Php
    if($_POST){
    $link = mysql_connect("主机的ip", "数据库用户名", "数据库密码");
    mysql_select_db('demo', $link);
    $uname = empty($_POST['username']) ? '' : $_POST['username'];
    $password = empty($_POST['password']) ? '' : $_POST['password'];
    $md5password = md5($password);
    $sql = "SELECT uid,username FROM user WHERE username='{$uname}' AND password='{$md5password}'";
    $query = mysql_query($sql, $link);
    $userinfo = mysql_fetch_array($query, MYSQL_ASSOC);
    if(!empty($userinfo)){
    //登录成功,打印出会员信息
    echo '<pre>',print_r($userinfo, 1),'</pre>';
    } else {
    echo "用户名不存在或密码错误!";
    }
    }
    

    这是login.php后台处理业务伪码

    <form name="login" method="post" action="">
    登录帐号: <input type="text" name="username" value="" size=30 /><br /><br />
    登录密码: <input type="text" name="password" value="" size=30 /><br /><br />
    <input type="submit" value="登录" />
    </form>
    

    这是前台的form表单
    上面如果正确输入数据库中的用户名和密码,则可以正常登陆,而且login.php的sql语句可以写为:

    SELECT id,username FROM user WHERE username='zhangsan' AND password='密码'(当然这块的密码是加密后的)
    

    但是如果攻击者则可能会在用户名中输入:zhangsan' AND 1=1-- hack,密码随便输入即可,这样在form表单提交之后的sql语句处理为:

    SELECT id,username FROM user WHERE username='zhangsan'AND 1=1-- hack AND password='密码'
    

    然后在数据库中执行sql语句,1=1是成立的条件,所以就是只要攻击者随便注册一个账号或者知道某个用户名,无需密码就可以登录到系统中。
    那我们如何防御sql注入呢?
    在服务器的那方面,应该保证上线的项目中错误提示的信息应该是关闭的(不应该是调试的模式)。例如PHP的生产环境中,应该在php.ini中把display_errors设置为Off,这样就关不了错误提示。
    1、开发人员在开发过程中要检查变量数据类型和格式,确保用户输入的内容是我们预想的格式来输入,其中可以用正则去验证。

    2、对于无法确定格式的变量,对一些特殊符号过滤或者转义进行处理。PHP的话可以PHP自带过滤和转义的函数进行处理。Eg:addslashes(单双引号、反斜线及NULL加上反斜线转义)

    3、还可以绑定变量,使用预编译语句的方式进行处理sql注入,因为MySQL的mysqli驱动提供了预编译语句的支持,这里以PHP语言为例:

    if($username){
    //使用mysqli驱动连接demo数据库
    $mysqli = new mysqli("主机ip", "数据库用户名", "数据库密码", 'demo');
    //使用问号替代变量位置
    $sql = "SELECT id,username FROM user WHERE username=?";
    $stmt = $mysqli->prepare($sql);
    //绑定变量
    $stmt->bind_param("s", $uname);
    $stmt->execute();
    $stmt->bind_result($id, $uname);
    while ($stmt->fetch()) {
    $row = array();
    $row['id'] = $id;
    $row['username'] = $uname;
    $userinfo[] = $row;
    }
    }
    

    这样在代码提交的时候,在sql语句中变量用问号表示,就无法改变sql语句的结构,就算是传递 zhangsan'AND 1=1-- hack 参数,只会当做字符串来解释查询,可以说是从根本上解决的sql注入的攻击。
    而实际上,绑定变量使用预编译也是预防sql注入的最好方式
    所以开发人员在实际项目过程中,一定要做好代码的严谨,而且永远不要相信用户那边的输入,最好对其格式上有严格的要求。

    相关文章

      网友评论

          本文标题:SQL注入的理解及预防----MySQL

          本文链接:https://www.haomeiwen.com/subject/osodxqtx.html