2010-05-06 160 views
5

我正在開發一個Web應用程序,用戶可以在其中回覆博客條目。這是一個安全問題,因爲他們可以發送將呈現給其他用戶的危險數據(並由JavaScript執行)。XSS攻擊防範

他們無法格式化他們發送的文本。沒有「大膽」,沒有顏色,沒有任何東西。只是簡單的文字。 我想出了這個正則表達式來解決我的問題:「。 「 」?「

[^\\w\\s.?!()] 

,所以,只要這不是一個單詞字符(包括AZ,az,0-9),而不是一個空白,」 !「,」(「或」)「將被替換爲空字符串。比每個quatation標記都將替換爲:「& quot」。

我檢查前端的數據,並在服務器上查看。

有沒有什麼方法有人可以繞過這個「解決方案」?

我想知道StackOverflow如何做到這一點?這裏有很多格式,所以他們必須對它做一個很好的工作。

+0

什麼是您的服務器端語言? – 2010-05-06 13:41:04

+0

Java。我使用Servlets – Colby77 2010-05-06 14:04:31

+0

你沒有對'<>'說過任何事情,這可能是xss中使用的最重要的字符...... – rook 2010-05-06 18:05:12

回答

0

可以使用Fiddler旁路前端,例如追加表單信息。 在後端使用html編碼,例如<a> = & lt; a & gt;

這樣文本將顯示爲文本而不是html元素。

1
  1. 不允許HTML標記。
  2. 不輸出沒有HTML的用戶輸入的任何內容 - 首先轉義它。這是更重要的一點!做到這一點,你永遠不會有XSS問題。
  3. 提供預覽功能,以便用戶在發佈前可以看到它的外觀。

如果您必須允許HTML標記,請定義白名單並根據它檢查用戶輸入。你甚至可以使用這個正則表達式。

說你讓<p><a href="..."><img src="...">

  1. 發現,對於每場比賽比賽<\S[^>]*>
  2. 用戶串的一切,檢查它,<(p|a href="[^"]+"|img src="[^"]+")/?>|</(a|p)>
  3. ,如果它不符合這個嚴格的正則表達式, 把它扔掉。
  4. 請參閱上述第2點。
  5. 儘量刻意破壞您的系統。要求他人嘗試破壞你的系統。
2

我同意Tomalak,只是想補充幾點。

  1. 不允許HTML標記。這個想法是在呈現它們之前將用戶輸入視爲文本和html轉義字符。爲此目的使用OWASP's ESAPI項目。你應該知道的This page explains the various possible encodings
  2. 如果您必須允許HTML標記,請使用庫爲您進行過濾。不要寫自己的正則表達式;他們很難得到正確的。使用OWASP's Anti-Samy project - 它是專門爲此用例而設計的。
3

如果你只是想簡單的文字不用擔心過濾特定的html標籤。你想要的PHP的htmlspecialchars() equvilent。使用一個很好的辦法就是print htmlspecialchars($var,ENT_QUOTES);此功能將執行以下編碼:

'&' (ampersand) becomes '&amp;' 
'"' (double quote) becomes '&quot;' when ENT_NOQUOTES is not set. 
''' (single quote) becomes '&#039;' only when ENT_QUOTES is set. 
'<' (less than) becomes '&lt;' 
'>' (greater than) becomes '&gt;' 

這是最低級解決XSS的問題,你不需要,你不要」一些複雜的庫/正則表達式不明白(並且在所有的複雜性都成爲安全的敵人之後可能是不安全的)。

請確保運行free xss scanner測試您的XSS FILTER

1

我建議您閱讀the XSS Prevention Cheat Sheet,其中詳細介紹了避免XSS攻擊的最佳做法。基本上,你需要過濾的東西取決於它將被使用的上下文。

例如,在這種場景中:

<body>...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...</body> 

你需要做的:

& --> &amp; 
< --> &lt; 
> --> &gt; 
" --> &quot; 
' --> &#x27;  &apos; is not recommended 
/--> &#x2F;  forward slash is included as it helps end an HTML entity 

雖然在一href=""例子的情況下,你需要做一個urlescape:

」除字母數字字符外,使用轉義ASCII值小於256的所有字符轉義格式。在數據中包含不受信任的數據:URL不應該被允許,因爲沒有好方法通過轉義禁用攻擊以防止切換出URL。所有的屬性都應該被引用。未加引號的屬性可以分解爲許多字符,包括[空格]%* +, - /; < => ^和|。需要注意的是實體編碼在這方面也沒用。」

雖然引用的文章給出了完整的判決,希望有一個在這個答案足夠的信息,讓你開始。

0

第一刪除任何壞的字符序列,如超長UTF-8,無效的Unicode。

你需要更明確是否<和>被剝離或變成實體。

您還需要剝離或編碼雙單引號,否則攻擊者可以添加一個你沒有想到的固有事件,例如, <輸入名稱=「評論」值=「富‘onSomething =有效載荷; A =’」 >

如果你真的要允許HTML的一些子集,小心試圖用正則表達式解析它,特別是那些你拿出你自己,例如瀏覽器將渲染棘手的標籤<a b=">"onMouseOver=alert(42)>就好了,正則表達式可能會與它不匹配。看看前面提到的Anti-Samy

如果您允許具有hrefsrc屬性的HTML標記,請確保它們指向http(s):方案,而不是javascript:方案。