java审计-JDBC注入审计

文章讲述了SQL注入攻击的原理,通过示例展示了攻击者如何利用这种漏洞获取敏感信息。然后讨论了解决方案,重点放在使用JDBC的预处理语句来防止SQL注入,尽管像LIKE和ORDERBY这样的操作需要额外处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

sql注入

基础

  • 在常见的web漏洞中,SQL注入漏洞较为常见,危害也较大。攻击者一旦利用系统中存在的SQL注入漏洞来发起攻击,在条件允许的情况下,不仅可以获取整站数据,还可通过进一步的渗透来获取服务器权限,从而进入内网。
  • 注入攻击的本质,是把用户输入的数据当做代码执行。这里有两个关键条件,第一个是用户能够控制输入;第二个是原本程序要执行的代码,拼接了用户输入的数据。接下来说下SQL注入漏洞的原理。

例子

  • 当用户发送GET请求:

    http://www.xxx.com/news.jsp?id=1
    
  • 这是一个新闻详情页面,会显示出新闻的title和content,程序内部会接收这个id参数传递给SQL语句,SQL如下:

    SELECT title,content FROM news WHERE id = 1
    
  • 这是SQL的原义,也是程序员想要得到的结果,但是如果用户改变了id的内容,修改成如下:

    http://www.jd.com/news.jsp?id=1 and 1=2 UNION SELECT username, password FROM admin
    
  • 此时内部程序执行的SQL语句为:这条SQL的原义就会被改变,导致将管理员数据表中的用户名显示在页面title位置,密码显示在页面content位置,攻击成功。

    SELECT title,content FROM news WHERE id = 1 and 1=2 UNION SELECT username, password FROM admin
    

解决

  • 参数过滤
  • 预处理

JDBC

基础

  • JDBC的连接是比较繁琐的,并且是最原始的连接方式,我们来看看JDBC的最原始的连接代码

例子-直接拼接where

   @GetMapping("/jdbc/vuln")
   //public String jdbc_sqli_vul(@RequestParam("username") String username) {
       public String jdbc_sqli_vul( String username) {

       StringBuilder result = new StringBuilder();

       try {
           Class.forName(driver);
           Connection con = DriverManager.getConnection(url, user, password);

           if (!con.isClosed())
               System.out.println("Connect to database successfully.");

           // sqli vuln code
           Statement statement = con.createStatement();
           String sql = "select * from users where username = '" + username + "'";
           logger.info(sql);
           ResultSet rs = statement.executeQuery(sql);

           while (rs.next()) {
               String res_name = rs.getString("username");
               String res_pwd = rs.getString("password");
               String info = String.format("%s: %s\n", res_name, res_pwd);
               result.append(info);
               logger.info(info);
           }
           rs.close();
           con.close();

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

解决

  • 参数过滤
  • 预处理

例子-like预处理写法

  • 错误写法

    // error code
     String sql = "select * from users where username like %?%";
     PreparedStatement st = con.prepareStatement(sql);
     st.setString(1, username);
    
  • 正确写法

    // fix code
    String sql = "select * from users where username like ?";
    PreparedStatement st = con.prepareStatement(sql);
    st.setString(1, "%"+username+"%");
    
    logger.info(st.toString());  // sql after prepare statement
    ResultSet rs = st.executeQuery();
    

例子-order by 预处理写法

  • 错误写法

    String sql = "select * from users where username order by ?";
    PreparedStatement st = con.prepareStatement(sql);
    st.setString(1, username);
    

在这里插入图片描述

  • 正确写法
    • 写死order by

总结

  • jdbc方式进行拼接的,可以直接使用预处理来规避sql注入,但是如果有like、order by 进行参数拼接不能直接使用预处理来解决,必须在set处把%拼接上。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值