2010-03-07 31 views
16

我可能在這裏是一個總的noob,但我仍然不確定CSRF(跨站點請求僞造)攻擊究竟是什麼。因此,讓我們看看三種情況...我是否有POST風險的CSRF攻擊風險,不需要用戶登錄?

1)我有一個POST表單,用於編輯我網站上的數據。我想要這些數據被編輯只有登錄的用戶。

2)我有一個網站,既可以登錄的用戶也可以使用客人。部分網站僅用於登錄用戶,但也有所有用戶都可以使用的POST表單 - 匿名而非(例如標準聯繫表單)。聯繫表格是否應該受到CSRF攻擊的保護?

3)我有一個網站根本沒有認證系統(當然,也許這是不現實的,所以我們可以說它有一個管理網站,它與其餘部分是分開的,管理部分得到了適當的保護)。該網站的主要部分僅供匿名用戶使用。它上面的POST表單需要保護嗎?

在1)的情況下,答案顯然是肯定的。但在2和3的情況下,我不知道(2和3之間的差異甚至是顯着的?)。

回答

32

還有的CSRF手段,每當這是針對在網站惡意的HTML或JavaScript嵌入在另一 HTML網頁(或電子郵件),這是成功執行。

一個例子是被放置在另一個網頁,然後再繼續這傻傻地詢問你的姓名和年齡的情況如下:

<form action="http://yoursite.com/transferfunds" method="post"> 
    Your name: <input type="text"><br> 
    Your age: <input type="text"><br> 
    <input type="submit"> 
    <input type="hidden" name="amount" value="1000"> 
    <input type="hidden" name="toaccount" value="12345678"> 
</form> 

注意,行動指向你的網站,該隱藏的輸入包括所需POST信息。此示例將嘗試將1000(無論以何種貨幣)的資金轉帳到帳號12345678.如果您需要在表單上登錄並實際檢查該資金,那麼上述情況當然只有在未知用戶有最近登錄了您的網站,但尚未註銷,或會話尚未過期。

爲了防止發生這種情況,最好的方法是在表單中添加一個基於請求的令牌並在服務器端對其進行驗證。即生成一個長的,唯一的,不可能猜到的隨機字符串,並將其存儲在會話中並嵌入爲表單的<input type="hidden">元素。提交表單時,將提交的令牌值與已經在會話中的令牌值進行比較(並立即刪除會話中的一個)。要更進一步,請使用CAPTCHA

在你的具體情況下,我認爲你實際上更擔心XSS,這與CSRF相反,但它反過來也可以成爲CSRF的來源。 XSS的一個例子是,當用戶進入其中將要在同一網站遲早會重新顯示輸入字段以下內容:

<form name="delete" action="admin/deleteusers" method="post"></form> 
<script>document.form.delete.submit();</script> 

每當你 - 如作爲根據管理員與評論查看頁面與(不可見的!)表單和腳本一起使用,那麼它將被成功執行。

防止XSS其實很簡單。在網頁上顯示任何用戶控制輸入(即請求URL,請求標頭,請求參數和請求主體)之前,只需HTML轉義。在PHP中,您可以使用htmlspecialchars()進行此操作,並在Java/JSP中使用JSTL fn:escapeXml()。這樣每個<將被轉換爲&lt;>&gt;,這將使得任何輸入的HTML/JS將按字面原樣顯示,因此不能被執行。

+0

謝謝 - 非常有幫助:)(即使我沒有特別提問,我發現與XSS的比較非常有用:))如果我理解正確,那麼我可能仍然希望使用類似於聯繫表單的CSRF來幫助在spambot預防,對嗎? –

+1

基於請求的令牌和/或驗證碼是最好的方法。目前還不清楚你的webapp編程語言是什麼。我檢查了你的問題歷史記錄,我猜你的目標是Python。您可能會發現http://captchas.net有用。該網站包含一個Python示例。 – BalusC

+0

謝謝,很好的回覆:)我想我或多或少知道如何在我選擇的技術(Django框架)中實現這一點。對攻擊本身的性質只是不清楚。 –