2016-02-01 45 views
1

我想知道是否有必要逃避MySQL服務器的輸出如果被檢索的數據,當用戶提交表單已經被過濾。如果正在檢索的數據已經過清理,是否需要從MySQL服務器轉義輸出?

示例:
1.用戶提交表單並附帶對博客帖子的評論。
2.在表單提交之前,將數據發送到MySQL服務器,它們的輸入被過濾,用FILTER_SANITIZE_SPECIAL_CHARS,以防止注入攻擊。
3.一旦數據發佈到服務器,用戶就會重新路由到另一個屏幕,他們可以查看他們的評論。
4.當從服務器檢索(已存儲的經濾波的輸入)他們的評論,是有必要逃脫這個輸出中呢?

下面是我的主要問題。我從表單(用於博客文章)中接收用戶輸入,用FILTER_SANITIZE_SPECIAL_CHARS進行消毒,然後將其發佈到MySQL服務器。如果我從服務器檢索到這些信息並將其顯示在html中,則沒有問題。但是,我一直在閱讀,你應該總是逃避服務器的輸出。所以我逃過了htmlspecialchars()這個帖子。現在,我遇到了所有特殊字符(包括圓括號和用戶在其帖子中使用的任何引號)以其轉義的html格式返回的問題。不用用戶友好。

什麼是最好的解決辦法這一點,或者是它甚至有必要逃避輸出,如果它是來自服務器和已消毒用戶輸入?

+1

HTML編碼輸出,而不是輸入。 –

回答

4

消毒是不是就像逃跑一樣,你應該確保不要混淆兩者。

消毒正在消除不需要的輸入。也就是說,如果用戶將<script>標記添加到其輸入中,並且您不希望其輸入包含<script>標記,那麼刪除該<script>標記將會進行消毒。消毒是而不是轉義輸出上下文的數據。

轉義正確編碼輸出上下文的數據。例如,爲了防止HTML注入,您可以撥打htmlspecialchars()&正確編碼爲&amp;。爲防止SQL注入,您可以使用mysqli::real_escape_string()'轉換爲\'。 (雖然這將是高度優選使用準備的語句/參數化查詢,以防止不必擔心SQL注入或逸出的。)

重要,逸出是上下文特定的。用於HTML的轉義不一定對SQL有效或足夠(反之亦然,或任何其他輸出上下文)。

FILTER_SANITIZE_SPECIAL_CHARS的問題在於它命名不佳:它在一個步驟中執行,這會混淆您的數據庫(因爲您的數據庫現在具有html編碼的數據),並且會混淆輸出(因爲現在您已經轉義的數據容易被多次轉義)。

相反,你應該明確地分開你的消毒和逃避的努力。 只有清理您不想保留的輸入數據。只有轉義輸出數據,並根據其正確的輸出上下文。

您想要在數據庫中存儲原始數據(輸出前轉義數據)的原因是,如果您需要輸出到不同的上下文(例如,現在您是dong JSON輸出,或者您需要寫入它到一個文件,或實際上看到原始數據是什麼),你不需要先取消它。 (如果您確實必須這樣做,您可能會合理地將一個預先保存的副本存儲在單獨的專欄中,但您應始終保留原始數據。)它也使規則變得簡單:始終清理輸入;總是逃避輸出。

+2

偉大的答案,我希望更多的人會花時間來理解這些基本的東西:-) – jgivoni

相關問題