Java学习笔记47(JDBC、SQL注入攻击原理以及解决)

JDBC:java的数据库连接

JDBC本质是一套API,由开发公司定义的类和接口

这里使用mysql驱动,是一套类库,实现了接口

驱动程序类库,实现接口重写方法,由驱动程序操作数据库

JDBC操作步骤:

1.注册驱动

2.获得连接

3.获得语句执行平台

4.执行sql语句

5.处理结果

6.释放资源

1.导入jar包,可以在网上下载到,这里使用的是:mysql-connector-java-5.1.37-bin.jar

注册驱动:

package demo;

import java.sql.DriverManager;
import java.sql.SQLException;

import com.mysql.jdbc.Driver;

public class JDBCDemo {
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        //注册驱动
        //DriverManager.registerDriver(new Driver());
        //不推荐上边这种方法,建议用反射技术,将驱动类加入内存
        Class.forName("com.mysql.jdbc.Driver");
    }
}

2.获得连接:

package demo;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class JDBCDemo {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.jdbc.Driver");
        //获得数据库连接
        String url = "jdbc:mysql://localhost:3306/mybase";
        String username = "root";
        String password = "xuyiqing";
        Connection con = DriverManager.getConnection(url,username,password);
        System.out.println(con);
    }
}

3.获取语句执行平台

通过数据库连接对象,获取到sql语句的执行者对象

package demo;

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

public class JDBCDemo {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/mybase";
        String username = "root";
        String password = "xuyiqing";
        Connection con = DriverManager.getConnection(url,username,password);
        //获取语句执行平台
        Statement stat = con.createStatement();
        System.out.println(stat);
    }
}

4.执行sql语句:

准备数据:

CREATE TABLE sort(
    sid INT PRIMARY KEY AUTO_INCREMENT,
    sname VARCHAR(100),
    sprice DOUBLE,
    sdesc VARCHAR(5000)
    );
INSERT INTO sort(sname,sprice,sdesc) VALUES(‘家电‘,2000,‘促销‘),
(‘家具‘,8900,‘价格上涨‘),
(‘玩具‘,300,‘赚钱‘),
(‘生鲜‘,500.99,‘促销‘),
(‘服装‘,24000,‘促销‘),
(‘洗涤‘,50,‘促销‘);

SELECT * FROM sort;

执行sql语句:

1.增删改

package demo;

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

public class JDBCDemo {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/mybase";
        String username = "root";
        String password = "xuyiqing";
        Connection con = DriverManager.getConnection(url,username,password);
        Statement stat = con.createStatement();
        //执行sql语句
        //这种方法注意:只能使用insert,delete,update语句
        int row = stat.executeUpdate("INSERT INTO sort(sname,sprice,sdesc) VALUES(‘汽车‘,2000,‘促销‘);");
        System.out.println(row);
        //释放资源
        stat.close();
        con.close();
    }
}

2.查询

package demo;

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

public class JDBCDemo {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/mybase";
        String username = "root";
        String password = "xuyiqing";
        Connection con = DriverManager.getConnection(url,username,password);
        Statement stat = con.createStatement();
        //查询sql语句
        String sql= "SELECT * FROM sort";
        //这个方法用于执行sql中的select查询
        ResultSet rs = stat.executeQuery(sql);
        //处理结果集
        while(rs.next()){
            //获取每列数据
            System.out.println(rs.getInt("sid")+"   "+rs.getString("sname")+
                    "   "+rs.getDouble("sprice")+"   "+rs.getString("sdesc"));
        }
        rs.close();
        stat.close();
        con.close();
    }
}

输出:

SQL注入攻击简单案例:

CREATE TABLE users(
     id INT PRIMARY KEY AUTO_INCREMENT,
     username VARCHAR(100),
     PASSWORD VARCHAR(100)
);

INSERT INTO users (username,PASSWORD) VALUES (‘a‘,‘1‘),(‘b‘,‘2‘);
package demo;

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

/*
 *  Java程序实现用户登录,用户名和密码,数据库检查
 *  演示被别人注入攻击
 */
public class JDBCDemo {
    public static void main(String[] args)throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/mybase";
        String username = "root";
        String password = "xuyiqing";
        Connection con = DriverManager.getConnection(url, username, password);
        Statement stat = con.createStatement();

        Scanner sc = new Scanner(System.in);
        String user = sc.nextLine();
        String pass = sc.nextLine();

        //执行SQL语句,数据表,查询用户名和密码,如果存在,登录成功,不存在登录失败
        String sql = "SELECT * FROM users WHERE username=‘"+user+"‘ AND PASSWORD=‘"+pass+"‘";
        System.out.println(sql);
        ResultSet rs = stat.executeQuery(sql);
        while(rs.next()){
            System.out.println(rs.getString("username")+"   "+rs.getString("password"));
        }

        rs.close();
        stat.close();
        con.close();
    }
}

正常情况,必须输入a,1或者b,2才可以登录成功

这里如果这样输入:

1=1恒成立,or两边只要有一边成立就会成功,这里就实现了最简单的sql注入攻击

解决:

使用PrepareStatement接口

package demo;

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

/*
 *  Java程序实现用户登录,用户名和密码,数据库检查
 *  防止注入攻击
 *  Statement接口实现类,作用执行SQL语句,返回结果集
 *  有一个子接口PreparedStatement  (SQL预编译存储,多次高效的执行SQL)
 *  PreparedStatement的实现类数据库的驱动中,如何获取接口的实现类
 *
 *  是Connection数据库连接对象的方法
 *  PreparedStatement prepareStatement(String sql) 

 */
public class JDBCDemo {
    public static void main(String[] args)throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/mybase";
        String username = "root";
        String password = "xuyiqing";
        Connection con = DriverManager.getConnection(url, username, password);
        Scanner sc = new Scanner(System.in);
        String user = sc.nextLine();
        String pass = sc.nextLine();

        //执行SQL语句,数据表,查询用户名和密码,如果存在,登录成功,不存在登录失败
        String sql = "SELECT * FROM users WHERE username=? AND PASSWORD=?";
        //调用Connection接口的方法prepareStatement,获取PrepareStatement接口的实现类
        //方法中参数,SQL语句中的参数全部采用问号占位符
        PreparedStatement pst =  con.prepareStatement(sql);
        System.out.println(pst);
        //调用pst对象set方法,设置问号占位符上的参数
        pst.setObject(1, user);
        pst.setObject(2, pass);

        //调用方法,执行SQL,获取结果集
        ResultSet rs = pst.executeQuery();
        while(rs.next()){
            System.out.println(rs.getString("username")+"   "+rs.getString("password"));
        }

        rs.close();
        pst.close();
        con.close();
    }
}

发现这个接口更安全,所以建议使用这个接口实现增删改查

使用PrepareStatement接口,实现数据表的更新操作

package demo;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

/*
 *  使用PrepareStatement接口,实现数据表的更新操作
 */
public class JDBCDemo {
    public static void main(String[] args) throws Exception{
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/mybase";
        String username="root";
        String password="xuyiqing";
        Connection con = DriverManager.getConnection(url, username, password);    

        //拼写修改的SQL语句,参数采用?占位
        String sql = "UPDATE sort SET sname=?,sprice=? WHERE sid=?";
        //调用数据库连接对象con的方法prepareStatement获取SQL语句的预编译对象
        PreparedStatement pst = con.prepareStatement(sql);
        //调用pst的方法setXXX设置?占位
        pst.setObject(1, "车");
        pst.setObject(2, 49988);
        pst.setObject(3, 7);
        //调用pst方法执行SQL语句
        pst.executeUpdate();

        pst.close();
        con.close();
    }
}

PrepareStatement接口实现数据表的查询操作

package demo;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

/*
 *  PrepareStatement接口实现数据表的查询操作
 */
public class JDBCDemo {
    public static void main(String[] args) throws Exception{
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/mybase";
        String username="root";
        String password="xuyiqing";
        Connection con = DriverManager.getConnection(url, username, password);    

        String sql = "SELECT * FROM sort";

        PreparedStatement pst = con.prepareStatement(sql);

        //调用pst对象的方法,执行查询语句,Select
        ResultSet rs=pst.executeQuery();
        while(rs.next()){
            System.out.println(rs.getString("sid")+"  "+rs.getString("sname")+"  "+rs.getString("sprice")+"  "+rs.getString("sdesc"));
        }
        rs.close();
        pst.close();
        con.close();
    }
}

原文地址:https://www.cnblogs.com/xuyiqing/p/8323664.html

时间: 2024-10-09 19:54:06

Java学习笔记47(JDBC、SQL注入攻击原理以及解决)的相关文章

渗透学习笔记--基础篇--sql注入(字符型)

环境:dvwa1.7数据库:mysql前置知识:sql语句(Click me)      在进行sql注入前,我们先熟悉熟悉select语句.一.打开我们的sql终端 二.进入之后可以看到有mysql>我们输入sql语句,即可返回我们想要的结果,注意分号哟!我们使用的dvwa,在我们前几章设置的时候,会在数据库中生成一个dvwa的database:这里我们使用它来进行我们的select 语句:(1)使用dvwa数据库use dvwa;(2)在users表里查询用户名为'admin'的所有信息se

渗透学习笔记--基础篇--sql注入(数字型)

环境:dvwa 1.7数据库:mysql dvwa的安全等级:medium 一.分析和查找注入点(1)知识点回顾如果上一篇有好好读过的同学应该知道,我们上一篇遇到的字符型注入.也即是通过Get或者Post方式传进去的数据被单引号或者双引号包裹住.如果我们想要注入自己的payload(有效载荷)的话,则我们必须先闭合前面的单引号或者双引号,否则我们的数据始终会被当做成字符串来处理. 这种类型的注入点称为字符型注入点. (2)这次我们的把防御等级提升了一个层次,来逐步加强我们手工注入的能力以及开更多

【荐】PDO防 SQL注入攻击 原理分析 以及 使用PDO的注意事项

我们都知道,只要合理正确使用PDO,可以基本上防止SQL注入的产生,本文主要回答以下几个问题: 为什么要使用PDO而不是mysql_connect? 为何PDO能防注入? 使用PDO防注入的时候应该特别注意什么? 一.为何要优先使用PDO? PHP手册上说得很清楚: Prepared statements and stored procedures Many of the more mature databases support the concept of prepared statemen

Java学习笔记45(多线程二:安全问题以及解决原理)

线程安全问题以及解决原理: 多个线程用一个共享数据时候出现安全问题 一个经典案例: 电影院卖票,共有100座位,最多卖100张票,买票方式有多种,网上购买.自主售票机.排队购买 三种方式操作同一个共享数据,这时候会出现安全问题: 示例: package demo1; public class Tickets implements Runnable { private int ticket = 100; public void run(){ while(true){ if (ticket>0) {

防止SQL注入攻击

SQL注入攻击的危害性很大.在讲解其防止办法之前,数据库管理员有必要先了解一下其攻击的原理.这有利于管理员采取有针对性的防治措施. 一. SQL注入攻击的简单示例. statement := "SELECT * FROM Users WHERE Value= " + a_variable + " 上面这条语句是很普通的一条SQL语句,他主要实现的功能就是让用户输入一个员工编号然后查询处这个员工的信息.但是若这条语句被不法攻击者改装过后,就可能成为破坏数据的黑手.如攻击者在输入

Java程序员从笨鸟到菜鸟之(一百)sql注入攻击详解(一)sql注入原理详解

前段时间,在很多博客和微博中暴漏出了12306铁道部网站的一些漏洞,作为这么大的一个项目,要说有漏洞也不是没可能,但其漏洞确是一些菜鸟级程序员才会犯的错误.其实sql注入漏洞就是一个.作为一个菜鸟小程序员,我对sql注入的东西了解的也不深入,所以抽出时间专门学习了一下.现在把学习成果分享给大家,希望可以帮助大家学习.下面我们就来看一下. 一.什么是sql注入呢?         所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的

JAVA学习笔记 -- JDBC及其应用

一.准备工作 1.开启SQL Server服务和启用TCP/IP  并且确认TCP端口 2.Eclipse下给项目导入sqljdbc4.jar包 将下载好的 sqljdbc_4.0.2206.100_chs.exe运行解压.然后在 .\Microsoft JDBC Driver 4.0 for SQL Server\sqljdbc_4.0\chs\auth 路径下选择合适版本的sqljdbc_auth.dll, 将其放在 C:\Windows\System32下. 给项目导入包:右键你的项目选择

jdbc_012_使用jdbc操作实现登录操作并且演示SQL注入攻击

一.建库及表语句(简单测试) drop database db_test; create database db_test; use db_test; create table user( userId int(5) primary key comment '用户id', userName varchar(16) comment '用户姓名', userPw varchar(16) comment '用户密码' ); insert into user(userId,userName,userPw

Java程序员从笨鸟到菜鸟之(一百零一)sql注入攻击详解(二)sql注入过程详解

在上篇博客中我们分析了sql注入的原理,今天我们就来看一下sql注入的整体过程,也就是说如何进行sql注入,由于本人数据库和网络方面知识有限,此文章是对网上大量同类文章的分析与总结,其中有不少直接引用,参考文章太多,没有注意出处,请原作者见谅) SQL注入攻击的总体思路是: 1.发现SQL注入位置: 2.判断后台数据库类型: 3.确定XP_CMDSHELL可执行情况 4.发现WEB虚拟目录 5. 上传ASP木马: 6.得到管理员权限: 一.SQL注入漏洞的判断 一般来说,SQL注入一般存在于形如