MySql之Sql注入的产生与预防

相信大家对于SQL注入这种东西并不陌生!

仍记得很久以前尝试利用SQL注入登录系统的时候.....

什么是SQL注入呢?

其实就是用户输入的内容作为SQL语句语法的一部分,从而改变程序内原有设定的SQL的真正意义

下面就以案例的形式为大家演示SQL注入的过程:

一.案例展示

1.测试准备

  • ①MySql数据库一枚
  • ②database名为mysqlstudy,且表尾admin
  • ③maven创建的webapp项目工程

2.代码展示:

***pom.xml

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.46</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>2.3.1</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.1.2</version>
    </dependency>
  </dependencies>

***index.jsp

<%--
  Created by IntelliJ IDEA.
  User: WHW
  Date: 2019/8/5
  Time: 19:49
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>测试SQL注入</title>
</head>
<body>
    <fieldset>
        <form action="/us" method="post">
            用户名:<input type="text" name="username"/><br/>
            密 码:<input type="text" name="password"/><br/>
            <input type="button" value="Login">
        </form>
    </fieldset>
</body>
</html>

***Admin.java

package com.howie.pojo;

/**
 * @Author weihuanwen
 * @Date 2019/8/5 19:18
 * @Version 1.0
 */
public class Admin {
    private int id;
    private String username;
    private String password;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "admin{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

***JDBCUtils.java

package com.howie.utils;

import java.sql.*;

/**
 * @Author weihuanwen
 * @Date 2019/8/5 18:11
 * @Version 1.0
 */
public class JDBCUtils {

    //1.数据库驱动信息
    private static String driver = "com.mysql.jdbc.Driver";
    //2.数据库连接信息
    private static String url =
            "jdbc:mysql://localhost:3306/mysqlstudy?characterEncoding=utf8";
    private static String username = "root";
    private static String password = "root";

    //3.静态代码块用于获取MySql驱动
    static {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 4.工具提供获取数据库连接的方法
     * @return
     */
    public static Connection getConnection() throws SQLException {
        //5.获取数据库连接并返回
        return DriverManager.getConnection(url, username, password);
    }

    /**
     * 5.释放资源
     * @param rs 结果集
     * @param stat sql执行者
     * @param conn 数据库连接对象
     */
    public static void closeResource(ResultSet rs, Statement stat,Connection conn){
        if (rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (stat != null){
            try {
                stat.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

***UserServlet.java

package com.howie.vertify;

import com.howie.pojo.Admin;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

/**
 * @Author weihuanwen
 * @Date 2019/8/5 19:14
 * @Version 1.0
 */
@WebServlet("/us")
public class UserServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Map<String, String[]> parameterMap = req.getParameterMap();
        Admin admin = new Admin();
        for (String fieldName : parameterMap.keySet()) {
            if ("username".equals(fieldName)){
                admin.setUsername(parameterMap.get(fieldName)[0]);
            }
            if ("password".equals(fieldName)){
                admin.setPassword(parameterMap.get(fieldName)[0]);
            }
        }
        VertifyAuthority va = new VertifyAuthority();
        if (va.vertify(admin)){
            resp.getWriter().write("Login Success!");
        }else {
            resp.getWriter().write("Login Failed!");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

***VertifyAuthority.java

package com.howie.vertify;

import com.howie.pojo.Admin;
import com.howie.utils.JDBCUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * @Author weihuanwen
 * @Date 2019/8/5 19:25
 * @Version 1.0
 */
public class VertifyAuthority {

    public boolean vertify(Admin admin){
        try {
            Connection conn = JDBCUtils.getConnection();
            Statement stat = conn.createStatement();
            String sql = "SELECT * FROM `admin` WHERE `username`='"+admin.getUsername()+"' and `password`='"+admin.getPassword()+"'";
            ResultSet rs = stat.executeQuery(sql);
            if (rs.next()){
                return true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return false;
    }
}

3.测试:

①启动项目在前端页面中输入数据库中已存在的用户名和密码

②登录结果如下:

③输入数据库中不存在的用户名,且密码输入:[whatever' or 'a'='a]

④登录结果如下:

4.总结:

用户可以通过输入改变程序设计的sql语句的原本含义

二.预防SQL注入

1.代码修改

***VertifyAuthority.java

package com.howie.vertify;

import com.howie.pojo.Admin;
import com.howie.utils.JDBCUtils;

import java.sql.*;

/**
 * @Author weihuanwen
 * @Date 2019/8/5 21:09
 * @Version 1.0
 */
public class VertifyAuthority {

    public boolean vertify(Admin admin){
        try {
            Connection conn = JDBCUtils.getConnection();
            //sql语句中使用占位符
            String sql = "SELECT * FROM `admin` WHERE `username`=? and `password`=?";
            //获取sql语句预处理对象
            PreparedStatement ps = conn.prepareStatement(sql);
            //设置第一个占位符的值
            ps.setObject(1,admin.getUsername());
            //设置第二个占位符的值
            ps.setObject(2,admin.getPassword());
            //执行查询
            ResultSet rs = ps.executeQuery();
            if (rs.next()){
                return true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return false;
    }
}

2.测试

①输入数据库中不存在的用户名,且密码输入:[whatever' or 'a'='a]

②登录结果如下:

3.总结:

preparedStatement 会将sql语句预先编译,并且可以过滤掉用户的输入的关键字

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值