详解SQL注入问题

一、代码漏洞根源

核心危险代码:

复制代码
// 直接拼接用户输入拼接SQL语句
String sql="select * from password where username='"+username+"'and password='"+password+"'";

使用 Statement + 字符串拼接 SQL ,用户输入的内容会直接拼入 SQL 语句,数据库会执行输入里的 SQL 逻辑,造成注入攻击。

二、注入攻击演示

1. 恶意输入

  • 用户名输入:

    1111

  • 密码输入:

    1' or '1' ='1

2. 拼接后最终执行 SQL,恒成立

复制代码
select * from password where username='1111'and password='1' or '1' ='1'

输出:

三、SQL 能登录成功的核心逻辑

数据库是这样计算的:

复制代码
where (条件A  and  条件B)  or  条件C
  • 条件 Ausername='1111'
  • 条件 Bpassword='1'
  • 条件 C'1'='1'永远成立!

最终结果:

复制代码
假 and 假  or  真
= 假 or 真
= 真

只要有一个条件成立,整个 WHERE 就成立!直接查到数据 → 登录成功!

本来想让数据库验证:

复制代码
用户名正确 并且 密码正确

结果被用户改成了:

复制代码
(用户名正确 并且 密码正确) 或者 1=1

1=1 永远是对的,所以不管用户名密码是什么,都能登录!


五、SQL 注入原理

用户输入的内容里带 SQL 语法,直接破坏了原本的查询逻辑,可以实现绕过密码登录。

  1. 前端用户输入带有 SQL 语法的特殊字符
  2. 后端无过滤,直接把输入拼入完整 SQL
  3. MySQL 识别拼接后的完整 SQL 并执行恶意逻辑
  4. 实现越权查询、篡改、删除数据

六、高危注入危害输入

  • 篡改全部数据
  • 直接删除数据表

七、解决方案(杜绝 SQL 注入)

  1. 放弃 Statement,使用 PreparedStatement 预编译对象
  2. 使用 ? 作为占位符替代字符串拼接
  3. 预编译会把用户输入全部当成普通文本,不会解析执行 SQL 语法

安全修复代码

复制代码
package com.qcby.sql;

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

public class LoginUtil {
    public static void main(String[] args) throws Exception{
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入用户名");
        String username=scanner.nextLine();
        System.out.println("请输入密码");
        String password=scanner.nextLine();
        safeLogin(username,password);
    }

    public static void safeLogin(String username,String pwd) throws Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        String url="你的数据库";
        String user="***";
        String password="****";
        Connection connection= DriverManager.getConnection(url,user,password);

        // 使用占位符,禁止字符串拼接
        String sql = "select * from password where username=? and password=?";
        PreparedStatement pstmt = connection.prepareStatement(sql);
        // 给占位符赋值
        pstmt.setString(1,username);
        pstmt.setString(2,pwd);

        ResultSet set=pstmt.executeQuery();
        if(set.next()){
            System.out.println("登录成功");
        }else{
            System.out.println("登录失败");
        }
        set.close();
        pstmt.close();
        connection.close();
    }
}
相关推荐
上海云盾-高防顾问几秒前
SD-WAN 跨境加速,真实日常使用体验
网络·网络安全
兜有米啦5 分钟前
数据库第二次作业
数据库
2401_8734794023 分钟前
SOC告警日志中IP归属不明怎么办?部署IP离线库三步提升响应效率
网络·网络协议·tcp/ip
Multipath71238 分钟前
多链路聚合 + 宽带自组网 + 卫星便携站,构筑应急通信“铁三角”乾元通多链路聚合路由破局“三断”绝境,重构应急通信生命线
网络·5g·安全·智能路由器·实时音视频
nVisual41 分钟前
机柜PDU安装位置与空间建模方案
大数据·网络·数据库·信息可视化·数据中心基础设施管理
weixin_66841 分钟前
Cursor-superpowers插件用法
数据库·人工智能
NWU_白杨1 小时前
三种常用的数据存储技术
数据库·redis·mysql·sqlite
吃饱了得干活1 小时前
亿级订单表分库分表设计,从0到1全流程
java·数据库·面试
蓝创工坊Blue Foundry1 小时前
图片文字提取到 Excel:批量任务如何先定义要交付的字段
运维·服务器·开发语言·数据库·自动化·ocr·excel
许彰午1 小时前
09-媒体访问控制
网络