java sql注入例子

我着重強調幾點:

1、默認Statement和PreparedStatement,每次只能執行一條sql,對應mysql可以通過增加url參數&allowMultiQueries=true解決。

2、mysql的註釋,可以用#、"-- ",多行註釋/* */。若使用"-- ",注意後面要有一個空格

3、mysql的驅動已經修改爲com.mysql.cj.jdbc.Driver,英文意思是之前的已過期,新驅動會自動通過DriverManage類自動裝載,不需要人工操作。

Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.

自動裝載驅動是在java.sql.DriverManager.loadInitialDrivers(),DriverManage的static代碼塊中,會檢測jar包中的META-INF/services/java.sql.Driver路徑,就是不需要我們寫Class.forName()。

4、着重強調sql注入的危害性,drop表,查詢全表數據等,一定要使用PreparedStatement,或mybatis的#{},其他情況一定要校驗字符串中是否包含特色字符,譬如;、' 、 -- 、#等。要理解這些符號的使用場景

5、今天還驗證了like ?也可以通過PreparedStatement預編譯設置參數

代碼:

測試主類App.java

package com.nding.test;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.nding.common.DBUtil;

/**
 * Hello world!
 *
 */
public class App 
{
	private static Logger logger = LoggerFactory.getLogger(App.class);
    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );
        testLikeSql();
        
    }
    
    public static void testLikeSql() {
    	// 默認jdbc.url不能執行兩條sql,需要拼接參數allowMultiQueries=true
    	String name = "%\';delete from student where id=4 or \'\'= \' ";
    	name = "%\';-- \' ";
    	Connection conn = null;
    	PreparedStatement psmt = null;
    	ResultSet rs = null;
    	conn = DBUtil.getConnection();
    	// 模擬sql注入
    	String sql ="SELECT * FROM `student` where name like \'" + name + "%\';";
    	System.out.println("sql: " + sql);
    	try {
			psmt = conn.prepareStatement(sql);
//			psmt.setString(1, "k%");
			rs = psmt.executeQuery();
			System.out.println("id" + " " + "name"
					 + " " + "deptNo");
			while (rs.next()) {
				System.out.println(rs.getInt("id") + " " + rs.getString("name")
						 + " " + rs.getInt("deptNo"));
			}
		} catch (SQLException e) {
			logger.error("execute sql fail, sql: " + sql, e);
		} finally {
			DBUtil.closeResource(rs, psmt, conn);
			DBUtil.close();
		}
    	
    }
    
    
}

數據庫工具類DBUtil.java

package com.nding.common;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.util.IOUtils;

public class DBUtil {

	private static Logger logger = LoggerFactory.getLogger(DBUtil.class);
	
	private static Properties dbProps = new Properties();
	
	private static ThreadLocal<Connection> local = new ThreadLocal<Connection>();
	static {
		
		String className = null;
		try (InputStream is = DBUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");){
			dbProps.load(is);
			className = dbProps.getProperty("driver");
			Class.forName(className);
		} catch (ClassNotFoundException e) {
			logger.error("sql driver class: {} not found", className);
		} catch (IOException e1) {
			logger.error("load jdbc.properties fail", e1);
		}
		
	}
	public static Connection getConnection() {
		Connection conn = local.get();
		if (conn == null) {
			try {
				conn = DriverManager.getConnection(dbProps.getProperty("url"), dbProps.getProperty("username"),
						dbProps.getProperty("password"));
			} catch (SQLException e) {
				logger.error("getConnection fail, db config: " + JSON.toJSONString(dbProps), e);
			}
			local.set(conn);
		}
		
		return conn;
	}
	
	public static void close() {
		Connection conn = local.get();
		if (conn != null) {
			local.remove();
			conn = null;
		}
		
	}
	public static void closeResource(ResultSet rs, Statement stmt, Connection conn) {
		closeAutoCloseableResource(rs);
		closeAutoCloseableResource(stmt);
		closeAutoCloseableResource(conn);
	}
	
	private static void closeAutoCloseableResource(AutoCloseable resource) {
		if (resource != null) {
			try {
				resource.close();
			} catch (Exception e) {
				// ignore
			}
		}
	}
}

配置文件jdbc.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC&allowMultiQueries=true
username=root
password=123456

maven項目的pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.nding</groupId>
  <artifactId>test</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>test</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
	<dependency>
	    <groupId>cglib</groupId>
	    <artifactId>cglib</artifactId>
	    <version>3.2.6</version>
	</dependency>
			<dependency>
				<groupId>org.slf4j</groupId>
				<artifactId>slf4j-api</artifactId>
				<version>1.7.5</version>
			</dependency>
			<dependency>
				<groupId>ch.qos.logback</groupId>
				<artifactId>logback-classic</artifactId>
				<version>1.0.9</version>
			</dependency>
			<dependency>
				<groupId>ch.qos.logback</groupId>
				<artifactId>logback-core</artifactId>
				<version>1.0.9</version>
			</dependency>
			<dependency>
				<groupId>org.apache.commons</groupId>
				<artifactId>commons-lang3</artifactId>
				<version>3.1</version>
			</dependency>
			<dependency>
				<groupId>commons-fileupload</groupId>
				<artifactId>commons-fileupload</artifactId>
				<version>1.2.2</version>
			</dependency>
			<dependency>
				<groupId>commons-io</groupId>
				<artifactId>commons-io</artifactId>
				<version>2.0.1</version>
			</dependency>
			<dependency>
				<groupId>commons-beanutils</groupId>
				<artifactId>commons-beanutils</artifactId>
				<version>1.8.0</version>
			</dependency>
		<dependency>
		    <groupId>com.alibaba</groupId>
		    <artifactId>fastjson</artifactId>
		    <version>1.2.47</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>6.0.6</version> <!-- 6.0.6 -->
		</dependency>							    
  </dependencies>
  	<build>
  		<finalName>test</finalName>
    <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
        	<include>**/*.txt</include>
        </includes>
      </resource>
    </resources>  		

	</build>
</project>


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章