如何清理Java生成代码的用户输入?
如果有一个生成文本形式Java代码的函数(如果您愿意的话,类似于模板引擎),您将如何清理用户提供的字段以防止代码注入 例如,如果我使用的模板类似于:如何清理Java生成代码的用户输入?,java,security,code-generation,code-injection,sanitization,Java,Security,Code Generation,Code Injection,Sanitization,如果有一个生成文本形式Java代码的函数(如果您愿意的话,类似于模板引擎),您将如何清理用户提供的字段以防止代码注入 例如,如果我使用的模板类似于: void function_${user_provided_function_name}() { // Do stuff }; 并且用户提供作为输入的(){System.exit(0);};无效函数_dummy,生成的代码为: void function_(){System.exit(0);}; void function_dummy()
void function_${user_provided_function_name}() {
// Do stuff
};
并且用户提供作为输入的(){System.exit(0);};无效函数_dummy
,生成的代码为:
void function_(){System.exit(0);}; void function_dummy() {
// Do stuff
};
即使我只是想不允许使用括号(以防止函数调用),这似乎非常脆弱。如果您想验证用户输入(按原样)以使代码可编译,您必须对用户提供的函数名进行三次检查:
- 词法检查:它必须是一个有效的Java标识符:以字母、美元
$
或下划线\
开头,然后是零个或多个字母、美元、下划线或数字
- 实际检查:它不能是Java关键字:
for
,while
,类
,摘要
,无效
,等等
- 语义检查:它不能是来自
java.lang.Object
:toString
、notify
、getClass
等的方法(也不能是来自其超类的不可重写方法)
要实现第一条规则,正则表达式可以做到这一点。其他两条规则只需一套即可
但是,如果您甚至愿意修改用户输入,则必须首先根据上述第一条规则删除所有错误字符,使其成为有效的Java标识符,然后应用其他两条规则。您可以检查所提供的字符串是否正确。我不会这样做。这种安全运行用户提供的源代码的方法是错误的。您需要在安全沙箱中运行它,以便只有一组白名单上的对象和方法可用。看看