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注入。

     

  • 相关阅读:
    UVa 10118 记忆化搜索 Free Candies
    CodeForces 568B DP Symmetric and Transitive
    UVa 11695 树的直径 Flight Planning
    UVa 10934 DP Dropping water balloons
    CodeForces 543D 树形DP Road Improvement
    CodeForces 570E DP Pig and Palindromes
    HDU 5396 区间DP 数学 Expression
    HDU 5402 模拟 构造 Travelling Salesman Problem
    HDU 5399 数学 Too Simple
    CodeForces 567F DP Mausoleum
  • 原文地址:https://www.cnblogs.com/damugua/p/12905804.html
Copyright © 2011-2022 走看看