esapi encodeForJavaScript Newlines限制?

时间:2015-01-24 01:35:03

标签: jsp esapi

我们将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是否按设计运作?有没有替代方法来处理这个问题?

感谢。

1 个答案:

答案 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年内没有进行过重大修改。