<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          2020全網(wǎng)最全前端安全綜述(深度好文!)

          共 5488字,需瀏覽 11分鐘

           ·

          2020-12-03 12:38

          前言

          大部分面試總結(jié)其實(shí)埋了很多坑,點(diǎn)到為止,但是坑還是需要埋的,今天這篇文章就是填第一個(gè)坑。上篇總結(jié)中就有一個(gè)題目

          33.能說一下你項(xiàng)目中遇到了哪些安全問題么,一般都是怎么解決的?

          xss、csrf、爬蟲、薅羊毛等安全問題

          傳輸加密、接口加簽、環(huán)境變量、token、輸入校驗(yàn)等

          那么前端平時(shí)開發(fā)中涉及到哪些安全問題呢,又都是怎么解決的呢,本文將一網(wǎng)打盡,同時(shí)建議各大中小公司,能夠在公司內(nèi)部實(shí)施的安全措施都應(yīng)該實(shí)施起來。

          以下是正文

          隨著前端的發(fā)展,前端應(yīng)用正在迅速變化。前端代碼承擔(dān)著與后端代碼幾乎相同的責(zé)任,可以做更多的事情,隨著公司體系越來越完善,開發(fā)框架和平臺的不斷成熟,需要開發(fā)者考慮的安全問題越來越少,但并不是開發(fā)者就不需要關(guān)心項(xiàng)目的安全問題。

          本文主要介紹幾種業(yè)務(wù)開發(fā)中經(jīng)常遇到的前端安全問題,由于篇幅有限本文點(diǎn)到為止,后續(xù)有機(jī)會(huì)會(huì)逐一展開來講,本文提供大量的圖例來說明問題。

          1. XSS

          XSS是跨站腳本攻擊的簡寫,攻擊者想盡一切方法 將一段腳本內(nèi)容放到目標(biāo)網(wǎng)站的目標(biāo)瀏覽器上解釋執(zhí)行。攻擊者將惡意腳本輸入到目標(biāo)網(wǎng)站中。當(dāng)其他用戶訪問該網(wǎng)站的時(shí)候,由于瀏覽器不知道它是由網(wǎng)站提供服務(wù)的腳本還是攻擊者埋入的腳本,因此將執(zhí)行此該腳本。攻擊者就可以很容易利用埋入的腳本進(jìn)行攻擊。

          1. 攻擊者編寫惡意攻擊的腳本
          2. 攻擊者訪問前端頁面,在輸入框中輸入編寫好的惡意腳本
          3. 攻擊者將惡意腳本進(jìn)行提交,后端將惡意腳本存儲(chǔ)在數(shù)據(jù)庫中
          4. 當(dāng)某些合法用戶訪問該網(wǎng)站的時(shí)候,該網(wǎng)站會(huì)獲取存儲(chǔ)在數(shù)據(jù)庫中的惡意腳本,但是瀏覽器不知道它是惡意腳本所以執(zhí)行了。

          其實(shí)就相當(dāng)于攻擊者在用戶端的頁面上注入了一段腳本,有了這段腳本攻擊者就可以為所欲為了

          防范
          1. 永遠(yuǎn)不要相信用戶的輸入,對用戶輸入的特殊字符串進(jìn)行轉(zhuǎn)譯,針對用戶的輸入設(shè)置標(biāo)簽白名單
          2. cookie設(shè)置HttpOnly,配合token或驗(yàn)證碼防范
          3. 設(shè)置CSP安全策略-可以通過兩種方式設(shè)置CSP,一種是meta標(biāo)簽,一種是HTTP響應(yīng)頭Content-Security-Policy

          2. CSRF

          CSRF是跨站請求偽造的簡寫,一種誘騙受害者提交惡意請求的攻擊,攻擊者盜用了你的身份,以你的名義發(fā)送惡意請求,請求到達(dá)后端時(shí),服務(wù)器將無法區(qū)分惡意請求和合法請求。。CSRF能夠做的事情包括:以你名義發(fā)送郵件,發(fā)消息,盜取你的賬號,甚至于購買商品,虛擬貨幣轉(zhuǎn)賬等。

          CSRF攻擊必須具備兩個(gè)流程

          1. 登錄受信任網(wǎng)站A,并在本地生成Cookie。
          2. 在不登出A的情況下,訪問危險(xiǎn)網(wǎng)站B。
          防范
          1. 同源檢測,直接禁止外域(受信域可以開白名單)對我們發(fā)起請求
          2. CSRF Token,就把Token以參數(shù)的形式加入請求了,提交給服務(wù)器的時(shí)候,服務(wù)器需要判斷Token的有效性
          3. Samesite Cookie屬性,Samesite=Strict只允許同源網(wǎng)站提交請求攜帶cookie

          3. 網(wǎng)絡(luò)傳輸安全

          中間人 (Man-in-the-middle attack, MITM) 是指攻擊者與通訊的兩端分別創(chuàng)建獨(dú)立的聯(lián)系, 并交換其所收到的數(shù)據(jù), 使通訊的兩端認(rèn)為他們正在通過一個(gè)私密的連接與對方直接對話, 但事實(shí)上整個(gè)會(huì)話都被攻擊者完全控制. 在中間人攻擊中, 攻擊者可以攔截通訊雙方的通話并插入新的內(nèi)容。

          是不是覺得有了https網(wǎng)絡(luò)傳輸安全問題就迎刃而解了呢,即使被中間人攔截了,數(shù)據(jù)也是加密的。其實(shí)不是這樣的,不知道大家有沒有使用過charles進(jìn)行抓包呢,如果數(shù)據(jù)都是加密的,為啥charles抓包后我們能夠看到傳輸?shù)拿魑哪?,其?shí)這就是中間人攻擊。

          charles中間人劫持


          防范
          1. 對于個(gè)人來說防止自己被中間人攻擊最基本的就是不要亂連不安全的網(wǎng)絡(luò)
          2. 公司APP來說應(yīng)該配置禁止被抓包

          3. APP和瀏覽器都應(yīng)該嚴(yán)格校驗(yàn)證書,不使用不安全的APP和瀏覽器

          4. 接口加簽

          通過上面的例子我們知道https并不是絕對安全的,他是會(huì)被中間人劫持的,那么我們有什么方法防止數(shù)據(jù)被篡改呢?

          接口加簽的目的是防止數(shù)據(jù)被篡改!

          舉兩個(gè)例子

          例子1:正常用戶提交轉(zhuǎn)賬申請,請求中攜帶正常用戶的用戶信息,他想轉(zhuǎn)賬N金額給用戶A,這樣的請求銀行沒法拒絕會(huì)正常轉(zhuǎn)賬,因?yàn)閿y帶了正常的用戶信息。但是當(dāng)中間人劫持了這個(gè)請求,他修改了轉(zhuǎn)賬賬號為B,修改了轉(zhuǎn)賬金額為M,這樣我們的錢會(huì)不會(huì)轉(zhuǎn)給其他人呢?

          例子2:我們辛辛苦苦寫了一個(gè)運(yùn)營小游戲,違規(guī)用戶隨便玩了一下得分為0,但是他通過Charles攔截了這個(gè)請求,修改了得分為10000,然后進(jìn)行提交,我們的正常服務(wù)器能否知道分?jǐn)?shù)是被篡改的呢?

          為了解決上述問題,我們可以引入接口加簽

          服務(wù)端網(wǎng)關(guān)首先會(huì)校驗(yàn)簽是不是對的,如果不對直接拒絕請求,而簽的生成和請求參數(shù)密密相關(guān),當(dāng)接口請求中的參數(shù)被篡改后,網(wǎng)關(guān)是沒法進(jìn)行驗(yàn)簽通過的,直接拒絕了請求,拋出錯(cuò)誤。

          5. 接口加密

          有時(shí)候我們的參數(shù)根本不想被人看見是啥,我們就可以利用參數(shù)加密了

          6. 接口防重放


          防重放也叫防復(fù)用,簡單來說,就是我獲取到這個(gè)請求的信息之后, 我什么也不改, 我就拿著接口的參數(shù)去重復(fù)請求這個(gè)充值的接口,也就是說我的請求是合法的,因?yàn)樗袇?shù)都是跟合法請求一模一樣的,也就是說: 服務(wù)端的 sign 驗(yàn)證一定能通過。如圖上的例子,即使我們不知道登錄賬戶名密碼,即使接口參數(shù)被加簽加密了,我們依舊能夠登錄并拿到登錄信息,我們根本不用關(guān)心加密加簽的邏輯,我們只需要簡單的重放攻擊即可。

          防重放設(shè)計(jì)
          1. 客戶端在請求中添加兩個(gè)參數(shù) 1.1 添加一個(gè)隨機(jī)不重復(fù)的字符串參數(shù) 比如uuid 至于怎么讓他不重復(fù),可以考慮拼接時(shí)間戳,md5隨機(jī)數(shù)等 1.2 添加一個(gè)請求時(shí)間的參數(shù) 如 time 值就是發(fā)送請求時(shí)的 時(shí)間戳
          2. 服務(wù)端接收到請求之后: 2.1 去緩存里中查找 uuid 這個(gè)參數(shù)對應(yīng)的值是否存在 2.2 如果不存在: 就把這個(gè)uuid的值保存到緩存中, 記錄這個(gè)請求 2.3 如果已存在: 存在那就證明, 已經(jīng)請求過一次了, 就不處理這個(gè)請求了

          這就是最簡單的防重放邏輯,接口只能調(diào)用一次,即使被中間人攻擊后也沒法進(jìn)行重放

          7. 環(huán)境檢測

          是不是瀏覽器


          是不是我們檢測上述變量就認(rèn)為是瀏覽器環(huán)境呢,其實(shí)不是這樣的,上面的變量都是可以被篡改的,所以可以作為參考,絕對不能過分的依賴!下面列舉幾項(xiàng)處理方案,可以看到當(dāng)我們檢測這些變量的時(shí)候,這些變量都是可以被篡改的。

          檢測變量對抗處理方案
          navigator.languagesObject.defineProperty(navigator,?'languages', {?get:?()?=>?["zh-CN",?"zh",?"en"]?});
          navigator.pluginsObject.defineProperty(navigator,?'plugins', { get:?()?=>?[1,?2,?3,?4,?5] });
          是不是模擬器


          一般我們檢測到這些變量的時(shí)候可以無腦的認(rèn)為就是模擬器,比如Puppeteer中我們啟動(dòng)的時(shí)候,navigator.webdriver這一屬性的值等于true的,常規(guī)瀏覽器中由于沒有這個(gè)屬性navigator.webdriver的值等于undefined的。

          Object.defineProperty(navigator,?'webdriver',?{
          ?get:?()?=>?undefined,
          });

          攻擊者這樣篡改后我們是不是就沒有辦法知道是不是webdriver了呢?其實(shí)我們還是有辦法判斷的,因?yàn)檫@邊只是返回了navigator.webdriver的值是非的,但是navigator上依舊有webdriver這個(gè)屬性,我們有沒有辦法檢測屬性是否存在呢?其實(shí)我們很容易拿到navigator上所有屬性的。

          var?attr?=?window.navigator,?result?=?[];
          do?{
          ????Object.getOwnPropertyNames(attr).forEach(function(a)?{
          ????????result.push(a)
          ????})
          }?while?(attr=Object.getPrototypeOf(attr));

          當(dāng)我們判斷navigator上有webdriver這個(gè)屬性的時(shí)候,就可以簡單的認(rèn)為這個(gè)是模擬器環(huán)境,是不是覺得很完美的判斷了是不是模擬器了,其實(shí)不是的,攻擊者甚至可以刪除掉webdriver屬性。

          delete?navigator.__proto__.webdriver

          這樣之后就完全抹去webdriver變量了,通過這個(gè)辦法來判斷是不是模擬器就沒有路子了。

          有沒有用戶行為


          通常我們可以通過判斷事件上的isTrusted屬性來判斷是不是真實(shí)的事件,大部分情況我們都能夠很好的處理,但是攻擊者是很可怕的,這些簡單的伎倆他們能夠輕輕松松的繞過,他可以重寫事件啊,比如:

          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);
          };

          通過上面的例子我們發(fā)現(xiàn),不管我們怎么攻防,攻擊者都是有辦法繞過去的。其實(shí)上面還都是簡單的攻防,攻擊者甚至可以自己定制瀏覽器,當(dāng)我們的頁面跑在攻擊者定制的瀏覽器中的時(shí)候,通過上面的那些方法我們真的無能為力了,那么是不是我們只能放棄了呢,其實(shí)不是的。

          辨別機(jī)器行為還是得需要驗(yàn)證碼

          8. 無處不在的驗(yàn)證碼

          驗(yàn)證碼這個(gè)名詞真正被發(fā)明出來是在2003年,這比很多概念晚多了,比如神經(jīng)網(wǎng)絡(luò)70年代就已經(jīng)有很多人在研究。卡內(nèi)基梅隆大學(xué)的Luis von Ahn,Manuel Blum, Nicholas J.Hopper等人首次提出了“CAPTCHA”這個(gè)詞。他們對驗(yàn)證碼系統(tǒng)做的很深刻的研究,并且將其付諸程序化。自此大量的驗(yàn)證碼開始被應(yīng)用到網(wǎng)站中,有效的阻止了黃牛軟件的肆虐。時(shí)至今日,每天有過億的驗(yàn)證碼被人們不斷地輸入著。

          傳統(tǒng)驗(yàn)證碼


          傳統(tǒng)驗(yàn)證碼易被各圖像識別軟件、打碼平臺輕易破解,人工智能飛速發(fā)展,因此扭曲的文本驗(yàn)證方式也不再是一個(gè)可靠的方法,據(jù)說已經(jīng)能夠解決99.8%的圖片字符型驗(yàn)證碼。由此誕生了很多新型的驗(yàn)證碼類型,其中國內(nèi)最具代表的就是極驗(yàn),國外的就是谷歌的reCAPTCHA,他們帶來了一種全新的模式。

          新型驗(yàn)證碼


          新型驗(yàn)證碼不僅很難破解,他的交互會(huì)更加的友善,甚至做到無驗(yàn)證碼,只有在需要進(jìn)行驗(yàn)證的時(shí)候才出來。下面是網(wǎng)易易盾的產(chǎn)品流程圖,其他產(chǎn)品都基本類似。背后依托強(qiáng)大的機(jī)器學(xué)習(xí)判斷行為到底是不是人。

          9. 代碼加密混淆

          代碼加密混淆大大降低了前端代碼的可讀性,同時(shí)一定程度上會(huì)增加代碼的體積。但是對于非常核心的業(yè)務(wù)邏輯,代碼加密是非常有必要的,比如:

          1. 前端加簽代碼,由于加簽是在前端進(jìn)行的,前端必須存有秘鑰和加簽規(guī)則,但是一旦被第三方知道加簽的秘鑰和規(guī)則,加簽也就不攻而破了,所以加簽的前端代碼必須得加密。
          2. 新型驗(yàn)證碼用戶行為采集代碼,新型驗(yàn)證碼涉及很多用戶行為的前端采集,然后提交后端分析,如果采集規(guī)則被第三方知道,那么攻擊者也就很好的進(jìn)行攻擊行為,所以采集代碼也是需要加密的。



          最后



          如果你覺得這篇內(nèi)容對你挺有啟發(fā),我想邀請你幫我三個(gè)小忙:

          1. 點(diǎn)個(gè)「在看」,讓更多的人也能看到這篇內(nèi)容(喜歡不點(diǎn)在看,都是耍流氓 -_-)

          2. 歡迎加我微信「qianyu443033099」拉你進(jìn)技術(shù)群,長期交流學(xué)習(xí)...

          3. 關(guān)注公眾號「前端下午茶」,持續(xù)為你推送精選好文,也可以加我為好友,隨時(shí)聊騷。


          點(diǎn)個(gè)在看支持我吧,轉(zhuǎn)發(fā)就更好了



          瀏覽 42
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久久九九热re6这里有精品 | 成人视频网 | 中文字幕日本无码 | 成人操B视频| 97婷婷综合 |