文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java最新SQL注入原因以及预防方案(易理解)

2024-12-03 14:10

关注

 前沿

在现有的框架中sql防注入已经做得很好了,我们需要做的就是尽量不要使用sql拼接调用

java sql注入原因以及预防方案(易理解)

SQL注入

1.1 原理

SQL注入是通过客户端的输入把SQL命令注入到一个应用的数据库中,从而执行恶意的SQL语句。

1.2 演示

1 案例1

有一个登录框,需要 输入用户名和密码 ,然后我们的密码输入 'or '123' = '123 这样的。我们在查询用户名和密码是否正确的时候,本来执行的sql语句是:select * from user where username = '' and password = ''. 这样的sql语句,现在我们输入密码是如上这样的,然后我们会通过参数进行拼接,拼接后的sql语句就是:

select * from user where username = '' and password = ' ' or '123' = '123 ';这样的了,那么会有一个or语句,只要这两个有一个是正确的话,就条件成立,因此 123 = 123 是成立的。因此验证就会被跳过。这只是一个简单的例子,

2 案例2

密码比如是这样的:'; drop table user;, 这样的话,那么sql命令就变成了:

select * from user where username = '' and password = ''; drop table user;', 那么这个时候我们会把user表直接删除了。

1.3 防范

1 前端

前端表单进行参数格式控制;

2 后端

注意: 永远也不要把未经检查的用户输入的值直接传给数据库

  1. package cn.javanode.thread; 
  2.  
  3. import java.util.regex.Pattern; 
  4.  
  5.  
  6. public class CheckSqlDemo { 
  7.  
  8.      
  9.     private static String reg = "(?:')|(?:--)|(/\\*(?:.|[\\n\\r])*?\\*/)|" 
  10.             + "(\\b(select|update|union|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute)\\b)"
  11.  
  12.  
  13.     private static Pattern sqlPattern = Pattern.compile(reg, Pattern.CASE_INSENSITIVE); 
  14.  
  15.     private static boolean isValid(String str) { 
  16.         if (sqlPattern.matcher(str).find()) 
  17.         { 
  18.             System.out.println("未能通过过滤器:str=" + str); 
  19.             return false
  20.         } 
  21.         return true
  22.     } 
  23.  
  24.     public static void main(String[] args) { 
  25.         System.out.println(isValid("tongji_user_add")); 
  26.     } 
  27.  

 补充

PreparedStatement是如何防止SQL注入的?

拼接参数(sql注入)

  1. Connection connection = DriverManager.getConnection(DB_URL, USER, PASS); 
  2.         PreparedStatement preparedStatement = connection.prepareStatement(sql);         
  3.         String param = "'test' or 1=1"
  4.         String sql = "select file from file where name = " + param; // 拼接SQL参数 
  5.         ResultSet resultSet = preparedStatement.executeQuery(); 
  6.         System.out.println(resultSet.next()); 

 输出结果为 true ,DB中执行的SQL为

  1. -- 永真条件1=1成为了查询条件的一部分,可以返回所有数据,造成了SQL注入问题 
  2. select file from file where name = 'test' or 1=1 

 2. setString (防注入) 

  1. Connection connection = DriverManager.getConnection(DB_URL, USER, PASS); 
  2.         PreparedStatement preparedStatement = connection.prepareStatement(sql);     
  3.         preparedStatement.setString(1,account);//设置参数 
  4.         preparedStatement.setString(2,password); 
  5.         ResultSet resultSet = preparedStatement.executeQuery();//执行查询sql,获取结果集 

 输出结果为 false ,DB中执行的SQL为 

  1. select file from file where name = '\'test\' or 1=1' 

我们可以看到输出的 SQL是把整个参数用引号包起来,并把参数中的引号作为转义字符,从而避免了参数也作为条件的一部分

源码分析

结论 

  1. //完整代码 
  2. public void setString(int parameterIndex, String x) throws SQLException { 
  3.        synchronized (checkClosed().getConnectionMutex()) { 
  4.            // if the passed string is nullthen set this column to null 
  5.            if (x == null) { 
  6.                setNull(parameterIndex, Types.CHAR); 
  7.            } else { 
  8.                checkClosed(); 
  9.  
  10.                int stringLength = x.length(); 
  11.  
  12.                if (this.connection.isNoBackslashEscapesSet()) { 
  13.                    // Scan for any nasty chars 
  14.                    // 判断是否需要转义 
  15.                    boolean needsHexEscape = isEscapeNeededForString(x, stringLength); 
  16.  
  17.                    if (!needsHexEscape) { 
  18.                        byte[] parameterAsBytes = null
  19.  
  20.                        StringBuilder quotedString = new StringBuilder(x.length() + 2); 
  21.                        quotedString.append('\''); 
  22.                        quotedString.append(x); 
  23.                        quotedString.append('\''); 
  24.  
  25.                        if (!this.isLoadDataQuery) { 
  26.                            parameterAsBytes = StringUtils.getBytes(quotedString.toString(), this.charConverter, this.charEncoding, 
  27.                                    this.connection.getServerCharset(), this.connection.parserKnowsUnicode(), getExceptionInterceptor()); 
  28.                        } else { 
  29.                            // Send with platform character encoding 
  30.                            parameterAsBytes = StringUtils.getBytes(quotedString.toString()); 
  31.                        } 
  32.  
  33.                        setInternal(parameterIndex, parameterAsBytes); 
  34.                    } else { 
  35.                        byte[] parameterAsBytes = null
  36.  
  37.                        if (!this.isLoadDataQuery) { 
  38.                            parameterAsBytes = StringUtils.getBytes(x, this.charConverter, this.charEncoding, this.connection.getServerCharset(), 
  39.                                    this.connection.parserKnowsUnicode(), getExceptionInterceptor()); 
  40.                        } else { 
  41.                            // Send with platform character encoding 
  42.                            parameterAsBytes = StringUtils.getBytes(x); 
  43.                        } 
  44.  
  45.                        setBytes(parameterIndex, parameterAsBytes); 
  46.                    } 
  47.  
  48.                    return
  49.                } 

 【编辑推荐】

  1. 一文教你探测虚拟环境是物理机、虚拟机还是容器?
  2. 比较9款代码质量工具,看看哪款更好用
  3. 推荐十个好用的程序员摸鱼网站,现在就给我玩起来!
  4. 2021年网络安全趋势:更高的预算,重点终端和云安全
  5. 为什么码农不应该在面试中同意进行编程测试

 

来源:今日头条内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯