当前位置: 首页 > news >正文

14.jdbc第三步PreparedStatement防sql注入

1.首先要明白什么是sql注入、怎么做

  • ①sql注入理解: 通过将不可信输入伪装成 SQL 语法片段,篡改原始 SQL 的语法结构,迫使数据库执行非预期的非法操作。

  • ② 怎样做

    • 通过 URL 参数传参或者其他传参方式将含有sql语法的参数传递给服务器

      恶意请求:http://你的网站/user?id=1'%20OR%20'1'='1
      (注:URL 中不能直接传空格 / 单引号,需 URL 编码:'编码为%27,空格编码为%20,最终拼接后的id仍是1' OR '1'='1);
      即传到服务器端后id = 1' OR '1'='1
      
    • 服务器端处理

              // 拼接SQL(核心风险点)String sql = "SELECT * FROM user WHERE id = '" + id + "'";//即:SELECT * FROM user WHERE id = '1' OR '1'='1'// 执行SQLStatement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery(sql);
      

      核心总结:注入的实现本质 ,利用字符串拼接,让参数变成SQL 语法的一部分;插入 OR/AND/DELETE/UPDATE 等 SQL 关键字,篡改执行逻辑;

2.防 SQL 注入的核心原则:让输入永远只做数据,不做语法

  • ① 先明确核心差异:Statement vs PreparedStatement 源码级执行逻辑

    特性StatementPreparedStatement
    SQL 处理时机执行时才解析、编译 SQL(每次都重新来)先预编译 SQL 结构,执行时仅代入参数(复用编译结果)
    注入风险极高(参数可篡改语法)无(参数仅为数据,不参与语法解析)
  • PreparedStatement 如何防注入?

    参数绑定阶段

    // PreparedStatementImpl的setString方法
    public void setString(int parameterIndex, String x) throws SQLException {synchronized (this.getConnectionMutex()) {// 步骤1:校验参数索引(避免越界)checkClosed();// 步骤2:对参数值做「安全转义」(核心!)// 比如把单引号 ' 转义为 '',把 \ 转义为 \\String escapedValue = escapeString(x);// 步骤3:将转义后的参数值存入「参数数组」,不修改原SQL结构this.parameterValues[parameterIndex - 1] = escapedValue;this.parameterTypes[parameterIndex - 1] = Types.VARCHAR;}
    }//escapeString(x)实现
    package com.mysql.cj.util;public class StringUtils {/*** 转义字符串中的特殊字符,适配MySQL的字符串字面量规则* @param str 待转义的用户输入参数* @param connection 数据库连接(获取字符集/转义配置)* @return 转义后的安全字符串*/public static String escapeString(String str, Connection connection) {if (str == null) {return null;}StringBuilder sb = new StringBuilder(str.length() * 2); // 预扩容,避免频繁扩容char[] chars = str.toCharArray();for (char c : chars) {switch (c) {// 1. 核心转义:单引号(SQL注入最常用的边界符)case '\'':sb.append("''"); // MySQL中用两个单引号转义一个单引号break;// 2. 转义反斜杠(避免攻击者用反斜杠绕过转义)case '\\':sb.append("\\\\");break;// 3. 转义换行符(避免换行截断SQL,或注入多行注释)case '\n':sb.append("\\n");break;// 4. 转义回车符case '\r':sb.append("\\r");break;// 5. 转义水平制表符case '\t':sb.append("\\t");break;// 6. 转义换页符case '\014':sb.append("\\f");break;// 7. 转义空字符(避免数据库解析异常)case '\0':sb.append("\\0");break;// 其他普通字符:直接追加,不处理default:sb.append(c);break;}}return sb.toString();}
    }
    

    核心动作:驱动自动转义参数中的特殊字符(如 1' OR '1'='1 会被转义为 1'' OR ''1''=''1),确保参数仅为纯数据。

http://www.gsyq.cn/news/73635.html

相关文章:

  • java
  • 详细介绍:【STL源码剖析】从源码看 heap:元素的 “下沉” 与 “上浮”
  • 大信息环境搭建从零开始(十四)CentOS 7 系统更新源更换详解:阿里云镜像源配置完整指南
  • 实用指南:Vue编程式路由导航
  • 【Java】String
  • 拒绝智商税!2025最新学习机榜单发布,十大热门机型横向对比,一看就懂
  • 2025年留学生求职机构排名推荐指南 途鸽求职榜首领跑赛道
  • 网络安全的守护与利器:r/netsec 月度技术讨论与工具分享
  • 重组蛋白表达纯化技术流程解析:从基因到蛋白的精准制备
  • 软件测试的分类1(含黑盒测试、白盒测试、Alpha测试、Beta测试、灰盒测试)
  • 全国中医师承选哪个机构靠谱?——在对比多家机构后最终选择了阿虎医考师承
  • 【Java】ArrayList
  • 小白必看!CAD 超详细安装教程
  • Java中的反射
  • 子弹射击
  • 安装Vivado
  • 解码类进阶核心——静态成员、this 指针、动态内存与友元机制
  • VIVADO 2023.2 license 可使用至2037年文件备份
  • 2025年度总评:国潮花灯生产厂商终极榜单发布,天幕花灯/春节花灯/古镇花灯/智能花灯/互动花灯/营销花灯/大型花灯花灯供货厂家排行榜单
  • ai生成一段学习golang的select、context、go、channel的代码
  • 背离
  • 银河麒麟V10 申威架构 docker-compose rpm 包安装教程(附命令)
  • 【Linux】服务器开启 ssh 服务 ssh 相关配置
  • 2025 省选 炼石计划 梦熊模拟赛 记录
  • SFT微调
  • 讲一讲 Transformer 在脑电 EEG 里的作用
  • 贪心算法之: 田忌赛马
  • 49
  • 小游戏联机服务开发实践:从零构建房间匹配与帧同步系统
  • PbootCMS登录失败:数据库目录写入权限不足!