Java中可以进行代码注入吗?

Posted

技术标签:

【中文标题】Java中可以进行代码注入吗?【英文标题】:Is code injection possible in Java? 【发布时间】:2010-12-25 06:05:46 【问题描述】:

现在您可以阅读很多关于代码注入、漏洞利用、缓冲区、堆栈和堆溢出等导致注入和运行代码的信息。我想知道这些东西与 Java 有什么关系。

我知道,Java 语言中没有指针。但是JVM不是在堆和/或堆栈中组织数据吗? 我知道没有 eval 函数(就像在 php 中一样),所以你不能轻易地将输入用作 Java 代码。我不太确定字节码级别发生了什么。

我认为 XSS 是可能的,例如在 Java EE 应用程序中,当没有过滤输入时。但这不是更多的 javascript 注入,因为注入的代码是在浏览器中运行的,而不是在 JVM 中?

那么,哪些代码注入可以使用 java 而哪些不可以呢?其他 Java 平台语言也是如此吗?

提前致谢。

【问题讨论】:

【参考方案1】:

Java 程序本身几乎不会受到代码注入的影响。但是,所有支持该应用程序的本机代码都容易受到各种不同类型的代码注入的影响——这包括 JVM 和应用程序或其库中的所有本机代码部分。

此外,还有一些事情需要考虑:

任何将 java 用作通往其他系统的网关的事情都是可能的:

SQL 注入

XSS(说到底就是JavaScript注入)

如果 java 程序本身是某种解释器/编译器,则可以将代码注入到您的解释语言/编译程序中(这包括将您的程序用作 java 编译器...)

当然,如果您可以让 java 程序将包含代码的文件写入磁盘(无论是本机代码、java 代码还是其他代码),您也许可以通过其他方式执行它(这可能是一个不同的漏洞在您的应用程序、操作系统或其他应用程序中) - 这不是直接代码注入,但效果非常相似。

【讨论】:

【参考方案2】:

如果服务器应用程序在运行时创建字节码(例如使用BCEL 或Javassist),并且如果这种创建会受到用户输入的影响,那么代码注入是可能的。

但是,如果您的应用程序不使用魔法(这应该是所有应用程序的 99%),那将是不可能的。

【讨论】:

【参考方案3】:

有几种方法可以将 Java 代码注入应用程序,例如使用脚本 API 或动态 JSP 包含。

下面的代码允许用户将任意 Javascript 注入 Java 的脚本引擎。

import javax.script.*;

public class Example1 
    public static void main(String[] args) 
        try 
            ScriptEngineManager manager = new ScriptEngineManager();
            ScriptEngine engine = manager.getEngineByName("JavaScript");
            System.out.println(args[0]);
            engine.eval("print('"+ args[0] + "')");
         catch(Exception e) 
            e.printStackTrace();
        
    

在这种情况下,攻击者决定注入在文件系统上创建文件的代码。

hallo'); var fImport = new JavaImporter(java.io.File); with(fImport)  var f = new File('new'); f.createNewFile();  //

查看owasp 网站了解更多示例

【讨论】:

【参考方案4】:

您可以编写一个接受 Java 代码 sn-p 的 Web 服务,将其包装在类/方法声明中,将其保存到磁盘,在其上运行编译器,然后动态加载并执行结果。所以代码注入当然是可能的。

但是对于典型的 Java 实现,由于相对重量级的编译过程,它可能不是很有效(尽管它可能对某些应用程序仍然实用)。

代码注入与 SQL 高度相关,因为许多初学者的“第一个猜测”是使用字符串连接将变量插入到语句中。但它很少在 Java 程序员中作为一个想法出现。所以这就是它没有太大问题的原因。

如果 Java 编译器被暴露为轻量级库服务,那么您将拥有更接近于 eval 的东西,因此它可能开始成为一个相关问题。

【讨论】:

关于效率的评论在这种情况下似乎并不十分相关,代码注入不一定需要高效。大多数漏洞利用不需要高性能......关键是没有多少应用程序做“接受代码,编译它,运行它”的事情,但那些做的很容易受到攻击。 “如果 Java 编译器暴露为轻量级库服务”:好吧,它们已经暴露了(查看 javax.tools.JavaCompiler,java.sun.com/javase/6/docs/api/javax/tools/JavaCompiler.html)。但同样,为了使代码注入工作,受到攻击的应用程序需要使用 JavaCompiler,幸好没有。 @sleske - 在第三段中,我说“但它很少在 Java 程序员中作为一个想法出现。所以这就是它不是什么大问题的原因。”所以我已经在你的两个 cmets 中说明了你的观点。在您关于性能无关紧要的评论中,我认为您对这个问题感到困惑 - 应用程序不会将输入传递给解释器/编译器以启用漏洞利用。他们通常这样做是通过字符串连接注入值。在他们考虑更简单的解决方案之前,他们很可能会限制这可能是多么缓慢或重量级。【参考方案5】:

如果可能的话,Java 早就死了。

另一方面,使用PreparedStatement 存储用户控制的输入很容易避免SQL 注入,而使用<c:out/> 用于(重新)显示用户控制的输入也很容易避免XSS。网页。

【讨论】:

【参考方案6】:

你不能注入 Java。但是,如果您不小心,人们可能会注入 Javascript(即您提到的 XSS)或 SQL。有堆和栈,但没有办法找到它们。

【讨论】:

【参考方案7】:

除非你在服务器上做一些奇怪的事情(比如动态生成代码等),否则代码注入是不可能的。

虽然我可以想到一个(丑陋的)情况,即应用程序根据用户输入动态创建 JSP。该 JSP 将被转换为 Java 代码,由 Web 容器编译为字节码,然后执行。这可能会引入一个注入点。但是动态生成 JSP 通常没有任何意义。

【讨论】:

【参考方案8】:

您不能注入 java,但如果输入未正确过滤,所有 Web 应用程序都容易受到 XSS 攻击。此外,任何与 sql 数据库交互的应用程序都可能容易受到 SQL 注入的攻击。为避免这种情况,您需要查看参数化查询。

【讨论】:

以上是关于Java中可以进行代码注入吗?的主要内容,如果未能解决你的问题,请参考以下文章

有啥方法可以在我的代码中注入 SQL 吗? [复制]

有啥方法可以在我的代码中注入 SQL 吗? [复制]

我可以将依赖项注入迁移(使用 EF-Core 代码优先迁移)吗?

JAVA代码审计 SQL注入篇

Shopify 应用程序可以在商店主题内自动注入液体代码吗?

JAVA SQL注入测试