Loading ...
Java 代码审计指南
在当今数字化时代,Java 应用程序的安全性至关重要。代码审计作为保障应用安全的关键环节,能够帮助我们提前发现潜在的安全漏洞。本文将详细介绍 Java 代码审计的思路方法以及常见基础漏洞的审计要点,为安全从业者和开发人员提供参考。

一、代码审计思路和方法

进行 Java 代码审计时,可采用以下四种主要思路和方法,它们各有优劣,适用于不同场景:
  1. 逆向追踪(回溯变量)
    • 方法:从敏感函数的参数入手,回溯变量的来源和传递过程,判断其是否可控且未经过严格过滤。例如,可依据 SQL 语句的特征来分析是否存在注入漏洞。
    • 优点:通过搜索敏感关键字,能快速、高效地挖掘到定向漏洞。
    • 缺点:由于未通读代码,对程序整体框架了解不深入,可能遗漏逻辑漏洞。
  2. 正向追踪(跟踪变量)
    • 方法:先找出接收外部参数的文件,然后跟踪变量的传递路径,观察其是否传入高危函数或存在代码逻辑漏洞。
    • 优点:挖掘范围比逆向追踪更全面。
    • 缺点:效率可能不如逆向追踪。
  3. 直接挖掘功能点漏洞
    • 方法:根据经验判断应用中哪些功能点可能存在漏洞,然后直接阅读该部分代码。
  4. 通读全文
    • 方法:通读整个应用程序的代码,以了解其业务逻辑和整体架构。建议先从程序入口文件(如 index 文件)、函数集文件(如 functionscommon)、配置文件(如 config)和安全过滤文件(如 filtersafecheck)入手。
    • 优点:能更好地了解程序架构和业务逻辑,挖掘出更多有价值的逻辑漏洞。
    • 缺点:耗时较多,对于大型程序来说工作量较大。

二、基础漏洞审计

1. SQL 注入

  • 漏洞原理:程序未对用户输入进行正确检查,直接以拼接方式将输入带入 SQL 语句中,导致攻击者可构造恶意 SQL 语句影响数据库操作。
  • SQL 语句执行方式
    • JDBC:通过 java.sql.Statement 对象进行直接拼接,容易产生注入;而 java.sql.PreparedStatement 使用预编译,相对安全。
    • MyBatis:使用 $ 符号进行拼接会造成注入,而 # 符号使用预编译,基本安全。
    • Hibernate 也可能存在相关注入风险,需具体分析。
  • 审计关键词StatementcreateStatementPrepareStatementselectupdateinsert
  • 常见注入类型
    • 参数动态拼接。
    • 预编译错误。
    • ORDER BY 注入:ORDER BY 无法预编译,需要使用拼接方式,易出现漏洞。
    • LIKE 模糊查询注入。
    • IN 查询注入:在 IN 语句中使用 # 会导致整个参数作为一个整体拼接进去,容易出现注入。
  • 审计方法:通过关键词搜索,找到关键字后查看周围是否安全调用外部变量或是否有过滤。若没有,则追踪调用栈查找引用位置。
  • 二次注入:在注册、登录等位置注入包含特殊字符的 SQL 语句,在后续查询用户信息的过程中可能导致二次注入。

2. 文件上传

  • 漏洞原理:程序员对文件上传的控制不足或处理有缺陷,导致用户可以上传可执行的动态脚本文件。问题的关键在于服务器如何处理和解释上传的文件。
  • 审计关键词org.apache.commons.fileuploadjava.io.FileMultipartFileRequestMethod
  • 审计方法
    • 关注上传表单代码段。
    • 关注文件上传后的后缀校验、文件类型黑白名单、Content-Type 黑白名单,以及(如果为图片)图片库检测。
    • 检查是否存在以下常见问题:未做任何过滤、仅在前端进行过滤、只判断 Content-Type、后缀过滤不全、读取后缀方式错误(例如,不安全的后缀获取方式为 fileName.indexOf("."))。
    • 后端需要对文件类型、大小、文件名和内容进行验证。

3. XSS (跨站脚本攻击)

  • 漏洞原理:通过注入恶意代码(通常是 JavaScript)到网页中,当用户访问该页面时,恶意代码被执行,可能导致用户信息泄露等问题。
  • 漏洞分类
    • 反射型 XSS:非持久化,注入的恶意代码通过服务器的响应返回到前端页面并被执行。
    • 存储型 XSS:持久化,注入的恶意代码存储在服务器中,用户访问页面时触发。
    • DOM 型 XSS:通过修改页面的 DOM 节点触发。
  • 审计关键词request.getParameterresponse.getWriter().print()response.getWriter().writer()<%=${<c:out<c:if<c:forEachModelAndViewModelMap
  • 修复手段:采用全局过滤器、安全应用程序接口(如 ESAPI / 谷歌的 xssProtect)、HTML 实体编码等方式进行防御。

4. 目录穿越

  • 漏洞原理:没有校验文件名中是否包含 ../ 等特殊字符及对用户访问文件进行限制,导致攻击者可访问未授权的目录和文件。
  • 审计关键词Pathjava.io.FileFileInputStreamfile.read
  • 修复手段:进行文件名过滤,检测路径是否合法。

5. URL 重定向

  • 审计关键词returnredirecturljumpgototargetlinknew ModelAndViewredirectAttributeresponse.setHeader
  • 修复手段:控制跳转域名,将跳转值写为固定值;设置只能根据路径跳转。

6. 命令执行

  • 漏洞原理:代码未对用户可控参数做过滤,导致恶意命令被拼接到正常命令中执行,可能对服务器造成严重破坏。
  • 执行命令方法
    • java.lang.ProcessBuilder.start()
    • java.lang.Runtime.getRuntime.exec():其 String 型重载在执行时会使用 StringTokenizer 函数按空格、制表符等分割命令,可能导致无法执行;而数组型重载可以直接调用 ProcessBuilder 执行,相对安全。
  • 审计关键词getParameterProcessBuilderstart()Runtime.getRuntime.exec()
  • 修复手段:避免直接使用 getRuntime,并过滤输入的恶意字符。

7. XXE (XML 外部实体注入)

  • 漏洞原理:应用程序在解析 XML 输入时,未禁止外部实体的加载,导致攻击者可加载恶意外部文件,获取敏感信息等。
  • 审计关键词XMLReaderSAXBuilderSAXReaderSAXParserFactoryDigesterDocumentBuilderFactory
  • 审计方法
    • 检查 XML 解释器的配置,看是否禁用了 XML 外部实体。
    • 查看代码中是否使用了上述关键词中列出的 XML 解析接口或类。
  • 修复手段:禁用 DTD / 禁用外部实体。

8. SSRF (服务端请求伪造)

  • 漏洞原理:攻击者伪造服务器发出请求,向内部网络或其他受保护资源发起请求,而服务器未进行过滤和限制,可能导致内部信息泄露等问题。
  • 审计关键词HttpURLConnection.getInputStreamURLConnection.getInputStreamHttpClient.executeURL.openStreamImageIO.read
  • 审计方法
    • 快速找到 HTTP 请求操作函数。
    • 测试是否可以访问内部地址(如 http://127.0.0.1 或内网 IP)或使用不同的 URL 协议(如 file 协议)。
  • 修复手段
    • 控制跳转域名,最好在源码中写为固定值。
    • 设置只能根据路径跳转。

9. 反序列化

  • 漏洞原理:应用程序在反序列化过程中,未对恶意数据进行验证和过滤,导致攻击者可以劫持字节流,植入恶意代码并被执行。
  • 必要条件:存在利用链(exploit chain)和触发点(trigger point)。
  • 审计关键词ObjectInputStream.readObjectXMLDecoder.readObjectyaml.loadXStream.fromXMLObjectMapper.readValueJSON.parseObject
  • 审计方法
    • 检查代码中是否使用了上述关键词。
    • 关注流行的 Java 框架(如 Apache Struts、Apache Commons Collections、Jackson)中存在的反序列化漏洞。

10. CSRF (跨站请求伪造)

  • 漏洞原理:攻击者盗用用户的身份,以用户的名义发起恶意请求,而服务器没有进行身份识别,可能导致用户数据被篡改等问题。
  • 审计方法:检查是否对 RefererToken 等参数进行了严格的检测。

11. 逻辑漏洞

  • 漏洞原理:在软件设计过程中存在错误或疏忽,导致未正确处理输入、验证用户身份、授权访问等,从而引发安全风险。
  • 审计方法:逻辑漏洞的产生不在于代码本身,而在于业务逻辑的缺陷,因此需要深入理解业务逻辑,才能进行测试。
  • 常见漏洞类型
    • 验证码漏洞:验证码爆破、回显、未与手机绑定、修改返回包绕过、转发、固定验证码等。
    • 支付漏洞:任意金额修改、负数购买、越权支付、修改运费、优惠券修改、四舍五入漏洞、整数溢出等。
    • 并发漏洞(条件竞争):后台未对操作加锁,导致并发操作产生安全问题,例如点赞或领取优惠券等。
    • 越权漏洞:攻击者修改用户身份识别参数(如 iduidname 等),进行不属于自己的操作,例如删除评论、查看他人信息等。

12. SpEL 表达式注入

  • 漏洞原理:程序未对用户输入进行验证,直接通过解析引擎解析 SpEL 表达式,可能导致恶意代码执行。
  • 审计关键词SpelExpressionParserparseExpressionexpression.getValue()
  • 修复手段:使用 SimpleEvaluationContext

 

通过以上对 Java 代码审计思路方法和常见漏洞的梳理,希望能帮助大家在实际工作中更好地进行代码审计,提升 Java 应用程序的安全性。在实际审计过程中,还需结合具体业务场景和代码细节,进行全面、深入的分析。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇