2014-05-24 69 views
2

在HTML模板引擎中,通過默認佔位符文本進行HTML轉義以幫助防止XSS(跨站點腳本攻擊)是非常好的做法。是否有可能在StringTemplate中實現這種行爲?如何在StringTemplate中默認轉義HTML?

我試圖註冊自定義AttributeRenderer其轉義HTML除非format"raw"

stg.registerRenderer(String.class, new AttributeRenderer() { 
    @Override 
    public String toString(Object o, String format, Locale locale) { 
     String s = (String)o; 
     return Objects.equals(format, "raw") ? s : StringEscapeUtils.escapeHtml4(s); 
    } 
}); 

但由於在這種情況下StringTemlate逃脫不僅佔位符文本,而且模板文本本身失敗。例如這個模板:

example(title, content) ::= << 
    <html> 
     <head> 
      <title>$title$</title> 
     </head> 
     <body> 
      $content; format = "raw"$ 
     </body> 
    </html> 
>> 

呈現爲:

&lt;html&gt; 
    &lt;head&gt; 
     &lt;title&gt;Example Title&lt;/title&gt; 
    &lt;/head&gt; 
    &lt;body&gt; 
     <p>Not escaped because of <code>format = "raw"</code>.</p> 
    &lt;/body&gt; 
&lt;/html&gt; 

任何人可以幫助?

回答

0

答案是恢復到StringTemplate v3。

0

沒有好的解決方案默認。該模板通過AttributeRenderer傳遞給字符串數據類型,並且沒有上下文信息來檢測它是否正在處理模板或變量。因此,所有字符串(包括模板)都默認進行編碼,因爲您無法爲模板指定「raw」。

另一種解決方案是在需要編碼的變量中使用format="xml-encode"。內置StringRenderer有幾種格式支持:

  • URL編碼
  • XML編碼

所以,你的例子是:

example(title, content) ::= << 
    <html> 
     <head> 
      <title>$title; format="xml-encode"$</title> 
     </head> 
     <body> 
      $content$ 
     </body> 
    </html> 
>> 

默認情況下,爲了編碼,您的選項有限。替代方案是:

  1. 使用自定義數據類型(不String)爲您的變量,所以你可以自定義數據類型註冊HtmlEscapeStringRenderer。如果您使用複雜的對象作爲已經使用標準字符串的變量,這很困難。
  2. 手動將原始和轉義變量添加到模型中,例如,加title(轉義)和title_raw(原始)。在這種情況下,您不需要自定義AttributeRenderer。 StringTemplate具有嚴格的視圖/模型分離,並且需要在使用原始值和轉義值呈現之前填充模型。

這兩個選項都不是特別理想,但我沒有看到任何其他選擇與StringTemplate4。

+0

當然,但很容易忘記添加'format =「xml-encode」',這就是爲什麼我的問題是如何啓用編碼**默認**。 – dened