前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SQL注入问题

SQL注入问题

作者头像
ZackSock
发布2020-02-14 13:58:08
1K0
发布2020-02-14 13:58:08
举报
文章被收录于专栏:ZackSockZackSock

sql注入是一种通过在输入中注入sql语句,来达到攻击数据库的效果。今天使用Java语言,来分析一下sql注入的相关问题。

一、什么是SQL注入

SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。

二、模拟SQL注入

我们先创建一个简单的数据库和一个user表:

代码语言:javascript
复制
create database test;
use database test;
create table user(username varchar(20), password(20));

我们在表中插入两个数据:

代码语言:javascript
复制
insert into user values('zack', '123456');
insert into user values('rudy', '123456');

我们再看一个简单的Java程序:

代码语言:javascript
复制
package com.zack.sql;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;

public class Sql {
  //链接的url
  private static String url = "jdbc:mysql:///all_test?serverTimezone=GMT";
  //用户名
  private static String user = "root";
  //密码
  private static String password = "123456";
  //用于输入
  Scanner sc = new Scanner(System.in);
  
  public static void main(String[] args) throws Exception {
    //加载驱动
    Class.forName("com.mysql.jdbc.Driver");
    //获取连接
    Connection conn = DriverManager.getConnection(url, user, password);
    //获取statment对象
    Statement stat = conn.createStatement();
    
    //要求用户输入用户名和密码
    System.out.println("请输入你的用户名:");
    String name = sc.next();
    System.out.println("请输入密码:");
    String pwd = sc.next();    
    
    //code1、通过用户输入的用户名和密码来查询数据库中是否存在该用户
    ResultSet set = stat.executeQuery("select * from user where username = '" + name + "' and password = '" + pwd + "'");

    //将匹配到的数据打印出来
    while(set.next()) {
      String username = set.getString("username");
      String password = set.getString("password");
      System.out.println("name:" + username + ", pwd:" + password);
    }
  }

}

我们看到code1,假设我们输入的如下:

代码语言:javascript
复制
zack
123456

这个正好是与我们数据库中匹配的,那么code1中执行的sql语句如下:

代码语言:javascript
复制
select * from user where username = 'zack' and password = '123456';

我们原本设想的是,如果输入不匹配的数据,将无法在数据库中查找到相应的东西,但是我们进行如下输入:

代码语言:javascript
复制
zack' or '1' = '1
111

这个时候,code1中执行的语句如下:

代码语言:javascript
复制
select * from user where username = 'zack' or '1'='1' and password = '123456';

其中’1’ = '1’是恒为真的,所以这个sql语句不会再去判断密码是否正确,这样就完成了SQL注入攻击的效果。

三、如何防止SQL注入

防止sql注入的方法也非常简单,在jdbc中有一个sql语句预编译的对象,我们可以通过PrepareStatement类来实现。假设我们还是要执行查询操作,执行语句如下:

代码语言:javascript
复制
String sql = "select * from user where username = ? and password = ?";

这里我们使用“?”来表示字段的值。然后我们来创建一个PrepareStatement对象,这里和Statement有些不一样:

代码语言:javascript
复制
//在创建PrepareStatement对象时,就传入了sql语句
PrepareStatement preStat = conn.prepareStatement(sql);

这里是在创建PrepareStatement对象时就传入了sql语句,而Statement是在执行查询操作时才传入sql语句。 因为我们已经传入了sql语句,所以在执行查询时不需要传入sql语句,但是要多一步匹配参数的操作:

代码语言:javascript
复制
//将name的值替换到sql语句中第一个?
preStet.setString(1, name);
//将name的值替换到sql语句中第二个?
preStat.setString(2, pwd);

其中name和pwd是我们输入的字符串变量。接下来我们就可以进行查询操作了:

代码语言:javascript
复制
ResultSet set = preStat.executeQuery();
while(set.next()) {
  String username = set.getString("username");
  String password = set.getString("password");
  System.out.println("name:" + username + ", pwd:" + password);
}

这里操作和之前类似,只是不需要传入sql语句。完整代码如下:

代码语言:javascript
复制
package com.zack.sql;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;

public class Sql {
  
  private static String url = "jdbc:mysql:///all_test?serverTimezone=GMT";
  private static String user = "root";
  private static String password = "123456";
  private static Scanner sc = new Scanner(System.in);
  private static String sql = "select * from user where username = ? and password = ?";
  
  public static void main(String[] args) throws Exception {
    //数据库操作
    Class.forName("com.mysql.jdbc.Driver");
    Connection conn = DriverManager.getConnection(url, user, password);
    PreparedStatement stat = conn.prepareStatement(sql);
    
    //要求用户输入用户名和密码
    System.out.println("请输入你的用户名:");
    String name = sc.next();
    System.out.println("请输入密码:");
    String pwd = sc.next();    
    
    //通过用户输入的用户名和密码来查询数据库中是否存在改用户
    stat.setString(1, name);
    stat.setString(2, pwd);
    ResultSet set = stat.executeQuery();
    while(set.next()) {
      String username = set.getString("username");
      String password = set.getString("password");
      System.out.println("name:" + username + ", pwd:" + password);
    }
  }

}
四、总结

SQL注入是早期比较流行的一种攻击数据库的方式,但现在很少会直接使用jdbc进行数据库操作,更不会直接使用sql语句拼接的方式进行操作。所以大多数情况SQL注入都是无效的,可能在一比较老的网址还是有效的,大家可以尝试一下。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 新建文件夹X 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 三、如何防止SQL注入
  • 四、总结
相关产品与服务
数据库专家服务
数据库专家服务(Database Expert Service,DBexpert)为您提供专业化的数据库服务。仅需提交您的具体问题和需求,即可获得腾讯云数据库专家的专业支持,助您解决各类专业化问题。腾讯云数据库专家服务团队均有10年以上的 DBA 经验,拥有亿级用户产品的数据库管理经验,以及丰富的服务经验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档