跨站腳本攻擊(Cross Site Scripting),縮寫爲XSS。惡意攻擊者往Web頁面裏插入惡意javaScript代碼,當用戶瀏覽該頁之時,嵌入其中Web裏面的javaScript代碼會被執行,從而達到惡意攻擊用戶的目的。javascript
一個簡單的XSS攻擊
代碼:html
async function(ctx, next){ ctx.set('X-XSS-Protection',0); ctx.render('index',{from:ctx.query.from}); };
注意:插入X-XSS-Protection頭部使瀏覽器XSS攔截器失效。java
開始攻擊:jquery
你們發現網頁執行了一段腳本,並且這段腳本是用戶惡意輸入的。這就是XSS攻擊最簡單的一個案例。把本來應該顯示純文本的地方,執行了一段黑客寫入的腳本。chrome
那XSS攻擊有什麼危害呢?數據庫
一、盜取各種用戶賬號
二、控制企業數據,包括讀取、篡改、添加、刪除企業敏感數據的能力
三、盜竊企業重要的具備商業價值的資料
四、非法轉帳
五、強制發送電子郵件
六、網站掛馬
七、控制受害者機器向其它網站發起攻擊npm
XSS攻擊的分類
一、反射型segmentfault
又稱爲非持久性跨站點腳本攻擊。漏洞產生的緣由是攻擊者注入的數據反映在響應中。非持久型XSS攻擊要求用戶訪問一個被攻擊者篡改後的連接,用戶訪問該連接時,被植入的攻擊腳本被用戶遊覽器執行,從而達到攻擊目的。也就是我上面舉的那個簡單的XSS攻擊案例,經過url參數直接注入。而後在響應的數據中包含着危險的代碼。瀏覽器
當黑客把這個連接發給你,你就中招啦!安全
二、存儲型
又稱爲持久型跨站點腳本,它通常發生在XSS攻擊向量(通常指XSS攻擊代碼)存儲在網站數據庫,當一個頁面被用戶打開的時候執行。持久的XSS相比非持久性XSS攻擊危害性更大,容易形成蠕蟲,由於每當用戶打開頁面,查看內容時腳本將自動執行。
該網頁有一個發表評論的功能,該評論會寫入後臺數據庫,而且訪問主頁的時候,會從數據庫中加載出全部的評論。
當我添加一個評論,而且暗藏一個腳本,以下圖:
當別人訪問主頁的時候,剛剛黑客寫入的評論裏面的腳本被瀏覽器當成代碼執行了,用戶莫名其妙受到攻擊:
上面就是兩種XSS攻擊的兩種基本類型。固然黑客不會彈出一個框框給你,告訴你被攻擊,黑客不會這麼傻的~他能夠在用戶不知情的狀況下,盜取用戶的cookie,改變網頁業務邏輯等等。
XSS攻擊的注入點
一、HTML節點內容
這個其實就是我以前演示的,HTML節點中暗藏攻擊腳本。
二、HTML屬性
這裏img的src屬性是由用戶傳遞過來的值,當用戶把圖片地址寫成:1"%20onerror="alert(%27哈哈被攻擊%27)
你們看下面發生了什麼:
三、JavaScript代碼 (字符串提早關閉)
當JavaScript代碼中有一個變量是由用戶提供的數據,這個數據也有可能以前被寫入了數據庫。以下圖,當用戶輸入的內容爲:
小柚子";alert(%27哈哈你被攻擊了!%27);"
四、富文本
你們都知道,富文本其實就是一段HTML。既然它是一段HTML,那麼就存在XSS攻擊。並且富文本攻擊的防護相對比較麻煩。
XSS攻擊防護
chrome瀏覽器自帶防護,可攔截反射性XSS(HTML內容和屬性),js和富文本的沒法攔截,因此咱們必須得本身作一些防護手段。
一、HTML節點內容的防護
將用戶輸入的內容進行轉義:
var escapeHtml = function(str) { str = str.replace(/</g,'<'); str = str.replace(/</g,'>'); return str; }
ctx.render('index', {comments, from: escapeHtml(ctx.query.from || '')});
二、HTML屬性的防護
對空格,單引號,雙引號進行轉義
var escapeHtmlProperty = function (str) { if(!str) return ''; str = str.replace(/"/g,'&quto;'); str = str.replace(/'/g,'''); str = str.replace(/ /g,' '); return str; }
ctx.render('index', {posts, comments, from:ctx.query.from || '', avatarId:escapeHtmlProperty(ctx.query.avatarId || '')});
三、JavaScript的防護
對引號進行轉義
var escapeForJS = function(str){ if(!str) return ''; str = str.replace(/\\/g,'\\\\'); str = str.replace(/"/g,'\\"'); return str; }
四、富文本的防護
富文本的狀況很是的複雜,js能夠藏在標籤裏,超連接url裏,何種屬性裏。
<script>alert(1)</script> <a href="javascript:alert(1)"></a> <img src="abc" onerror="alert(1)"/>
因此咱們不能過用上面的方法作簡單的轉義。由於狀況實在太多了。
如今咱們換個思路,
提供兩種過濾的辦法:
1)黑名單
咱們能夠把<script/> onerror 這種危險標籤或者屬性歸入黑名單,過濾掉它。可是咱們想,這種方式你要考慮不少狀況,你也有可能漏掉一些狀況等。
2)白名單
這種方式只容許部分標籤和屬性。不在這個白名單中的,一概過濾掉它。可是這種方式編碼有點麻煩,咱們須要去解析html樹狀結構,而後進行過濾,把過濾後安全的html在輸出。
這裏提供一個包,幫助咱們去解析html樹狀結構,它使用起來和jquery很是的相似。
npm install cheerio --save
var xssFilter = function(html) { if(!html) return ''; var cheerio = require('cheerio'); var $ = cheerio.load(html); //白名單 var whiteList = { 'html' : [''], 'body' : [''], 'head' : [''], 'div' : ['class'], 'img' : ['src'], 'a' : ['href'], 'font':['size','color'] }; $('*').each(function(index,elem){ if(!whiteList[elem.name]) { $(elem).remove(); return; } for(var attr in elem.attribs) { if(whiteList[elem.name].indexOf(attr) === -1) { $(elem).attr(attr,null); } } }); return $.html(); } console.log(xssFilter('<div><font color="red">你好</font><a href="http://www.baidu.com">百度</a><script>alert("哈哈你被攻擊了")</script></div>'));
你們能夠看到:
<script>不在白名單中,因此被過濾掉了。
五、CSP(Content Security Policy)
內容安全策略(Content Security Policy,簡稱CSP)是一種以可信白名單做機制,來限制網站中是否能夠包含某來源內容。默認配置下不容許執行內聯代碼(<script>塊內容,內聯事件,內聯樣式),以及禁止執行eval() , newFunction() , setTimeout([string], ...) 和setInterval([string], ...) 。
示例:
1.只容許本站資源
Content-Security-Policy: default-src ‘self’
2.容許本站的資源以及任意位置的圖片以及 https://segmentfault.com 下的腳本。
Content-Security-Policy: default-src ‘self’; img-src *; script-src https://segmentfault.com