zoukankan      html  css  js  c++  java
  • SQL注入

    一:SQL注入:

    就是通过SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。
    就是说:用户在网友输入框中输入SQL命令后,后台接收后没有进行识别或类型转换,直接就运行了。

    什么意思呢?

    假如我们的登录

    select * from user
    where
        1=1
       and user.password="123456"
    limit 1

    当我们在前台传入  or  1=1

    select * from user
    where
        1=1
       and user.password="13456"
        or 1=1
    limit 1

    就把第一行的数据给显示出来了。这样。我们不知道密码也是能登录的。

    二:mybatis中的占位符和拼接符

    1、占位符

    (1)#{}表示一个占位符号,通过#{}把parameterType 传入的内容通过preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。

    (2)#{}可以接收简单类型值或pojo属性值。如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。

    例如(这是用JDBC编写,在Mybatis中我们看不到PreparedStatement,只要是用占位符#{},它自动实现这过程):

     String sql = “insert into user (name,pwd) values(?,?)”;  
     PreparedStatement ps = conn.preparedStatement(sql);  
     ps.setString(1, “jack”);   //占位符顺序从1开始
     ps.setString(2, “123456”); //也可以使用setObject
     ps.executeQuery();

    2、拼接符

    ${}表示拼接sql串,通过${}可以将parameterType 传入的内容直接拼接在sql中且不进行jdbc类型转换,${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value。

    三、为什么PreparedStatement 有效的防止sql注入?

    1、PreparedStatement简介

    PreparedStatement是用来执行SQL查询语句的API之一,Java提供了 Statement、PreparedStatement 和 CallableStatement三种方式来执行查询语句,其中 Statement 用于通用查询, PreparedStatement 用于执行参数化查询,而 CallableStatement则是用于存储过程。

    2、普通SQL注入简介

    比如:某个网站的登录验证SQL查询代码为:

    strSQL = "SELECT * FROM users WHERE name = '" + userName + "' and pw = '"+ passWord +"';"

     

    恶意填入:

    userName = "1' OR '1'='1";

    passWord = "1' OR '1'='1";

     

    那么最终SQL语句变成了:

    strSQL = "SELECT * FROM users WHERE name = '1' OR '1'='1' and pw = '1' OR '1'='1';"

     

    因为WHERE条件恒为真,这就相当于执行:

    strSQL = "SELECT * FROM users;"

    因此可以达到无账号密码亦可登录网站。

    3、使用PreparedStatement的参数化的查询可以阻止大部分的SQL注入

    在使用参数化查询的情况下,数据库系统(eg:MySQL)不会将参数的内容视为SQL指令的一部分来处理,而是在数据库完成SQL指令的编译后,才套用参数运行,因此就算参数中含有破坏性的指令,也不会被数据库所运行。

    即SQL语句在程序运行前已经进行了预编译,当运行时动态地把参数传给PreprareStatement时,即使参数里有敏感字符如 or '1=1'、数据库也会作为一个参数一个字段的属性值来处理而不会作为一个SQL指令。

    补充1:在页面输入的时候可以加入校验,不可输入sql关键字,不可输入空格,也可以防止SQL注入。

    补充2:PreparedStatement比 Statement 更快

    使用 PreparedStatement 最重要的一点好处是它拥有更佳的性能优势,SQL语句会预编译在数据库系统中。执行计划同样会被缓存起来,它允许数据库做参数化查询。使用预处理语句比普通的查询更快,因为它做的工作更少(数据库对SQL语句的分析,编译,优化已经在第一次查询前完成了)。为了减少数据库的负载,生产环境中德JDBC代码你应该总是使用PreparedStatement 。值得注意的一点是:为了获得性能上的优势,应该使用参数化sql查询而不是字符串追加的方式。下面两个SELECT 查询,第一个SELECT查询就没有任何性能优势。

    SQL Query 1:字符串追加形式的PreparedStatement

    String loanType = getLoanType();

    PreparedStatement prestmt = conn.prepareStatement("select banks from loan where loan_type=" + loanType);

    SQL Query 2:使用参数化查询的PreparedStatement

    PreparedStatement prestmt = conn.prepareStatement("select banks from loan where loan_type=?");

    prestmt.setString(1,loanType);

    很明显Mybatis中是用的参数化查询

  • 相关阅读:
    《Eclipse中的一些快捷键》
    《Java中的抽象类及抽象类的作用》
    《Java中的不可变类》
    《final修饰基本类型变量和引用类型变量的区别》
    《类成员案例》
    《Java中的单例模式--两种》
    《Java中的自动装箱和拆箱功能.》
    Chrome 经典插件
    Sublimeの虚拟环境(Venv)设置
    HTTP下午茶
  • 原文地址:https://www.cnblogs.com/bulrush/p/10692272.html
Copyright © 2011-2022 走看看