2010-12-16 101 views
8

我正致力於在基於Spring的Java Web應用程序中防止跨站點腳本(XSS)。我已經實現了一個類似於本示例http://greatwebguy.com/programming/java/simple-cross-site-scripting-xss-servlet-filter/的servlet過濾器,它可以清理所有輸入到應用程序中。作爲一種額外的安全措施,我希望在所有JSP中清理應用程序的所有輸出。我已經做了一些研究,看看如何做到這一點,並找到兩個互補的選擇。替代使用c:out來防止XSS

其中之一就是使用了Spring的defaultHtmlEscape屬性。這很容易實現(在web.xml中有幾行),當你的輸出通過spring的標籤之一(例如:message或form標籤)時,它很好用。我已經找到了另一種選擇是不能直接使用EL表達式,如${...},而使用<c:out value="${...}" />

這第二種方法完美的作品,但是由於我的工作(200個+ JSP文件)的應用程序的大小。用c:out標籤取代EL表達式的所有不適當用法是一項非常繁瑣的任務。此外,確保所有開發人員都堅持使用c:out標記(更不用說,代碼將會有多不可讀),這將成爲一項繁瑣的任務。

是否有替代方法來轉義需要較少代碼修改的EL表達式的輸出?

回答

10

由於Servlet 2.5/JSP 2.1,你可以創建一個自定義的ELResolver這樣做。您可以在ServletContextListener#contextInitialized()註冊。

@Override 
public void contextInitialized(ServletContextEvent event) { 
    JspFactory.getDefaultFactory() 
     .getJspApplicationContext(event.getServletContext()) 
     .addELResolver(new YourCustomELResolver()); 
} 

ELResolver#getValue()你可以做退讓工作。

您唯一的問題是,您將無法在允許的地方顯示HTML(例如,已經通過白名單的方式從惡意標記/屬性中清除過,以便最終生成像Jsoup can這樣的無辜標記)。


這麼說,我不同意有必要由Filter當你在問題中的第1段提到的期間輸入逃脫XSS。你有雙重逃跑的危險。您只需要在可能受到傷害的點上逃避它,也就是說,在視圖方面,它將在HTML,輸出之間內聯。我建議擺脫所謂的XSS過濾器,並通過使用JSTL <c:out>fn:escapeXml()(或自定義EL解析器,但絕對不是常規方法)將注意力集中在視圖側。未來的代碼維護者將非常感激。

+1

不要使用'fn:escapeXml'來轉義HTML。它會生成''',它不是一個標準的HTML實體。 – 2010-12-17 16:05:25

+1

@羅蘭:不,它沒有。它生成''',它在HTML和XML中都是有效的(就像'c:out'一樣)。 – BalusC 2010-12-17 16:12:27

+0

啊,那太好了。所以我必須與其他'escapeXml'函數混淆。可以肯定的是,我在JSTL規範中進行了查找,其中明確提到了這一點。 – 2010-12-17 18:45:30

1

This blog post描述了一種自定義的ELResolver,用於轉義String類型的EL表達式值。註冊這個自定義ELResolver將導致它轉義所有EL表達式的輸出。在一個JSP必須以編程輸出HTML,你需要不涉及一個EL表達式,如自定義標籤或一個scriptlet機制的特殊情況:

<%= "Java expression hopefully returning safe HTML" %>