Java 中可以进行代码注入吗?
如今,您可以阅读很多有关代码注入、漏洞利用、缓冲区、堆栈和堆溢出等导致注入和运行代码的内容。我想知道这些内容与 Java 相关。
我知道,Java语言中没有指针。但是 JVM 不是在堆和/或堆栈中组织数据吗? 我知道没有 eval 函数(就像在 PHP 中一样),所以你不能轻松地将输入用作 Java 代码。我不太确定字节码级别上发生了什么。
我认为 XSS 是可能的,例如在 Java EE 应用程序中,当没有过滤输入时。但这不是更多的 JavaScript 注入吗?因为注入的代码在浏览器中运行,而不是在 JVM 中运行?
那么哪些代码注入可以用 java 实现,哪些不能呢?对于其他 Java 平台语言来说也是如此吗?
提前致谢。
nowadays you can read much about code injection, exploits, buffer-, stack- and heap-overflows etc. leading to inject and run code. I wonder what of this stuff is relevant for Java.
I know, there are no pointers in the Java language. But doesn't the JVM organize data in heaps and / or stacks?
I know there is no eval function (like in PHP) so you cant easily use an input as Java-code. I am not so sure whats going on on bytecode level.
I think XSS is possible, for example in an Java EE application, when no inputs are filtered. But isn't this more a JavaScript injection, because the injected code runs in the browser and not in the JVM?
So which code injections are possible with java and which are not? And is this true for other Java platform languages, too?
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
java 程序本身几乎不易受到代码注入的攻击。但是,支持该应用程序的所有本机代码都容易受到各种不同类型的代码注入的影响 - 这包括 JVM 以及应用程序或其库中的所有本机代码部分。
另外,还有一些事情需要考虑:
任何使用 java 作为通往其他系统的网关的情况都是可能的:
SQL 注入
XSS(最终只不过是 JavaScript 注入)
如果 java 程序本身就是一个解释器/编译器某种意义上,可以将代码注入到您的解释语言/编译程序中(这包括将您的程序用作java编译器......)
当然,如果您可以让java程序将包含以下内容的文件写入磁盘代码(无论是本机,java还是其他东西),您也许可以通过其他方式执行它(这可能是您的应用程序,操作系统或其他应用程序中的不同漏洞) - 这不是直接代码注入,但与影响。
A java program itself is pretty much not vulnerable to code injection. However, all the native code that supports the app is vulnerable to all the different kinds of code injection - this includes the JVM and all native code parts in the app or its libraries.
Also, there are a few more things to consider:
Anything where java is used as a gateway to other systems is possible:
SQL Injection
XSS (which is in the end nothing more than JavaScript Injection)
If the java program is itself a interpreter/compiler of some kind, it might be possible to inject code into your interpreted language/compiled program (this includes using your program as a java compiler...)
And of course if you can get the java program to write a file to disk that contains code (be it native, java or something else) you might be able to get it executed by other means (which can be a different vulnerability in your app, the os or another app) - this is not direct code injection but quite similar in effect.
如果服务器应用程序在运行时创建字节码(例如使用 BCEL 或 Javassist),如果此创建可以受到用户输入的影响,则可以进行代码注入。
但是,如果您的应用程序不使用魔法(这应该是所有应用程序的 99%),则这是不可能的。
If the server application creates bytecode at runtime (for example with BCEL or Javassist), and if this creation can be influenced by user input, then a code injection is possible.
However, if you application uses no magic (which should be 99% of all applications), it will not be possible.
有多种方法可以将 Java 代码注入到应用程序中,例如使用脚本 API 或动态 JSP 包含。
下面的代码允许用户将任意 Javascript 注入到 Java 的脚本引擎中。
在这种情况下,攻击者决定注入在文件系统上创建文件的代码。
查看 owasp 网站了解更多示例
There are a couple ways in which Java code could be injected into an application such as using the scripting API or dynamic JSP includes.
The code below allows a user to inject arbitrary Javascript into Java's script engine.
In this case, the attacker decides to inject code that creates a file on the file system.
check owasp website for more examples
您可以编写一个 Web 服务,它接受 Java 代码片段,将其包装在类/方法声明中,将其保存到磁盘,在其上运行编译器,然后动态加载并执行结果。所以代码注入当然是可能的。
但对于典型的 Java 实现,由于相对重量级的编译过程,它可能不是很有效(尽管它对于某些应用程序可能仍然实用)。
代码注入与 SQL 高度相关,因为许多初学者的“第一个猜测”是使用字符串连接将变量插入语句中。但它很少在 Java 程序员中作为一个想法出现。所以这就是人们不太担心的原因。
如果 Java 编译器作为轻量级库服务公开,那么您将拥有更接近于
eval
等价物的东西,因此它可能会开始成为一个相关的问题。You could write a web service that accepted a Java code snippet, wrapped it in a class/method declaration, saved it to disk, ran the compiler on it and then dynamically loaded and executed the result. So code injection is certainly possible.
But with typical Java implementations, it's perhaps not very efficient because of the relatively heavyweight compilation process (it might still be practical for some apps though).
Code injection is highly relevant with SQL because the "first guess" of many beginners is to use string concatenation to insert variables into a statement. But it rarely crops up as an idea amongst Java programmers. So that's the reason it isn't much of a concern.
If Java compilers become exposed as light-weight library services, then you'd have something much closer to the equivalent of
eval
and therefore it might start to become a relevant concern.如果可能的话,Java 早就消亡了。
另一方面,通过使用 很容易避免 SQL 注入
PreparedStatement
来存储用户控制的输入,使用
用于(重新)在网页上显示用户控制的输入。If it was possible, Java would already have been dead for long.
On the other hand, SQL injections are very easy to avoid by using
PreparedStatement
to store user-controlled input and XSS is also very easy to avoid by using<c:out/>
for (re)displaying user-controlled input at the webpage.除非您在服务器上做奇怪的事情(例如动态生成代码等),否则不可能进行代码注入。
尽管我可以想到应用程序根据用户输入动态创建 JSP 的一种(丑陋的)情况。该 JSP 将被转换为 Java 代码,该代码由 Web 容器编译为字节码,然后执行。这可能会引入注入点。但是动态生成 JSP 通常没有任何意义。
Unless you are doing weird things on the server (like dynamically generating code, etc), it is impossible to bo vunerable for code injection.
Although I can think of an (ugly) situation where the application dynamically creates a JSP based on user input. That JSP will be translated to Java code, which is being compiled to byte-code by the web container, and then executed. This could introduce an injection point. But generating JSP's dynamically normally doesn't make any sense.
你不能注入Java。但如果你不小心,人们可能会注入 Javascript(即你提到的 XSS)或 SQL。有堆和栈,但没有办法访问它们。
You can't inject Java. But if you are not careful, people could inject Javascript (i.e. XSS as you mention) or SQL. There are heaps and stacks, but no way to get to them.
您无法注入 java,但如果输入未正确过滤,所有 Web 应用程序都容易受到 XSS 攻击。此外,任何与 SQL 数据库交互的应用程序都可能容易受到 SQL 注入的攻击。为了避免这种情况,您需要研究参数化查询。
You can't inject java, but all web applications are vulnerable to XSS if the input is not properly filtered. Also any application that interacts with a sql database can be vulnerable to SQL injection. To avoid this you will want to look into Parameterized Queries.
如果将其与解释语言进行比较,这肯定更困难。然而,JVM 支持 JavaScript 等脚本语言,上面的示例之一演示了 JavaScript 运行时的注入。
JVM 还支持使用 Groovy 编写脚本,这相当于 Java 脚本编写。因此,如果您知道这是在幕后发生的事情,您可以使用类似的东西:
当然,您必须以某种方式在服务器上获取 test.groovy ,这是另一个故事。有关更多详细信息,请参阅此线程:从 Java 调用 Groovy 函数。 Groovy 即时编译为字节代码,并自动加载到 JVM 中。
我见过用 Java 编写的企业应用程序公开了一个脚本 Web 控制台,您可以在其中提供整个 Groovy 文件并在系统仍在运行的情况下执行它......具有管理员权限。它背后使用了 JVM 的脚本功能。您还可以将它与 JavaScript 一起使用。
以下是截至 2020 年 7 月 JVM 支持的脚本语言:
科特林
斯卡拉
格罗维
克洛尤尔
幻影
锡兰
Jython
JRuby
弗雷格
扩展
戈洛
康库纳斯
雪人
有关更多详细信息,请参阅本文。
底线是,Java 中的代码注入并不像其他语言那么容易,尤其是解释型语言,如 JavaScript、Ruby、PHP 等。
It is certainly more difficult, if you compare it to interpreted languages. However, the JVM supports scripting languages like JavaScript, and one of the example above demonstrates injection when JavaScript is at play.
The JVM also supports scripting with Groovy, which is the the Java scripting equivalent. So, if you know that this is what is happening behind the scenes, you can use something similar to this:
Of course, you will have to get test.groovy on the server somehow, which is another story. See this thread for more details: Calling a Groovy function from Java. Groovy compiles to byte code on the fly and it is automatically loaded into the JVM.
I've seen enterprise applications written in Java expose a Scripting Web Console, where you could supply an entire Groovy file and execute it with the system still running ... with Admin privileges. Behind it uses the JVM's scripting capabilities. You could also use it with JavaScript.
Here are the scripting languages supported by the JVM as of July, 2020:
Kotlin
Scala
Groovy
Clojure
Fantom
Ceylon
Jython
JRuby
Frege
Xtend
Golo
Concurnaas
Yeti
See this article for more details.
Bottom line, code injection in Java is not as easy as it is in other languages, especially interpreted ones, like JavaScript, Ruby, PHP, etc.