文件操作,如使用 SecureASTCustomizer 从 groovy 创建和删除限制
File Operation like create and delete restrict from groovy with SecureASTCustomizer
我想限制文件操作,如创建文件、删除文件等。
我已经检查过 SecureASTCustomizer 但它只限制导入包级别。如果任何一个在 groovy class 中直接使用而没有导入包,那么它是允许脚本的
并允许执行操作这是我们面临的问题。
我试过这个但没有成功。
MethodCallExpression methodCall = new MethodCallExpression(new VariableExpression("file"), "delete", MethodCallExpression.NO_ARGUMENTS);
List l= new ArrayList<>();
l.add(methodCall);
secure.setExpressionsBlacklist(l);
是否可以仅限制特定class 的少数方法,例如文件的删除方法、新文件的创建等?
请建议使用 groovy.
实现此目的的任何方法
据我所知,您不能禁止对某些 类 的调用,但您可以使用 Groovy metaClass.
全局替换对某些方法的调用
例如,在评估您可能拥有的任何脚本之前,您可以将此片段添加到其文本中:
File.metaClass.delete = {
println "We ain't deleting no files!"
return false
}
当一些 Groovy 代码调用 File#delete()
时,它将 运行 这个 lambda 而不是实际的方法。
示例:
final shell = new GroovyShell()
final result = shell.evaluate '''
// our "protection"
File.metaClass.delete = {
println "We ain't deleting no files!"
}
// the actual script
def f = new File('hello.txt')
def deleted = f.delete()
if (deleted) 'DELETED THE FILE!!'
else "File exists? ${f.isFile()}"
'''
println result
运行 这打印了这个(假设 hello.txt
存在于工作目录中):
We ain't deleting no files!
File exists? true
这对于 DSL 来说已经足够好了,但它很容易被绕过。
旁路示例:
File.metaClass.delete = {
println "We ain't deleting no files!"
}
// malicious scripts
@groovy.transform.CompileStatic
class NonGroovy {
static deleteFile(File f) {
f.delete()
}
}
def f = new File('hello.txt')
def deleted = NonGroovy.deleteFile(f)
if (deleted) 'DELETED THE FILE!!'
else "File exists? ${f.isFile()}"
这会打印:
DELETED THE FILE!!
绕过的方法多到你无法防御!
如果这是出于安全目的,我建议实际使用 Java 的 SecurityManager
并为您的脚本仔细设置策略,或者告诉 Groovy 编译器使用您自己的 ClassLoader
只加载使用安全的 类 的实现(也很难做到,但加上您可以在 SecureASTCustomizer
上设置的限制,它可能是易于管理的)。
另请查看此博客 post:https://levelup.gitconnected.com/secure-groovy-script-execution-in-a-sandbox-ea39f80ee87
而这个 GitHub 项目提到它试图在 Jenkins CI 的上下文中实施安全沙箱:https://github.com/jenkinsci/groovy-sandbox
我想限制文件操作,如创建文件、删除文件等。 我已经检查过 SecureASTCustomizer 但它只限制导入包级别。如果任何一个在 groovy class 中直接使用而没有导入包,那么它是允许脚本的 并允许执行操作这是我们面临的问题。 我试过这个但没有成功。
MethodCallExpression methodCall = new MethodCallExpression(new VariableExpression("file"), "delete", MethodCallExpression.NO_ARGUMENTS);
List l= new ArrayList<>();
l.add(methodCall);
secure.setExpressionsBlacklist(l);
是否可以仅限制特定class 的少数方法,例如文件的删除方法、新文件的创建等? 请建议使用 groovy.
实现此目的的任何方法据我所知,您不能禁止对某些 类 的调用,但您可以使用 Groovy metaClass.
全局替换对某些方法的调用例如,在评估您可能拥有的任何脚本之前,您可以将此片段添加到其文本中:
File.metaClass.delete = {
println "We ain't deleting no files!"
return false
}
当一些 Groovy 代码调用 File#delete()
时,它将 运行 这个 lambda 而不是实际的方法。
示例:
final shell = new GroovyShell()
final result = shell.evaluate '''
// our "protection"
File.metaClass.delete = {
println "We ain't deleting no files!"
}
// the actual script
def f = new File('hello.txt')
def deleted = f.delete()
if (deleted) 'DELETED THE FILE!!'
else "File exists? ${f.isFile()}"
'''
println result
运行 这打印了这个(假设 hello.txt
存在于工作目录中):
We ain't deleting no files!
File exists? true
这对于 DSL 来说已经足够好了,但它很容易被绕过。
旁路示例:
File.metaClass.delete = {
println "We ain't deleting no files!"
}
// malicious scripts
@groovy.transform.CompileStatic
class NonGroovy {
static deleteFile(File f) {
f.delete()
}
}
def f = new File('hello.txt')
def deleted = NonGroovy.deleteFile(f)
if (deleted) 'DELETED THE FILE!!'
else "File exists? ${f.isFile()}"
这会打印:
DELETED THE FILE!!
绕过的方法多到你无法防御!
如果这是出于安全目的,我建议实际使用 Java 的 SecurityManager
并为您的脚本仔细设置策略,或者告诉 Groovy 编译器使用您自己的 ClassLoader
只加载使用安全的 类 的实现(也很难做到,但加上您可以在 SecureASTCustomizer
上设置的限制,它可能是易于管理的)。
另请查看此博客 post:https://levelup.gitconnected.com/secure-groovy-script-execution-in-a-sandbox-ea39f80ee87
而这个 GitHub 项目提到它试图在 Jenkins CI 的上下文中实施安全沙箱:https://github.com/jenkinsci/groovy-sandbox