我们将esapi引入我们的Spring JSP项目,以处理呈现为HTML和Javascript的清理数据。我们使用的一个字段由第三方Web服务设置,我们将结果输出到Javascript变量:
var errReason= '<esapi:encodeForJavaScript>${myOrder.rateErrorMessage}</esapi:encodeForJavaScript>';
问题是WebService的结果有时会在末尾附加换行符。我原以为encodeForJavascript应该处理换行符,但是上面的代码会像这样呈现:
var errReason 'This was an invalid request: missing required parameter
';
esapi是否按设计运作?有没有替代方法来处理这个问题?
感谢。
答案 0 :(得分:1)
根据给定的信息,它不能成为导致您的问题的esapi。以下单元测试通过:
@Test
public void testWindowsNewline() {
Encoder instance = ESAPI.encoder();
assertEquals("\\x0D\\x0A", instance.encodeForJavaScript("\r\n"));
}
FWIW,taglibs are just wrappers around the esapi encoder class.
看来你正在使用javascript字符串中嵌入的taglibs,如果我在团队的代码审查中看到,我会将其标记为缺陷,这就是原因:
JSP编译器在呈现页面时经历了多个步骤。你有HTML渲染,数据绑定和JSTL绑定,仅举几例。由于此排序是特定于实现的,因此您希望尝试远离混合代码,就像您在此处一样。
我怀疑JSP编译器在调用"\r\n"
之前将<esapi:encodeForJavaScript></esapi:encodeForJavaScript>
解释为HTML空格。
这是我过去做过的几件事。我更倾向于在Controller / Service层转义。这个例子假设是Spring MVC,并且正在取得巨大的自由。
@Controller
public class FooController {
//This should actually be done in a service class, but this is for demo
private Encoder = ESAPI.encoder();
@Autowired
private DataService dataService;
//logic for handling request
public String returnStringEscapedForJavascriptContext(){
OrderBean myOrder = dataService.getMyOrder();
String unescaped = myOrder.getRateErrorMessage();
String escapedAsJavascriptData = encoder.encodeForJavaScript(unescaped);
return escapedAsJavascriptData ;
}
}
如果您将myOrder
转换为viewBean等,则适用相同的基本逻辑。
另一个解决方案是将安全的esapi转义方法包装为一个抽象类,所有的视图bean都是从这个方式继承而来的,如果你真的想在JSP中做这个工作,你可以这样:
public abstract class SecureBean {
private Encoder encoder = ESAPI.encoder();
public String escapeForJavaScript(String input){
return encoder.escapeForJavaScript(input);
}
}
然后继承:
public class OrderBean extends SecureBean {
String rateErrorMessage; //with getters/setters assumed
}
现在在你的jsp:
var errReason= '${myOrder.escapeForJavaScript(myOrder.rateErrorMessage())}';
其中一些有点冗长,但这里的目标是不要尝试踩到JSP的渲染顺序。您也可以考虑编写适配器接口进行编码/解码,这样您就可以换掉编码器实现 - esapi已经失去了OWASP旗舰状态,并且在~1。5年内没有进行过重大修改。