Java安全学习-SQL注入

SQL注入

SQL注入是因为程序未能正确对用户的输入进行检查,将用户的输入以拼接的方式带入SQL语句,导致了SQL注入的产生。攻击者可通过SQL注入直接获取数据库信息,造成信息泄漏。

JDBC

JDBC有两个方法执行SQL语句,分别是PrepareStatement和Statement。但是推荐使用PrepareStatement,因为PrepareStatement事先对语句进行预处理,能够很好地防护SQL注入攻击;而Statement没有进行预处理,因此不能防止SQL注入。

漏洞示例代码
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class JdbcTest {

    public static void main(String[] args) {
        String db_url="";
        String db_user="";
        String db_pass="";
        String id="";

        try {
            Connection connection = DriverManager.getConnection(db_url, db_user, db_pass);
            
            //要执行的sql语句
            String sql = "select * from users where id = '" + id + "'";
            //由于对要查询的sql语句使用的是Statement来进行处理,而不是预处理,因此在执行sql语句的时候就存在sql注入漏洞。
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery(sql);

            while (resultSet.next()){
                String user = resultSet.getString("user");
                String pass = resultSet.getString("pass");
                System.out.println("账号是:"+user+"\t密码是:"+pass);
            }

        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
漏洞修复代码(错误的示范)

即使使用到了PrepareStatement来对SQL语句进行处理,但是如果没有使用?作为占位符,而是直接采取拼接的方式构造SQL,此时进行预编译也无用。

import java.sql.*;

public class JdbcTest {
    public static void main(String[] args) {
        String db_url="";
        String db_user="";
        String db_pass="";
        String id="";

        try {
            Connection connection = DriverManager.getConnection(db_url, db_user, db_pass);
            
            //这里对sql语句没有采用?作为占位符,因此也是存在sql注入漏洞的
            String sql = "select * from users where id = '" + id + "'";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);

            ResultSet resultSet = preparedStatement.executeQuery(sql);

            while (resultSet.next()){
                String user = resultSet.getString("user");
                String pass = resultSet.getString("pass");
                System.out.println("账号是:"+user+"\t密码是:"+pass);
            }

        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
漏洞修复代码1

将要查询的数据换为?进行占位即可

import java.sql.*;

public class JdbcTest {
    public static void main(String[] args) {
        String db_url="";
        String db_user="";
        String db_pass="";
        String id="";

        try {
            Connection connection = DriverManager.getConnection(db_url, db_user, db_pass);
            
            //将要查询的数据换为?进行占位即可
            String sql = "select * from users where id = ?";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);

            ResultSet resultSet = preparedStatement.executeQuery(sql);

            while (resultSet.next()){
                String user = resultSet.getString("user");
                String pass = resultSet.getString("pass");
                System.out.println("账号是:"+user+"\t密码是:"+pass);
            }

        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
漏洞修复代码2

使用安全框架API进行漏洞的修复,该框架是owasp提供的一套API级别的web应用解决方案,可靠性很强。

import org.owasp.esapi.ESAPI;
import org.owasp.esapi.codecs.Codec;
import org.owasp.esapi.codecs.OracleCodec;

import java.sql.*;

public class JdbcTest {
    public static void main(String[] args) {
        String db_url="";
        String db_user="";
        String db_pass="";
        String id="";

        try {
            Connection connection = DriverManager.getConnection(db_url, db_user, db_pass);
            Codec<Character> oracleCodec = new OracleCodec();
            String sql = "select * from users where id = '"+ ESAPI.encoder().encodeForSQL(oracleCodec,id)+"'";
            Statement statement = connection.createStatement();

            ResultSet resultSet = statement.executeQuery(sql);

            while (resultSet.next()){
                String user = resultSet.getString("user");
                String pass = resultSet.getString("pass");
                System.out.println("账号是:"+user+"\t密码是:"+pass);
            }

        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值