2010-07-20 32 views
8

防止或阻止PHP Web應用程序中的JavaScript注入發生所需的措施,以免泄漏敏感信息(PHP,HTML/XHTML和JavaScript中的最佳實踐)?在PHP Web應用程序中阻止JavaScript注入

+1

可能重複的[如何防止PHP中的代碼注入攻擊?](http://stackoverflow.com/questions/1205889/how-to-prevent-code-injection-attacks-in-php) – 2010-07-20 23:55:13

+0

@Gert G :我相信這個問題是關於SQL和XSS注入的......而不是JavaScript注入。 – Alerty 2010-07-21 00:05:31

+2

不完全重疊 - 這些技術適用,但還有其他措施未涵蓋在該問題中提出的項目中。見下文。 – 2010-07-21 00:05:42

回答

6

好的第一步是應用question Gert G linked中列出的方法。這包括詳細的各種可以在不同情況下用來清潔輸入功能,包括mysql_real_escape_stringhtmlentities()htmlspecialchars()strip_tags()addslashes()

一種更好的方式,只要有可能,是爲了避免直接將用戶輸入到你的數據庫。僱用whitelist input validation:在任何情況下,如果您只有有限的選項範圍,請從硬編碼值中選擇插入,而不是從任何面向客戶端的表單中獲取輸入。基本上,這意味着只有你接受的某些價值觀,而不是試圖消除/打擊惡意/惡意/惡意投入。

例如: 如果您的表單中包含項目的下拉列表,請不要使用此下拉列表中的輸入進行插入。請記住,惡意客戶可以編輯與表單提交一起發送的信息,即使您認爲他們只有有限的選項。相反,請將下拉菜單引用服務器端代碼中數組中的索引。然後使用該數組選擇要插入的內容。這樣,即使攻擊者試圖向您發送惡意代碼,它也不會實際觸及您的數據庫。

顯然,這不適用於自由形式的應用程序,如論壇或博客。對於那些,你必須回到「第一步」的技術。不過,通過白名單輸入驗證可以改進各種選項。

只要可能,您也可以使用parameterized queries(也稱爲帶有綁定變量的預準備語句)進行sql交互。這將告訴你的數據庫服務器,所有的輸入只是一個值,所以它減輕了注入攻擊帶來的很多潛在問題。在很多情況下,這甚至可以涵蓋自由形式的應用程序。

4

如果你沒有通過任何需要被格式化爲html然後使用:

strip_tags() <- Eliminates any suspicious html 

,然後運行以下保存到數據庫

mysql_real_escape_string() 

之前清理如果你的AJAX是節約用戶通過文本框或wysiwyg輸入html,然後查看使用HTMLPurifier去除javascript,但允許html標記。

+0

假設在我的csv文件中我有列的值,如那麼我怎樣才能刪除這個列值,並使其爲空 – 2014-09-15 10:13:35

6

將輸出到html的任何值與htmlspecialchars()對齊默認

只有當你需要輸出到本身包含html的html字符串時,才使用htmlspecialchars()的藉口。在這種情況下,您必須確保該字符串來自完全安全的來源。如果你沒有這種信心,那麼你必須通過白名單html過濾器來傳遞它,只允許有限的一組標籤,屬性和屬性值。你應該特別小心屬性值。你絕不應該允許所有的東西都作爲屬性值傳遞,特別是對於像src,hef,style這樣的屬性。

你應該知道你的web應用程序中的所有地方,你可以在不使用htmspeciachars()的情況下將任何內容輸出到html,確保你真的需要這些地方,並且要知道盡管你有信心,但這些地方都是潛在的漏洞。

如果您認爲這太過於謹慎:「爲什麼我需要使用htmlspecialchar()這個變量,我知道它只包含整數並且會釋放所有寶貴的CPU週期?」

記住這一點:你不知道,你只是想你知道,CPU週期是最便宜的東西在世界上幾乎所有的人都將等待數據庫或文件系統或內存訪問被浪費。

而且從不使用黑名單HTML過濾器。 YouTube上犯了那個錯誤,有人突然發現,只有第一<script>被刪除,如果在評論進入第二個你可以注入任何JavaScript爲觀衆瀏覽器。

同樣以避免SQL注入與mysql_real_escape_string治療(),您膠水SQL查詢,或更好,但使用PDO預處理語句的所有值。

2

我不提供,所以我會後我的建議其他的答案完全同意。

推薦閱讀 XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet

HTML注入: 每當顯示任何用戶提交的內容,應該適當清理與htmlspecialchars或者單引號內使用指定ENT_QUOTES時htmlentities。我建議不要用單引號封裝,並且總是用雙引號封裝你的屬性(不要忽略它們)。這適用於的東西,如:

<input value="<?php echo htmlspecialchars($var); ?>" /> 
<textarea><?php echo htmlspecialchars($var); ?></textarea> 
<p><?php echo htmlspecialchars($var); ?></p> 
<img width="<?php echo htmlspecialchars($var); ?>" /> 

JavaScript注入: 這是最好的做法(但並不總是可行的),以從來沒有迴音用戶內容爲事件和JavaScript。但是,如果你這樣做,就可以做一些事情來降低風險。只傳遞整數ID。如果您需要諸如類型說明符之類的內容,請在輸出之前提前使用白名單和/或條件檢查。只有在適當時纔可能強制用戶內容使用字母數字; preg_replace("/[^A-Za-z0-9]/", '', $string);,但要非常小心你在這裏允許的。僅在包含引號時才包含內容,並注意htmlspecialchars/htmlentities在這裏不能保護您。它將在運行時解釋,即使它已被翻譯成html實體。 這適用於的東西,如:

<a href="www.stackoverlow.com/?id=<?php echo (int)$id; ?>">Click</a> 
href, src, style, onClick, etc. 

,除非它已經被迫爲int或其他一些非常非常有限的字符集不迴應任何用戶內容到其他領域,如腳本標記等體(如你知道你在做什麼)。

SQL注入: 使用Prepared statements,綁定用戶的內容給他們,從不直接插入用戶的內容到查詢。我建議爲不同的基本語句類型創建一個具有輔助函數的準備語句的類(並且在這個主題上對所有數據庫語句進行功能化)。如果您選擇不使用準備好的語句,然後使用mysql_real_escape_string()或類似的(不和addslashes())。在存儲到數據庫之前儘可能驗證內容,如強制/檢查整型數據類型,對類型進行條件檢查等。使用正確的數據庫列類型和長度。記住這裏的主要目標是防止sql注入,但你也可以選擇在這裏做html/javascript注入保護。

其他資源 我已經做了一些在線研究,希望找到一個已經公開的簡單解決方案。我發現了OWASP ESAPI,但它看起來相當過時。到PHP版本的鏈接在幾個地方被打破。我相信我在這裏找到了它; ESAPI PHP但它又相當過時,並不像我希望的那麼簡單。但是,您可能會發現它很有用。總而言之,永遠不要假設你受到保護,比如在onClick屬性中使用htmlentities。您必須在正確的位置使用正確的工具,並避免在錯誤的位置進行操作。