簡體   English   中英

如何使用OWASP HTML Sanitizer允許特定字符?

[英]How to allow specific characters with OWASP HTML Sanitizer?

我正在使用OWASP Html Sanitizer來防止對我的網絡應用程序進行XSS攻擊。 對於許多應該是純文本的字段,Sanitizer的效果超出了我的預期。

例如:

HtmlPolicyBuilder htmlPolicyBuilder = new HtmlPolicyBuilder();
stripAllTagsPolicy = htmlPolicyBuilder.toFactory();
stripAllTagsPolicy.sanitize('a+b'); // return a+b
stripAllTagsPolicy.sanitize('foo@example.com'); // return foo@example.com

當我的電子郵件地址等字段中包含+ ,如foo+bar@gmail.com我最終會在數據庫中輸入錯誤的數據。 所以有兩個問題:

  1. + - @這樣的字符本身是否真的需要編碼?
  2. 如何配置OWASP html清理程序以允許特定字符,如+ - @?

問題2對我來說是更重要的答案。

您可能希望使用ESAPI API過濾特定字符。 雖然如果您想允許特定的HTML元素或屬性,可以使用以下allowElements和allowAttributes。

//定義策略。

Function<HtmlStreamEventReceiver, HtmlSanitizer.Policy> policy
     = new HtmlPolicyBuilder()
         .allowElements("a", "p")
         .allowAttributes("href").onElements("a")
         .toFactory();

 // Sanitize your output.
 HtmlSanitizer.sanitize(myHtml, policy.apply(myHtmlStreamRenderer));

XSS中的危險在於,一個用戶可能會在其輸入數據中插入html代碼,您稍后會將這些代碼插入發送給另一個用戶的網頁中。

如果您想要防止這種情況,原則上可以遵循兩種策略。 您可以在用戶輸入系統進入系統時刪除所有危險字符,也可以在以后將其寫回瀏覽器時對危險字符進行html編碼。

第一個策略示例:

用戶輸入數據(使用html代碼)

  1. 服務器刪除所有危險字符
  2. 修改后的數據存儲在數據庫中
  3. 一段時間后,服務器從數據庫讀取修改后的數據
  4. 服務器將網頁中的修改數據插入另一個用戶

第二個策略示例:

  1. 用戶輸入數據(使用html代碼)
  2. 具有危險字符的未修改數據存儲在數據庫中
  3. 一段時間后,服務器從數據庫中讀取未修改的數據
  4. 服務器對危險數據進行html編碼,並將其插入到另一個用戶的網頁中

第一種策略更簡單,因為您通常不經常讀取數據而使用它們。 但是,它也更難,因為它可能會破壞數據。 如果您需要的數據不是稍后將其發送回瀏覽器(例如使用電子郵件地址來實際發送電子郵件),則特別困難。 這使得在數據庫中進行搜索,在pdf報告中包含數據,在電子郵件中插入數據等等更加困難。

另一種策略的優點是不會破壞輸入數據,因此您可以更自由地在以后使用數據。 但是,實際檢查是否對發送到瀏覽器的所有用戶提交的數據進行html編碼可能更加困難。 解決您的特定問題的方法是在您(或者如果)將該電子郵件地址放在網頁上時對電子郵件地址進行html編碼。

XSS問題是混合用戶提交的數據和控制代碼時出現的更普遍問題的示例。 SQL注入是同一問題的另一個例子。 問題是用戶提交的數據被解釋為指令而不是數據。 第三個不太為人所知的例子是,如果您在電子郵件中混合用戶提交的數據。 用戶提交的數據可能包含電子郵件服務器解釋為指令的字符串。 這種情況下的“危險角色”是換行符后跟“From:”。

不可能針對所有可能的控制字符或字符序列驗證所有輸入數據,這些字符可能在某種程度上被解釋為將來某些潛在應用中的指令。 對此唯一的永久解決方案是在實際使用該數據時實際清理所有可能不安全的數據。

說實話,你應該真正針對所有用戶提供的輸入進行白名單。 如果它是一個電子郵件地址,只需使用OWASP ESAPI或其他東西驗證輸入與其Validator和電子郵件正則表達式。

如果輸入通過白名單,您應該繼續將其存儲在數據庫中。 將文本顯示給用戶時,應始終對其進行HTML編碼。

OWASP不建議您使用黑名單方法,並且可能會被承諾攻擊用戶的人繞過。

我知道7年后我會回答問題,但也許對某人有用。 所以,基本上我同意你們的意見,出於安全考慮,我們不應該允許特定角色(你們已經涵蓋了這個主題,謝謝)。 然而,我正在研究傳統的內部項目,該項目需要轉義html字符,但“@”因為我無法分辨(但無關緊要)。 我的解決方法很簡單:

private static final PolicyFactory PLAIN_TEXT_SANITIZER_POLICY = new HtmlPolicyBuilder().toFactory();


public static String toString(Object stringValue) {
    if (stringValue != null && stringValue.getClass() == String.class) {
        return HTMLSanitizerUtils.PLAIN_TEXT_SANITIZER_POLICY.sanitize((String) stringValue).replace("&#64;", "@");
    } else {
        return null;
    }
}

我知道它不干凈,創建額外的String,但我們非常需要這個。 因此,如果您需要允許特定字符,則可以使用此解決方法。 但是,如果您需要這樣做,您的應用程序可能設計不正確。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM