zoukankan      html  css  js  c++  java
  • SQL注入与参数化查询

    SQL注入的本质

    SQL注入的实质就是通过SQL拼接字符串追加命令,导致SQL的语义发生了变化。为什么发生了改变呢? 因为没有重用以前的执行计划,而是对注入后的SQL语句重新编译,然后重新执行了语法解析。 所以要保证SQL语义不变,(即想要表达SQL本身的语义,并不是注入后的语义)就必须保证执行计划确定不被改变。
     
    SQL注入的表现
     示例
    1.我们先熟悉一下表里的东西
     

     2.要查询的原SQL语句。

    3.注入的SQL语句

     

    分析示例:
    原SQL语句
    select COUNT(*) from T_Users where UserName  = 'a' and Password  ='b'1

    语义:要查找(用户名为‘a’,密码为‘b’) 的用户总共有几个.  查询结果为1

    注入后的SQL语句
    select COUNT(*) from T_Users where UserName  = 'a' and Password  = 'b' or 1=1 --'1

    注入后的语义:查找 (密码是a的,并且用户名是b的,) 或者1=1 的所有用户的数量。 这时候语义发生了改变,查询结果为4

    分析:如果用户在输入密码时, 输入的不是b    而是b’ or 1=1- -  ,语义将会发生改变,(- -在数据库中是注释的标记)最后查询的结果当然也就不相同了。原语句的查询结果为1,注入后的查询结果为4。
    SQL注入的危害
    我们刚刚示范了SQL注入带来的查询结果的改变,这个可能会让别有用心的用户熟知我们数据库中的记录条数。或者如果输入的是b’ delect T_Users - -  这时候我们整张表都被删除了,这个带来的后果可想而知。
    防止SQL注入–参数化查询
    我们的机房重构中D层一直在用参数化查询,但是我当时没有完全理解用参数化查询的用意。直到现在才理解了为什么要用参数化查询和参数化查询如何防止SQL注入的。
    public int checkUser(Users user)
       {
        string sql = "select COUNT(*) from T_Users where UserName = @UserName and Password = @Password";
        SqlParameter[] paras ={new SqlParameter ("@UserName",User.username) ,
                                          new SqlParameter ("@Password",User.password)};
        int num = sqlhelper.ExecuteNonQuery(sql, paras);
        return num ;
       }12345678

    这是我们用了参数化查询后的效果,我们来分析一下参数化查询是如何防止sql注入的。

    select count(*) from T_Users where UserName = ‘a’ and Password = ‘b’ or 1=1- -‘,
    是等到 UserName 参数传过来,才会去编译这条 sql语句(sql语句是编译后执行的),而这个时候, 这个拼接的sql 多了 or 选项,这改变了sql语句的本意。
    参数化查询:是先编译 这样一条sql,   select count (*) from T_Users where = UserName = @UserName and Password = @Password ,和函数的编译一样, 这样的话,以后’b’ or 1=1- - ’  只能作为 Password  的参数了,,,相当于你去查  ” ‘b’ or 1=1—’   ” 这个密码,而不是 查  “b” 这个密码 或者 ” 1=1 ” 了。 相当于把 or 给屏蔽掉了。or 原来是sql的一项(普通的拼接),现在就是个普通字符串参数(参数化查询)
    ,不能改变sql语义,也不能改变编译执行计划,所以防止了SQL注入。
     
    示例小结:
    正常的命令是程序中的“常量”,能动手脚的只能是可输入的用户名、密码这些可输入的“变量”。 拼接方式是将常量、变量拼在一起编译,才可以在正常的命令后追加命令。参数化的方式仅常量参与编译,就无法追加命令,防止了sql注入。
    总结:
    参数化查询的方式简单来说就是指用参数参与编译,这样就全是常量了,编译执行计划时没有用到参数,所以命令是确定的。编译后计划便确定了,编译后传参数知识为了运行执行计划,执行计划不变,就不会多出命令,SQL语义就无法改变,防止了sql注入。

     

  • 相关阅读:
    2:(sql语言的数据类型)
    4:关系数据库标准语言sql(sql概述:功能,特点)
    毕业设计:反射,枚举
    毕业设计:阶段性总结
    3.9易错题
    3.8(关系代数表达查询)
    3.7(附加的关系运算)
    3.5(关系的完整性约束)、(关系代数的五种基本运算:选择和投影(关于行运算和列运算的概念还不清晰))
    3.4(从E-r概念模型到关系模型即DBMS直接支持的数据模型)
    php 如何获取图片后缀和可变函数的使用实战
  • 原文地址:https://www.cnblogs.com/damugua/p/12905804.html
Copyright © 2011-2022 走看看