再談瀏覽器安全與跨域

安全

1.XSS攻擊的方式

XSS攻擊分爲存儲型XSS攻擊,反射性XSS攻擊

存儲型XSS攻擊一般發生在表單提交,接口請求時候(接口請求的話,在URL得query中可能傳入一些XSS攻擊代碼,在拼接sql的時候,·--表示註釋,可以把原本的sql語句註釋掉,換成自己的sql查詢語句,返回攻擊者想要的數據),亦或是在url中比如:

axios.get('http://www.hahaha.com/api/v1?name=<script>alert(document.cookie)</script>')

app.use('/api/v1',(req,res,next) => {
    res.send(name);
})

這樣後端把url中name解析後,值返回給瀏覽器,瀏覽器解析的時候,就執行了url中的代碼,攻擊者引導用戶點擊一些地方(小圖片等等等),然後

我們不能信任用戶的輸入,用戶的輸入的一些特殊符號比如尖括號都要轉義,而且不要允許瀏覽器可以謝蓋cookie,後端返回的response的header中設置http-only,而且對url要進行encode,用的是時候再decode

2.CSRF攻擊的方式和防止

CSRF是(cross site resquest forgery)跨站請求僞造

大概是這樣的:

用戶在訪問網站A的時候登陸了網站A,登錄後網站A服務器的response在客戶端cookie中存入了用戶的用戶信息,

在用戶沒有退出登陸前,瀏覽器是保存了用戶的sesion信息的

假設我想給媽媽轉一筆錢,我向銀行發送了一個http請求,在url中附帶了一些參數:

axois.get('http://www.bank.com/api?user=renye&mount=10000&for='renye_mom')

因爲瀏覽器自動攜帶cookie,登錄後,銀行服務器生成了sessionId並且放到了cookie中,所以這個httpq請求發送到服務器的時候,銀行可以驗證我的確是登錄了,操作成功。

但是,cookie是存在瀏覽器中的,不是存在某個網站的頁面的,因此如果攻擊者誘導我訪問了他自己做的網站,裏面可能有些什麼不可描述的東西,在這個網站中,攻擊者嵌入了一個img標籤:

<img src='http://www.bank.com/api?user='renye'&amount=10000&for="hacker"/>

網站加載的時候,img標籤沒有同源限制,因此頁面加載到這個標籤的時候,瀏覽器會帶着cookie發送http請求到這個src的url上,銀行服務器看到這個user沒變,而且cookie攜帶了,驗證通過了,完犢子,10000塊就莫得了。

那麼怎麼防禦呢?

1.http的請求頭裏面有有一個referer字段,它標識的是http請求的來源url,我們如果在銀行的頁面轉賬,這個referer就是以銀行的域名開頭的地址,服務器可以驗證這個字段,只有是來自自己域名的http請求蔡處理,但是問題是referer需要瀏覽器保證安全,那瀏覽器自己還有漏洞,豈不是把自己的安全給了第三方,不可不可

2.token

token登場!我們知道之所跨站請求僞造可以成功,是因爲http請求中攜帶了cookie,那我就不把用戶的登錄信息放到cookie中,我可以再http請求中以參數的形式放一個隨機的token,在服務器先攔截這個http,看看token對不對,再決定是否響應這個http請求。

流程如下:用戶發送登錄請求,服務器生成token(一段獨特的字符串 `${user}${id}${Date.now()}${hash(secret)}`),res.send給客戶端。客戶端代碼中,發送post登錄請求,在返回的promise中then解析出返回數據,在response中的token字段拿到,然後重點來了!客戶端代碼我用localStorage.set('token',response.token),然後發送請求的時候,我用:

localStotage.get('token')拿到這個token然後發送到服務器,這樣,登錄信息就不在cookie中,而在localstorage中了

。當然存的時候最好加個密,用個加密算法。而且,token用明文傳輸很危險,我們最好用https協議。

3.https的加密方式

剛纔提到了傳輸token要用https協議,那麼問題來了,什麼tm是https協議中的s呢?聽了這麼多年的非對稱加密,考試也考了,找實際上已經忘的一乾二淨。。。

 

非對稱加密:我向銀行發信息,銀行先給我一個公鑰,我用公鑰加密我們的信息,銀行收到信息用銀行的私鑰解密

大概是這樣的:當我們向一個協議爲https的站點發送請求的時候比如我們向https://www.bank.com發送請求,那麼首先銀行服務器就會先返回用銀行的私鑰加密了的網頁,和銀行的數字證書,然後客戶端在證書管理器中看有沒有這個證書,有的話就可以,客戶端對信息用公鑰加密,然後傳給服務器,服務器用私鑰解密。

跨域

1.jsonp

2.CORS:主要的方式

  1. 首先查看http頭部有無origin字段;
  2. 如果沒有,或者不允許,當成普通請求;
  3. 如果有且是允許的,再看是否是preflight(method=OPTIONS);
  4. 如果不是preflight(簡單請求),返回Allow-Origin,Allow-Credential等字段,並返回正常內容;
  5. 如果是preflight(非簡單請求),返回Allow-Headers,Allow-Methods等;

3.nginx

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章