freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

如何防御Java中的SQL注入
云鲨RASP 2023-05-26 17:59:16 158556
所属地 北京

SQL注入是应用程序遭受的最常见的攻击类型之一。鉴于其常见性及潜在的破坏性,需要在了解原理的基础上探讨如何保护应用程序免受其害。

什么是SQL注入

SQL注入(也称为SQLi)是指攻击者成功篡改Web应用输入,并在该应用上执行任意SQL查询。此种攻击通常会利用编程语言用来括住字符串的转义字符。攻击者想方设法用表单字段或URL参数向应用注入额外的SQL代码进而获得在目标数据库上执行未经授权的操作的能力。

1685094991_6470824fa808b0c5b3f5e.png!small?1685094991748

图1:SQL注入原理

SQL注入的影响

实现SQL注入的攻击者可以更改目标数据库中的数据。如果目标应用使用的数据库连接字符串授予用户写入权限,SQL注入可能会造成重大破坏:攻击者可以删除大量数据,甚至删除表本身。


此外,即使攻击者只能获得对数据库的读取权限,也可能会导致敏感数据泄露,如财务信息或行业机密等业务敏感信息,以及客户的私人信息等。随着隐私法规越来越完善,数据泄露也是SQL注入最危险的后果之一。

Java中的SQL注入

Java语言已经存在了几十年。尽管开发人员拥有包含稳定的应用框架和可靠的ORM的丰富生态系统,仍不足以保护Java免于SQL注入攻击。以Ruby为例。尽管Rails是一个稳定的开发框架,但是SQL注入仍构成了Ruby应用70%的安全威胁。

以如下Java代码片段为例:

String sql = "select "

+ "id, title, excerpt, body"

+ "from Posts where slug = '"

+ slug

+ "'";

代码通过关联用户以某种方式输入的值(可能是URL参数)来组装SQL查询。

这段代码的问题在于通过用户提供的值进行关联。假设这个Web应用的基URL是

https://example.com/posts

如果我们将my-first-java-project添加到URL中,它变为

example.com/posts/my-first-java-projec

相应的SQL代码会变为

select id, title, excerpt, body from Posts where slug = 'my-first-java-project'

这段代码看起来似乎没什么问题。

进一步地,假设一个不太善意的用户将URL设置为

https://example.com/posts/whatever%27%20or%20%271%27=%271

其中实际传递的参数是

‘whatever’ or ‘1’=’1′

得出的SQL代码是

select id, title, excerpt, body from Posts where slug = 'whatever' or '1'='1'

现在攻击者已经成功注入了未经授权的代码。SQL查询的where子句有了一个判断' 1 '是否等于' 1 '的附加条件。鉴于1=1是真命题,所有POST请求都可以被取回。

这看起来不是什么大问题;但如果对象是敏感的客户信息,也即获取敏感信息只需要一点点SQL注入,问题就不容忽视了。

防御Java SQL注入的技术

尽管SQL注入攻击很常见,而且具有潜在的破坏性,但它们并非无法防御。被利用的漏洞大多源于编码错误,改进方向有以下几种:。

1.使用参数化查询

针对Java中的SQL注入,可以从使用参数化查询入手。下面的例子基于前一节中提到的查询语句进行了改动

String sql = "select id, title, excerpt, body from Posts where slug = ?";

用一个问号形式的占位符替换了关联信息。下一步是创建一个预编译语句,并给它绑定参数值

Connection connection = dataSource.getConnection();PreparedStatement p = c.prepareStatement(sql);p.setString(1, slug);

通过使用参数化查询,我们可以以一种安全的方式组装查询语句与用户提交的值。

2.允许列表输入验证

这种方法是使用参数化查询的补充。

白名单输入验证是指将输入限制为预先编译的已知有效值列表,并对其余输入进行拦截。这包括使用正则表达式来验证某些类型的信息、验证数值参数是否符合预期范围以及检查参数是否符合预期数据类型。
建议对所有类型的用户输入进行URL参数、表单字段、导入文件的内容等验证。

3.以最小授权执行查询

SQL注入一旦成功,需确保应用使用的连接字符串给予用户最小授权。在应用的特定部分,唯一需要的数据库权限是读取权限。这里推荐使用只有读取权限的连接字符串;即便攻击者能够注入未经授权的代码,至少无法更改或删除数据。

4.利用Java持久化

防御SQL注入的另一种方法是使用JPQL (Java持久性查询语言)。JPA (Java Persistence API)有几种实现方式,最流行的是Spring Data JPA和Hibernate。它们为应用提供了额外的数据层,有助于降低SQL注入成功的概率。

Java安全漏洞概述

SQL注入是Web应用最常遭受攻击类型之一;此外,还有许多安全威胁是Java开发人员应该注意的,包括:


  • 恶意Jar

  • XSS注入

  • Java LDAP注入

  • XPath注入

  • SecurityManager漏洞

以下是一些增强Java应用安全性的建议:

1、识别第三方漏洞。现代应用通常对第三方库和工具有很多依赖。使用SCA(软件成分分析)工具对代码进行检测,并形成软件物料清单(SBOM),盘点代码中引入的第三方组件及这些组件引入的漏洞风险,并围绕SBOM建立安全管理流程。

1685095067_6470829bb6857ca2e8ef9.png!small?1685095068350

图2:SCA图例

2、安全左移。在SDLC中尽早引入安全管理,使用自动化工具及相应的管理流程来支持安全编码实践。

3、敏捷右移。应用上线后进入安全运营阶段,使用监控和保护应用安全的工具是关键,RASP能结合应用的逻辑及上下文,以函数级的精度对访问应用系统的每一段代码进行检测,实时监控安全状况、记录并阻断攻击,而无需人工干预。

1685095080_647082a87041af57c401b.jpg!small?1685095080543

图3:RASP原理

SQL注入并不复杂,但其影响却不容小觑。本文介绍了一些防御手段,以避免Java应用成为SQL注入的牺牲品。安全理念、自动化工具及有效的安全管理流程共同构成了保护应用免于安全威胁的终极保障。

# 漏洞 # SQL注入 # web安全
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 云鲨RASP 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
云鲨RASP LV.4
悬镜云鲨RASP,中国领先的应用威胁免疫平台,使用网址:https://rasp.xmirror.cn/
  • 14 文章数
  • 2 关注者
GOTC演讲回顾|基于代码疫苗技术的开源软件供应链安全治理
2023-06-25
【高危】 Apache Kafka 远程代码执行漏洞复现及攻击拦截 (CVE-2023-25194)
2023-06-09
【高危】WebLogic Server 远程代码执行漏洞复现及攻击拦截 (CVE-2023-21839)
2023-05-18
文章目录