2009-08-13 62 views
17

當我準備解決輸入數據過濾和消毒問題時,我很好奇是否有最佳(或最常用)的做法?在將數據插入數據庫之前過濾/清理數據(HTML,JavaScript等)是更好的方法,還是應該在數據準備好以HTML格式顯示時完成?何時過濾/清理數據:在數據庫插入之前或顯示之前?

的幾個注意事項:

  • 我這樣做在PHP,但我懷疑這個問題的答案是語言無關。但是,如果您有任何特定於PHP的建議,請分享!
  • 這不是轉義數據庫插入數據的問題。我已經有很好的PDO處理。

謝謝!

+0

查看我的答案:http://stackoverflow.com/questions/129677/whats-the-best-method-for-sanitizing-user-input-with-php/130323#130323 – troelskn 2009-08-13 21:49:15

回答

17

說到顯示用戶提交的數據,普遍接受的口頭禪是「過濾輸入,轉義輸出」。

在進入數據庫之前,我會建議不要轉義諸如html實體之類的東西,因爲您永遠不知道HTML何時不會成爲您的顯示媒介。另外,不同類型的情況需要不同類型的輸出轉義。例如,在Javascript中嵌入字符串需要不同於HTML中的轉義。之前這樣做可能會讓你陷入虛假的安全感。

因此,基本的經驗法則是,在使用之前進行消毒,並專門用於該用途;不是先發制人。 (請注意,我不是在談論爲SQL轉義輸出,只是爲了顯示,請仍然爲SQL字符串綁定轉義數據)。

+0

+1優秀的技巧總體而言,尤其是「在進入數據庫之前,我會建議不要轉義諸如html實體之類的東西,因爲你永遠不知道HTML何時不會成爲你的顯示媒體」8年後的 – Jeach 2013-04-30 15:01:46

8

我喜歡以原始形式存儲/存儲數據。 我只根據我使用它的位置轉義/過濾數據。

    網頁上的
  • - 編碼的所有HTML
  • 上的SQL - 殺報價
  • 上網址 - URL編碼
  • 上的打印機 - 編碼它那份工作
  • - 編碼逃避對什麼都命令
6

如果需要,在數據庫放入數據庫之前對其進行清理(如果您沒有使用數據庫交互層來處理該數據庫)。在顯示之前對其進行消毒以供顯示。

以目前不必要的引用形式存儲事物只會導致太多問題。

6

至少有兩種類型的過濾/消毒的,你應該關心:

  • SQL
  • HTML

很明顯,第一個有前/時被照顧將數據插入數據庫,以防止SQL注入。
但是你已經知道了,正如你所說的,所以我不會再多談這件事。


第二個,在另一方面,是一個更有趣的問題:

  • 如果您的用戶必須能夠修改他們的數據,但有趣的是它歸還給他們以同樣的方式,他們一開始就進入它;這意味着你必須存儲一個「非html-specials-escaped」版本。
  • 如果你想有一些顯示HTML,你也許使用類似HTMLPurifier:很強大......但是,如果你在每個數據運行它時,它必須顯示可能需要有點過分資源.. 。

所以:

  • 如果你想顯示一些HTML,使用重型工具來驗證/過濾它,我會說,你需要一個已經過濾/任何版本存儲到數據庫,不破壞服務器,每次顯示數據時重新創建它
    • 但你也需要存儲「原始」版(見我之前說的)
    • 在這種情況下,我可能會存儲兩個版本到數據庫,即使它需要更多的地方......或者至少使用一些好的緩存機制,不要一遍又一遍地重新創建乾淨的版本。
  • 如果不想顯示任何HTML,你將使用htmlspecialchars或等價物,這可能不是太大的CPU吃的......所以它可能沒有多大意義
    • 你仍然需要存儲的「原始」版本
    • 但是當你outputing數據可能會好逃跑。

BTW,第一解決方案也很好,如果輸入的數據,當用戶在使用類似的bbcode /降價/ wiki和你使其在HTML ...
至少,作爲只要它比更新顯示更頻繁 - 特別是如果您不使用任何緩存來存儲乾淨的HTML版本。

+0

(Re:特別消毒HTML),現在客戶端呈現是很常見的,「我想說你需要將一個已經過濾/無論什麼版本存儲到數據庫中,以便不破壞服務器」,現在更關聯點。對HTML進行消毒是一項代價高昂的操作,在許多情況下,通過保存而不是顯示時進行消毒更有意義。在操作方面存在着明顯的損失,在更新清理規則時需要進行數據遷移,但在許多情況下,這些折衷是有價值的。 – 2017-11-15 18:19:47

3

主要是它取決於你打算與輸入,以及開發環境做。

在大多數情況下,你想要原來的輸入。通過這種方式,您可以調整輸出到您內心的內容,而不用擔心丟失原始內容。這也可以讓你解決諸如輸出錯誤等問題。您始終可以看到您的過濾器是多麼的錯誤,或者客戶的輸入是錯誤的。

另外一些短期的語義數據可以立即過濾。 1)你不想在數據庫中使用雜亂的電話號碼,所以對於這樣的事情來說,消毒可能是件好事。 2)您不希望其他程序員在不轉義的情況下意外輸出數據,並且您在多程序員環境中工作。但是,對於大多數情況下,原始數據是更好的IMO。

5

我總是說馬上將它們傳遞給他們需要轉義的地方之前逃脫的事情。您的數據庫不關心HTML,因此在存儲到數據庫中之前轉義HTML是不必要的。如果您想要輸出HTML以外的內容,或者更改哪些標籤被允許/不允許,您可能需要做一些工作。而且,在需要完成時要記住做出轉義的權利比在過程的更早階段更容易記住。

還值得注意的是,HTML轉義的字符串可能比原始輸入長得多。如果我在註冊表單中輸入日文用戶名,原始字符串可能只有4個Unicode字符,但HTML轉義可能會將其轉換爲長字符串「〹 𐤲 䡈 穩」 。然後,我的4個字符的用戶名對於您的數據庫字段來說太長,並且以兩個日文字符加上一半的轉義碼存儲,這也可能阻止我登錄。

請注意,瀏覽器傾向於轉義某些內容,如非 - 提交表格中的英文文本,並且總是會有那些在任何地方都使用日文用戶名的smartass。因此,您可能希望在存儲之前實際使用HTML。

相關問題