JDBC如何避免SQL注入

JDBC如何避免SQL注入

一 . 什么是SQL注入

SQL注入(SQL Injection)是一种代码注入技术,它允许攻击者将或“注入”恶意的SQL命令到后端数据库引擎执行。这些恶意的SQL命令可以执行未授权的数据库查询、修改数据、管理数据库服务器上的文件系统、执行管理操作(如关闭数据库服务)等,从而可能对网站或应用程序造成严重的安全威胁。

假设有一个简单的Web应用程序,它使用以下SQL查询来根据用户提供的用户名查找用户信息:

SELECT * FROM users WHERE username = '' + @username + ''

如果用户输入了admin'--(注意末尾的--是SQL注释的开始),那么生成的SQL查询将变为:

SELECT * FROM users WHERE username = 'admin'--'

由于--之后的任何内容都被视为注释,因此查询实际上变成了:

SELECT * FROM users WHERE username = 'admin'

这允许攻击者绕过正常的验证逻辑,直接以admin用户的身份检索信息,即使他们不知道admin用户的密码。

二 . 如何避免?

使用PreparedStatement解决SQL注入问题

PreparedStatement 在 Java 中是避免 SQL 注入的一种有效手段。它通过使用参数化查询来工作,这种方式确保了用户输入被当作数据而不是 SQL 代码的一部分来执行。以下是 `PreparedStatement如何避免 SQL 注入的详细解释:

1. 参数化查询

当你使用PreparedStatement 时,你首先编写一个带有占位符(通常是 ?)的 SQL 语句。然后,你通过 set 方法(如 setInt(), setString() 等)为这些占位符提供具体的值。这些值在运行时被绑定到 SQL 语句中,而不是在 SQL 语句被解析或编译时。

2. 编译一次,执行多次

PreparedStatement对象在数据库中被编译一次,但可以被执行多次,每次执行时只需替换占位符的值。这种机制不仅提高了性能(因为避免了重复的编译),还增强了安全性,因为 SQL 语句的结构在编译时就已经固定,不会被后续的用户输入所改变。

3. 防止 SQL 注入

由于 PreparedStatement 使用占位符和参数绑定机制,用户输入的数据被当作数据值来处理,而不是 SQL 代码的一部分。这意味着即使输入中包含 SQL 关键字、特殊字符或注释等,它们也不会被数据库解析为 SQL 语句的一部分,从而避免了 SQL 注入攻击。

我们来看下列代码 , 这里进行了一个登录的校验 , 使用

connection.prepareStatement("SELECT * FROM user WHERE username = ? AND password = ?");

这样就可以有效避免sql注入问题

package com.Month08.Day_11;

import com.Month07.Day_02.Class1;

import java.sql.*;
import java.util.Scanner;

public class HDBC {

    public static void main(String[] args) throws ClassNotFoundException, SQLException {


//        statement.executeUpdate("insert into user(username , password) values (123,123)");


        select();

    }


    public static void select()throws ClassNotFoundException, SQLException {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用户名");
        int username = sc.nextInt();
        System.out.println("请输入密码");
        int password = sc.nextInt();

        Class.forName("com.mysql.jdbc.Driver");

        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/users","root","root");

        PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM user WHERE username = ? AND password = ?");

        preparedStatement.setInt(1,username);
        preparedStatement.setInt(2,password);

        ResultSet resultSet = preparedStatement.executeQuery();
        while (resultSet.next()){
            System.out.println("登陆成功");
        }

        connection.close();


    }
}

在这里插入图片描述

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

攒了一袋星辰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值