XSS攻击之所以会发生,归根结底是因为用户输入的数据变成了可执行代码。所以通常情况下,我们需要对用户输入的数据进行HTMLEncode处理,将其中的中括号、单引号、双引号之类的特殊字符进行编码。这就使得一个Web安全问题引入了国际化bug的潜在可能。
再次回到本案来走读示例代码。 public PromptPanel(String title, String message, ImageResource imageResource, String okButtonText, String cancelButtonText) { ... if (!StringUtil.isNullOrEmpty(title)) { _title = SafeHtmlUtils.htmlEscapeAllowEntities(title); } if (!StringUtil.isNullOrEmpty(message)) { _message = SafeHtmlUtils.htmlEscapeAllowEntities(message); // fixes XSS } ... } 这里我们可以清晰的看到,_title和_message这两个变量为了避免XSS攻击,都经过了htmlEscapeAllowEntities方法的转义处理。然而在初始化ImageLabel的时候,程序对lable的内容进行了二次转义,这就导致了HTML Entity在前端的出现。 private void initContent() { <span style="white-space:pre"> </span>if (!StringUtil.isNullOrEmpty(_title)) { <span style="white-space:pre"> </span>Label title = new Label(_title); <span style="white-space:pre"> </span>container.add(title); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>ImageLabel label = new ImageLabel(_message, _imageResource); <span style="white-space:pre"> </span>… } public ImageLabel(String label, ImageSpec imageSpec) { <span style="white-space:pre"> </span>this(new SafeHtmlBuilder().appendEscaped(label).toSafeHtml(), imageSpec); } 现在我们了解了问题的成因,再次审视,不禁反思——这真的只是法文特有的国际化bug么?其他自然语言(例如英文)就不存在类似问题? 显然事实并非如此,英文中I'm, I didn't这样的词句依然可以触发该现象。那么当我们再次遇到这个所谓法文常见“国际化问题”时,还会不假思索的将其标识为国际化bug么?读到这里,相信大家已经有了自己的答案。