预编译

编译器在编译sql语句时,会依次进行词法分析、语法分析、语义分析等操作,

预编译技术会让数据库跳过编译阶段,也就无法就进行词法分析,关键字不会被拆开,注入语句也就不会被识别为SQL的关键字,从而防止恶意注入语句改变原有SQL语句本身逻辑。

Java_JDBC注入

在使用JDBC进行数据库操作时,有以下几种情况会产生SQL注入问题

  • 使用Statement方法单纯拼接SQL语句

    演示代码
// 采用Statement方法拼接SQL语句,导致注入产生

public String vul1(String id) {

    Class.forName("com.mysql.cj.jdbc.Driver");//加载数据库驱动程序
Connection conn = DriverManager.getConnection(db_url, db_user, db_pass);//建立数据库连接 Statement stmt = conn.createStatement();//创建Statement对象用来执行sql语句 String sql = "select * from users where id = '" + id + "'"; // 拼接语句产生SQL注入
ResultSet rs = stmt.executeQuery(sql);//返回SQL语句执行结果
...
}

使用拼接方法进行SQL语句查询,预防SQL代码的方式可以采用黑名单过滤等方法

  • PrepareStatement错误使用预编译

    演示代码
// PrepareStatement会对SQL语句进行预编译,但如果直接采取拼接的方式构造SQL,此时进行预编译也无用。

public String vul2(String id) {
Class.forName("com.mysql.cj.jdbc.Driver");//加载数据库驱动程序
Connection conn = DriverManager.getConnection(db_url, db_user, db_pass);//建立数据库连接
String sql = "select * from users where id = " + id;// 拼接语句产生SQL注入
PreparedStatement st = conn.prepareStatement(sql);//创建预编译对象接受SQL语句
ResultSet rs = st.executeQuery();//返回SQL语句执行结果
}

代码中虽然采用了预编译的方式进行SQL执行,但是依然在构造SQL语句时进行了拼接参数,这样无任何意义,依然可以进行拼接SQL注入

正确使用预编译即可防止SQL注入

// 正确的使用PrepareStatement可以有效避免SQL注入,使用?作为占位符,进行参数化查询

public String safe1(String id) {
String sql = "select * from users where id = ?";
PreparedStatement st = conn.prepareStatement(sql);
st.setString(1, id);
ResultSet rs = st.executeQuery();
}
Statement和PreparedStatement是Java JDBC API中两种常用的执行SQL语句的方式
Statement:
Statement对象用于执行静态SQL语句,即在编译时已经确定了SQL语句的结构。
Statement执行SQL语句时,直接将完整的SQL语句发送给数据库执行。
Statement对象适用于执行不带参数的简单SQL查询或更新操作。
由于Statement对象没有预编译阶段,每次执行SQL语句时都需要将SQL语句编译一次,这可能导致一定的性能开销。
由于没有参数化输入的机制,使用Statement对象时需要谨慎处理输入数据,以防止SQL注入攻击。
PreparedStatement:
PreparedStatement对象用于执行动态SQL语句,即在执行时才确定SQL语句的具体参数值。
PreparedStatement对象在创建时需要提供一个SQL模板,其中的参数使用占位符(例如,“?”)表示。
在执行PreparedStatement时,首先会对SQL语句进行编译和优化,然后只需提供参数值,而不需要重新编译SQL语句。
PreparedStatement适用于频繁执行带有参数的SQL语句,如参数化查询。
由于PreparedStatement具有预编译和参数化输入的特性,可以提高性能和安全性,并且能够防止SQL注入攻击。

Java_MyBatis注入

#{name}和${name}是MyBatis中两种常用的参数传递方式,具有不同的行为和特点
#{name}(参数占位符):
是一种安全的参数传递方式,会自动进行参数值的转义和处理,防止SQL注入攻击
使用#{name}时,MyBatis会将参数值作为预编译的参数,将其安全地插入到SQL语句中。
-----------------------------------------------------------------------------
${name}(文本替换):
${name} 是一种简单的文本替换方式,它会将 ${name} 直接替换为参数值,不进行参数值的转义或处理。
使用${name}时,参数值会被直接拼接到SQL语句中,存在SQL注入的风险。

在使用MyBatis进行SQL操作时,并不是所有SQL语句都可以进行预编译

  • order by注入

    错误代码
// 由于使用#{}会将对象转成字符串,形成order by "user" desc造成错误,因此很多研发会采用${}来解决,从而造成SQL注入

@GetMapping("/vul/order")
public List<User> orderBy(String field, String sort) {
return userMapper.orderBy(field, sort);
} // xml方式
<select id="orderBy" resultType="com.best.hello.entity.User">
select * from users order by ${field} ${sort}
</select> // 注解方式
@Select("select * from users order by ${field} desc")
List<User> orderBy2(@Param("field") String field);
  • like模糊查询注入

    错误代码
// 模糊搜索时,直接使用'%#{q}%' 会报错,部分研发图方便直接改成'%${q}%'从而造成注入

@Select("select * from users where user like '%${q}%'")
List<User> search(String q);

安全代码

// 安全代码,采用concat
@Select("select * from users where user like concat('%',#{q},'%')")
List<User> search(String q);

关于MyBatis并不是所有语句都可以采用#{name}的方式,其实就是如果需要用数据库表的字段来替换的话就不能用参数绑定

更多MyBatis防止SQL注入参考

在进行代码审计时,由于MyBatisSQL错误语法的明显特征,可使用全局搜索特征关键字%${、${来查看是否存在注入,从而进一步分析。

XXE注入

在Java中的XXE注入与PHP中的XXE注入原理没有任何区别,只是在Java中所实现XML数据解析所用的方法不同,以下是在Java中常用于处理XML数据的相关接口、类、工具等

XMLReader

SAXReader

DocumentBuilder

XMLStreamReader

SAXBuilder

SAXParser

SAXSource

TransformerFactory

SAXTransformerFactory

SchemaFactory

Unmarshaller

XPathExpression

相应的防护措施为禁用外部实体或者使用黑名单过滤,所使用处理XML数据的相关接口等不同,禁用外部实体的语句也不同。

SSTI模板注入

模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,利用模板引擎来生成前端的html代码,模板引擎会提供一套生成html代码的程序,然后只需要获取用户的数据,然后放到渲染函数里,然后生成模板+用户数据的前端html页面,然后反馈给浏览器,呈现在用户面前。

当前使用的一些框架,比如python的flask,php的tp,java的spring等一般都采用成熟的的MVC的模式,用户的输入先进入Controller控制器,然后根据请求类型和请求的指令发送给对应Model业务模型进行业务逻辑判断,数据库存取,最后把结果返回给View视图层,经过模板渲染展示给用户。

漏洞成因就是服务端接收了用户的恶意输入以后,未经任何处理就将其作为 Web 应用模板内容的一部分,模板引擎在进行目标编译渲染的过程中,执行了用户插入的可以破坏模板的语句,因而可能导致了敏感信息泄露、代码执行、GetShell 等问题。其影响范围主要取决于模版引擎的复杂性。

php常见的模板:twig,smarty,blade

python常见的模板有:Jinja2,tornado

java常见的引擎:FreeMarker, velocity

具体参考SSTI(模板注入)漏洞(入门篇)

SPEL表达式注入

说白了就是RCE命令执行

详情参考JAVA表达式注入漏洞

以上内容仅作学习记录,如有错误或瑕疵,欢迎批评指正,感谢阅读。

Web攻防--Java_SQL注入--XXE注入-- SSTI模板注入--SPEL表达式注入的更多相关文章

  1. SpEL表达式注入漏洞学习和回显poc研究

    目录 前言 环境 基础学习和回显实验 语法基础 回显实验 BufferedReader Scanner SpEL漏洞复现 低版本SpringBoot中IllegalStateException CVE ...

  2. 一文详解SpEL表达式注入漏洞

    摘要:本文介绍了SpEL表达式以及常见的SpEL注入攻击,详细地介绍了部分漏洞攻击实例以及常用的漏洞检测与防御手段. 本文分享自华为云社区<SpEL表达式注入漏洞分析.检查与防御>,作者: ...

  3. SpringBoot SpEL表达式注入漏洞-分析与复现

    目录 0x00前言 0x01触发原因 0x02调试分析 0x03补丁分析 0x04参考文章 影响版本: 1.1.0-1.1.12 1.2.0-1.2.7 1.3.0 修复方案:升至1.3.1或以上版本 ...

  4. java代码审计-SpEL表达式注入

    0x01 前言 Spring Expression Language(简称 SpEL)是一种功能强大的表达式语言.用于在运行时查询和操作对象图:语法上类似于Unified EL,但提供了更多的特性,特 ...

  5. SpringBoot框架SpEL表达式注入漏洞复现与原理分析

    前言 这是2016年的一个洞,利用条件是至少知道一个触发 springboot 默认错误页面的接口及参数名. 影响版本:1.1.0-1.1.12 1.2.0-1.2.7 1.3.0 修复方案:升级版本 ...

  6. SpEL表达式注入

    一.内容简介 Spring Expression Language(简称SpEL)是一种强大的表达式语言,支持在运行时查询和操作对象图.语言语法类似于Unified EL,但提供了额外的功能,特别是方 ...

  7. SSTI(模板注入)

    SSTI 一. 什么是SSTI 模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档. ...

  8. XFF SSTI 模板注入 [BJDCTF2020]The mystery of ip

    转自https://www.cnblogs.com/wangtanzhi/p/12328083.html SSTI模板注入:之前也写过:https://www.cnblogs.com/wangtanz ...

  9. GYCTF Flaskapp[SSTI模板注入 ]

    题目复现传送门 学习链接: 找了个师傅的blog先学习一下基础的flask知识 https://www.freebuf.com/column/187845.html(从零学flask) 简单记录一下: ...

  10. Web攻防之XSS,CSRF,SQL注入

    摘要:对Web服务器的攻击也可以说是形形色色.种类繁多,常见的有挂马.SQL注入.缓冲区溢出.嗅探.利用IIS等针对Webserver漏洞进行攻击.本文结合WEB TOP10漏洞中常见的SQL注入,跨 ...

随机推荐

  1. js代理(Proxy) 和 反射(Reflection)

    在实际开发中经常会遇到js抛出的错误,但是我们有没有想过自己去接管js异常验证,根据自己的需求抛出异常呢?原本也许不行,但是在es6出来后就可以做到了 一.代理(Proxy) 什么是'代理' 呢?代理 ...

  2. ubuntu18 安装单机k8s v1.18.2

    背景 当我们需要对k8s进行二次开发时,k8s环境是必须的,那么在ubuntu上部署单机k8s是最方便的,便于开发调试 系统准备 本人用的是Ubuntu18,以下以此为例 部署之前,最好切换至root ...

  3. 【LeetCode滑动窗口专题#2】无重复字符的最长子串

    #1传送门 无重复字符的最长子串 给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: s = "abcabcbb" 输出: 3 解释: 因为 ...

  4. 纠删码技术在vivo存储系统的演进【上篇】

    作者:vivo 互联网服务器团队- Gong Bing 本文将学术界和工业界的纠删码技术的核心研究成果进行了相应的梳理,然后针对公司线上存储系统的纠删码进行分析,结合互联网企业通用的IDC资源.服务器 ...

  5. SQL专家云快速解决阻塞

    背景 当数据库突然产生严重阻塞时,运维人员要快速找到阻塞的源头并处理,让业务快速恢复.但是大多数运维人员只掌握了sp_who2.sp_lock等简单的语句,存在以下不足: 找不到真正的源头,过程中会误 ...

  6. vue2父传子,子传父

    首先看父传子 自定义一个子组件 <template> <div> 子组件: <span>{{inputName}}</span> </div> ...

  7. redis集群报错:MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on disk.

    之前在x86架构的服务器部署redis集群,未遇到题中问题:然而在ARM架构的服务器部署redis集群,第一次遇到如此问题.虽然问题已经解决,但不清楚问题的具体原因,在此做个记录. 性能测试过程中,通 ...

  8. C++ 数独游戏

    C++ 数独游戏 直接上代码: 1 // 数独 sudoku 2 3 #include <iostream> 4 5 using namespace std; 6 7 int P[9][9 ...

  9. WinUI(WASDK)使用MediaPipe检查人体姿态关键点

    前言 之前有用这个MediaPipe.NET .NET包装库搞了手势识别,丰富了稚晖君的ElectronBot机器人的第三方上位机软件的功能,MediaPipe作为谷歌开源的机器视觉库,功能很丰富了, ...

  10. Rust 学习笔记:快速上手篇

    Rust 学习笔记:快速上手篇 这篇学习笔记将用于记录本人在快速上手 Rust 编程语言时所记录的学习心得与代码实例.为此,我会在本笔记库项目的Programming/LanguageStudy/目录 ...