问题描述
我们打算让我们的客户在我们的平台内执行他们自己的groovy脚本。他们将被允许访问只有受控制的方法,但我们有一个问题。尽管我们会尽可能地小心谨慎,但我们可能会面临长时间运行循环的风险 - 导致内存泄漏或无限循环,从而影响我们的平台。
groovy脚本中是否有固有的方法来防止这种可能性? 解决方案
您可以防止循环和所有危险语法结构使用。
好文章 here。
如果您可以限制您的DSL(您的客户端可以运行的代码),以便它只能调用您的方法对象,这是由你来保证内存不能泄漏或以任何方式被滥用。
GroovyShell
通过自定义 CompilerConfiguration
CompilerConfiguration
与自定义 SecureASTCustomizer
使用方法 addCompilationCustomizers(... )
您可能想要让DSL中的所有函数调用都通过您的自定义类。为此,让你的shell解析脚本,将脚本转换为 DelegatingScript
并将它传递给你的对象:
DemoDSLHelper delegate = new DemoDSLHelper(); //您的定制类需要在DSL
中公开的自定义方法GroovyShell shell = new GroovyShell(createCompilerConfiguration());
Script script = shell.parse(scriptText);
((DelegatingScript)脚本).setDelegate(delegate);
Object result = script.run();
在单独的JVM中运行它,以便您可以使用OS强制限制进程(容器化等)的独立基元,或者如果它不尊重你的规则(持续时间,资源消耗等),就干掉它。如果它必须在执行其他事情的JVM中运行,那么至少您需要对DSL在您接受的内容中采取极为严格的限制。
以及完整的可运行示例。 p>
We intend to allow our clients to execute their own groovy scripts within our platform. They will be allowed to access only controlled methods but we have one concern.Although we will take all possible care somewhere we might get into a risk of long running loops - resulting in memory leak or infinite loop which can affect our platform.Is there any inherent way within groovy script to protect against such probability?
You can prevent loops and all dangerous syntax constructs with a SecureASTCustomizer.
Nice article here.
If you can restrict your DSL (the code your client can run) so that it can only invoke your methods on your object(s), it's up to you to guarantee memory cannot leak or be abused in any way.
GroovyShell
by passing it a custom CompilerConfiguration
CompilerConfiguration
with a custom SecureASTCustomizer
using method addCompilationCustomizers(...)
You probably want to get all function calls in your DSL to go through a custom class of yours. For that, have your shell parse the script, cast the script as a DelegatingScript
and pass it your object:
DemoDSLHelper delegate = new DemoDSLHelper(); // Your custom class with custom methods you want to expose in the DSL
GroovyShell shell = new GroovyShell(createCompilerConfiguration());
Script script = shell.parse(scriptText);
((DelegatingScript)script).setDelegate(delegate);
Object result = script.run();
Run that in a separate JVM, so that you can enforce limits on the process with OS-dependent primitives for that (containerization, etc), or simply kill it if it fails to respect your rules (duration, resources consumption, etc). If it must run within a JVM that does other things, at the very least you'll need to be extremely restrictive in what you accept in the DSL.
And here a gist with complete runnable example.
这篇关于Groovy脚本:如何防范可能的内存泄漏或无限循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!