上一篇面試總結中其實埋了不少坑,作到點到爲止,可是坑仍是須要埋的,今天這篇文章就是埋第一個坑。上篇總結中就有一個題目javascript
33.能說一下你項目中遇到了哪些安全問題麼,通常都是怎麼解決的?前端
xss、csrf、爬蟲、薅羊毛等安全問題傳輸加密、接口加簽、環境變量、token、輸入校驗等java
那麼前端平時開發中涉及到哪些安全問題呢,又都是怎麼解決的呢,本文將一網打盡,同時建議各大中小公司,可以在公司內部實施的安全措施都應該實施起來。web
隨着前端的發展,前端應用正在迅速變化。 前端代碼承擔着與後端代碼幾乎相同的責任,能夠作更多的事情,隨着公司體系愈來愈完善,開發框架和平臺的不斷成熟,須要開發者考慮的安全問題愈來愈少,但並非開發者就不須要關心項目的安全問題。面試
本文主要介紹幾種業務開發中常常遇到的幾種前端安全問題,因爲篇幅有限本文點到爲止,後續有機會會逐一展開來說,本文提供大量的圖例來講明問題。數據庫
XSS是跨站腳本攻擊的簡寫,攻擊者想盡一切方法 將一段腳本內容放到目標網站的目標瀏覽器上解釋執行。攻擊者將惡意腳本輸入到目標網站中。 當其餘用戶訪問該網站的時候,因爲瀏覽器不知道它是由網站提供服務的腳本仍是攻擊者埋入的腳本,所以將執行此該腳本。攻擊者就能夠很容易利用埋入的腳本進行攻擊。後端
其實就至關於攻擊者在用戶端的頁面上注入了一段腳本,有了這段腳本攻擊者就能夠隨心所欲了瀏覽器
CSRF是跨站請求僞造的簡寫,一種誘騙受害者提交惡意請求的攻擊,攻擊者盜用了你的身份,以你的名義發送惡意請求,請求到達後端時,服務器將沒法區分惡意請求和合法請求。。CSRF可以作的事情包括:以你名義發送郵件,發消息,盜取你的帳號,甚至於購買商品,虛擬貨幣轉帳等。緩存
CSRF攻擊必須具有兩個流程安全
中間人 (Man-in-the-middle attack, MITM) 是指攻擊者與通信的兩端分別建立獨立的聯繫, 並交換其所收到的數據, 使通信的兩端認爲他們正在經過一個私密的鏈接與對方直接對話, 但事實上整個會話都被攻擊者徹底控制. 在中間人攻擊中, 攻擊者能夠攔截通信雙方的通話並插入新的內容。
是否是以爲有了https網絡傳輸安全問題就迎刃而解了呢,即便被中間人攔截了,數據也是加密的。其實不是這樣的,不知道你們有沒有使用過charles進行抓包呢,若是數據都是加密的,爲啥charles抓包後咱們可以看到傳輸的明文呢,其實這就是中間人攻擊。
經過上面的例子咱們知道https並非絕對安全的,他是會被中間人劫持的,那麼咱們有什麼方法防止數據被串改呢?
接口加簽的目的是防止數據被串改!
舉兩個例子
例子1:正經常使用戶提交轉帳申請,請求中攜帶正經常使用戶的用戶信息,他想轉帳N金額給用戶A,這樣的請求銀行無法拒絕會正常轉帳,由於攜帶了正常的用戶信息。可是當中間人劫持了這個請求,他修改了轉帳帳號爲B,修改了轉帳金額爲M,這樣咱們的錢會不會轉給其餘人呢?
例子2:咱們辛辛苦苦寫了一個運營小遊戲,違規用戶隨便玩了一下得分爲0,可是他經過Charles攔截了這個請求,修改了得分爲10000,而後進行提交,咱們的正常服務器可否知道分數是被串改的呢?
爲了解決上述問題,咱們能夠引入接口加簽
服務端網關首先會校驗籤是否是對的,若是不對直接拒絕請求,而籤的生成和請求參數密密相關,當接口請求中的參數被串改後,網關是無法進行驗籤經過的,直接拒絕了請求,拋出錯誤。
有時候咱們的參數根本不想被人看見是啥,咱們就能夠利用參數加密了
防重放也叫防複用,簡單來講,就是我獲取到這個請求的信息以後, 我什麼也不改, 我就拿着接口的參數去重複請求這個充值的接口,也就是說個人請求是合法的,由於全部參數都是跟合法請求如出一轍的,也就是說: 服務端的 sign 驗證必定能經過。如圖上的例子,即便咱們不知道登陸帳戶名密碼,即便接口參數被加簽加密了,咱們依舊可以登陸並拿到登陸信息,咱們根本不用關心加密加簽的邏輯,咱們只須要簡單的重放攻擊便可。
uuid
至於怎麼讓他不重複,能夠考慮拼接時間戳,md5隨機數等time
值就是發送請求時的 時間戳
這就是最簡單的防重放邏輯,接口只能調用一次,即便被中間人攻擊後也無法進行重放
是否是咱們檢測上述變量就認爲是瀏覽器環境呢,其實不是這樣的,上面的變量都是能夠被串改的,因此能夠做爲參考,絕對不能過度的依賴!下面列舉幾項處理方案,能夠看到當咱們檢測這些變量的時候,這些變量都是能夠被串改的。
檢測變量 | 對抗處理方案 |
---|---|
navigator.languages | Object.defineProperty(navigator, 'languages', { get: () => ["zh-CN", "zh", "en"] }); |
navigator.plugins | Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5] }); |
通常咱們檢測到這些變量的時候能夠無腦的認爲就是模擬器,好比Puppeteer
中咱們啓動的時候,navigator.webdriver
這一屬性的值等於true
的,常規瀏覽器中因爲沒有這個屬性navigator.webdriver
的值等於undefined
的。
Object.defineProperty(navigator, 'webdriver', { get: () => undefined, });
攻擊者這樣串改後咱們是否是就沒有辦法知道是否是webdriver
了呢?其實咱們仍是有辦法判斷的,由於這邊只是返回了navigator.webdriver
的值是非的,可是navigator
上依舊有webdriver
這個屬性,咱們有沒有辦法檢測屬性是否存在呢?其實咱們很容易拿到navigator
上全部屬性的。
var attr = window.navigator, result = []; do { Object.getOwnPropertyNames(attr).forEach(function(a) { result.push(a) }) } while (attr=Object.getPrototypeOf(attr));
當咱們判斷navigator
上有webdriver
這個屬性的時候,就能夠簡單的認爲這個是模擬器環境,是否是以爲很完美的判斷了是否是模擬器了,其實不是的,攻擊者甚至能夠刪除掉webdriver
屬性。
delete navigator.__proto__.webdriver
這樣以後就徹底抹去webdriver
變量了,經過這個辦法來判斷是否是模擬器就沒有路子了。
一般咱們能夠經過判斷事件上的isTrusted
屬性來判斷是否是真實的事件,大部分狀況咱們都可以很好的處理,可是攻擊者是很可怕的,這些簡單的伎倆他們可以輕輕鬆鬆的繞過,他能夠重寫事件啊,好比:
function clone(e) { const t = {}; for (let attr in e) { if (typeof e[attr] === "function") { t[attr] = e[attr]; } else { Object.defineProperty(t, attr, { get: () => { if (attr === 'isTrusted') { return true; } return e[attr]; }, set: v => { e[attr] = v; } }); } } return t; } const oldAEL = document.addEventListener; window.addEventListener = document.addEventListener = function (e, func, c) { const newFunc = function (event) { const newEvent = clone(event); return func(newEvent); }; return oldAEL.call(this, e, newFunc, c); };
經過上面的例子咱們發現,無論咱們怎麼攻防,攻擊者都是有辦法繞過去的。其實上面還都是簡單的攻防,攻擊者甚至能夠本身定製瀏覽器,當咱們的頁面跑在攻擊者定製的瀏覽器中的時候,經過上面的那些方法咱們真的無能爲力了,那麼是否是咱們只能放棄了呢,其實不是的。
辨別機器行爲仍是得須要驗證碼
驗證碼這個名詞真正被髮明出來是在2003年,這比不少概念晚多了,好比神經網絡70年代就已經有不少人在研究。卡內基梅隆大學的Luis von Ahn,Manuel Blum, Nicholas J.Hopper等人首次提出了「CAPTCHA」這個詞。他們對驗證碼系統作的很深入的研究,而且將其付諸程序化。自此大量的驗證碼開始被應用到網站中,有效的阻止了黃牛軟件的肆虐。時至今日,天天有過億的驗證碼被人們不斷地輸入着。
傳統驗證碼易被各圖像識別軟件、打碼平臺輕易破解,人工智能飛速發展,所以扭曲的文本驗證方式也再也不是一個可靠的方法,聽說已經可以解決99.8%的圖片字符型驗證碼。由此誕生了不少新型的驗證碼類型,其中國內最具表明的就是極驗,國外的就是谷歌的reCAPTCHA,他們帶來了一種全新的模式。
新型驗證碼不只很難破解,他的交互會更加的友善,甚至作到無驗證碼,只有在須要進行驗證的時候纔出來。下面是網易易盾的產品流程圖,其餘產品都基本相似。背後依託強大的機器學習判斷行爲究竟是不是人。
代碼加密混淆大大下降了前端代碼的可讀性,同時必定程度上會增長代碼的體積。可是對於很是核心的業務邏輯,代碼加密是很是有必要的,好比:
歡迎關注公衆號:前端複習課,一塊兒分享交流前端知識