在SaaS应用程序中,我有一些模板用于生成通知电子邮件或某些HTML页面.到目前为止,我还没有使用百日咳,到目前为止所有模板都是硬编码的,但我很乐意改变它,以便应用程序的用户可以自己编辑这些模板.问题是,如果我允许用户自己编辑模板,用户可能会调用任何Java方法,这将完全损害系统安全性.
百万美元可以"沙盒化"还是可以禁用在用户编辑模板环境中危险的所有功能?(为了执行,模板只接收带有getter和setter或java.util.Map的POJO,因此在模型上调用方法不是问题)
最明显的问题是OGNL/SpringEL.这些表达的力量可能很大,但它们也非常危险.我只需要从模型中调用getter.所以我试着像这样实现我自己的表达式解析器(以下只是一些快速和脏的概念证明,它不是"完成"):
final TemplateEngine templateEngine = new TemplateEngine();
final StandardDialect dialect = new StandardDialect();
dialect.setExpressionParser(new IStandardExpressionParser() {
@Override
public IStandardExpression parseExpression(final IExpressionContext context, final String input) {
if (!input.startsWith("${") || !input.endsWith("}")) {
throw new IllegalArgumentException("Only variable expressions allowed, not " + input);
}
final String[] path = StringUtils.split(input.substring("${".length(), input.length() - "}".length()), '.');
return new IStandardExpression() {
@Override
public String getStringRepresentation() {
return "Variable " + Arrays.toString(path);
}
@Override
public Object execute(final IExpressionContext context) {
Object result = context.getVariable(path[0]);
for (int i = 1; i < path.length; i++) {
try {
result = BeanUtils.getProperty(result, path[i]);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new Error(e);
}
}
return result;
}
@Override
public Object execute(final IExpressionContext context, final StandardExpressionExecutionContext expContext) {
return execute(context);
}
};
}
});
templateEngine.setDialect(dialect);
System.out.println(templateEngine.process(
"<html xmlns:th=\"http://www.thymeleaf.org\"><p th:text=\"${someVar}\"></p></html>",
new Context(Locale.ENGLISH, Collections.singletonMap("someVar", "someValue"))
));
Run Code Online (Sandbox Code Playgroud)
它看起来很有效,但这还够吗?还是有其他安全漏洞?
归档时间: |
|
查看次数: |
157 次 |
最近记录: |