關於csrf,什麼是csrf,怎麼防範它?

小說明

因爲行文時過於隨意,被評論區的盆友指出,特將部分不相關的內容移除,以避免其餘人受到干擾,混淆概念javascript

先說下CSRF的定義

跨站請求僞造(英語:Cross-site request forgery),也被稱爲 one-click attack 或者 session riding,一般縮寫爲 CSRF 或者 XSRF, 是一種挾制用戶在當前已登陸的Web應用程序上執行非本意的操做的攻擊方法。[1]跨網站指令碼(XSS)相比,XSS 利用的是用戶對指定網站的信任,CSRF 利用的是網站對用戶網頁瀏覽器的信任php

簡單點說,CSRF 就是利用用戶的登陸態發起惡意請求。html

經過一個故事來介紹csrf

這是最近在知乎上看到的一個例子十分形象(因爲是微信內分享,我如今找不到連接了,直接把故事內容補上吧)前端

防盜系統啓動
媽媽: 給我看着衣服呀
小孩: 好的java

小偷來了node

正常工做:
小孩: 你是誰?
小偷: 我是張三
小孩:媽媽,有人偷衣服
媽媽: 誰?
小孩: 張三
小偷被抓git

漏洞:
小孩: 你是誰?
小偷: 我叫逗你玩
小孩: 媽媽有人偷衣服呀
媽媽: 誰?
小孩: 逗你玩
媽媽: ...程序員

csrf是讓用戶住不知情的狀況下,冒用其身份發起了一個請求
小偷: 你媽媽喊你去買洗衣粉github

如何攻擊

假設網站中有一個經過 Get 請求提交用戶評論的接口,那麼攻擊者就能夠在釣魚網站中加入一個圖片,圖片的地址就是評論接口web

<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>
複製代碼

若是接口是 Post 提交的,就相對麻煩點,須要用表單來提交接口

<html>
    <head>
        <script type="text/javascript"> function steal() { &emsp; iframe = document.frames["steal"]; iframe.document.Submit("transfer"); } </script>
    </head>

    <body onload="steal()">
        <iframe name="steal" display="none">
            <form method="POST" name="transfer"&emsp;action="http://www.myBank.com/Transfer.php">
                <input type="hidden" name="toBankId" value="11">
                <input type="hidden" name="money" value="1000">
            </form>
        </iframe>
    </body>
</html>
複製代碼

如何防護

防範 CSRF 能夠遵循如下幾種規則:

  1. Get 請求不對數據進行修改
  2. 不讓第三方網站訪問到用戶 Cookie
  3. 阻止第三方網站請求接口
  4. 請求時附帶驗證信息,好比驗證碼或者 token

SameSite

能夠對 Cookie 設置 SameSite 屬性。該屬性設置 Cookie 不隨着跨域請求發送,該屬性能夠很大程度減小 CSRF 的攻擊,可是該屬性目前並非全部瀏覽器都兼容。

驗證 Referer

對於須要防範 CSRF 的請求,咱們能夠經過驗證 Referer 來判斷該請求是否爲第三方網站發起的。

在後臺接收到請求的時候,能夠經過請求頭中的Referer請求頭來判斷請求來源

Token

服務器下發一個隨機 Token(算法不能複雜),每次發起請求時將 Token 攜帶上,服務器驗證 Token 是否有效。

node可使用 csurf中間件來防護csrf攻擊

var cookieParser = require('cookie-parser')
var csrf = require('csurf')
var bodyParser = require('body-parser')
var express = require('express')

// setup route middlewares
var csrfProtection = csrf({ cookie: true })
var parseForm = bodyParser.urlencoded({ extended: false })

// create express app
var app = express()

// parse cookies
// we need this because "cookie" is true in csrfProtection
app.use(cookieParser())

app.get('/form', csrfProtection, function (req, res) {
  // pass the csrfToken to the view
  res.render('send', { csrfToken: req.csrfToken() })
})

app.post('/process', parseForm, csrfProtection, function (req, res) {
  res.send('data is being processed')
})

複製代碼

在頁面模板視圖中(取決於您的模板語言;在這裏演示了handlebar風格),將csrfToken值設置爲一個名爲_csrf的隱藏輸入字段的值:

<form action="/process" method="POST">
  <input type="hidden" name="_csrf" value="{{csrfToken}}">
  
  Favorite color: <input type="text" name="favoriteColor">
  <button type="submit">Submit</button>
</form>
複製代碼

使用ajax怎麼避免csrf攻擊,前端代碼
當經過ajax訪問受保護的路由時,csrf令牌須要在請求中傳遞。一般,這是使用一個請求頭來完成的,由於添加一個請求頭一般能夠在不進行有效負載修改的狀況下在中心位置完成。 CSRF令牌從服務器端的req.csrftoken()調用中得到。這個令牌須要向客戶端公開,一般是將其包含在初始頁面內容中。一種多是將它存儲在一個HTML的標籤中,在這個標籤中,能夠在請求的時候經過JavaScript檢索值。

<meta name="csrf-token" content="{{csrfToken}}">
複製代碼

下面是一個使用Fetch API從頁面上的標籤中使用CSRF令牌發送到/進程路由的示例:

// Read the CSRF token from the <meta> tag
var token = document.querySelector('meta[name="csrf-token"]').getAttribute('content');

// Make a request using the Fetch API
fetch('/process',{
    credentials:'same-origin', // includes cookies in the request
    headers:{
        'CSRF-Token': token // is the csrf token as a header
    },
    method:'POST',
    body:{
        data:'data'
    }
})

複製代碼
token生成與解析(一個示例)
  • 生成過程: token=salt-hash, hash=哈希函數(salt+密碼)

  • 解密過程: const [salt, hash] = token.split('-'), 從新計算hash=哈希函數(salt+密碼), 而後比較

防抓包

使用HTTPS(HTTPS 仍是經過了 HTTP 來傳輸信息,可是信息經過 TLS 協議進行了加密。)替換HTTP,對傳輸的數據進行加密,這樣,當請求的信息被抓包工具抓包後,也沒法修改提交的數據.

其餘須要瞭解的一些web安全知識

密碼安全(加鹽,對稱加密,非對稱加密等)

密碼安全雖然大可能是後端的事情,可是做爲一名優秀的前端程序員也須要熟悉這方面的知識。

對於密碼存儲來講,必然是不能明文存儲在數據庫中的,不然一旦數據庫泄露,會對用戶形成很大的損失。而且不建議只對密碼單純經過加密算法加密,由於存在彩虹表的關係。

一般須要對密碼加鹽,而後進行幾回不一樣加密算法的加密。

node中對密碼進行加密一般使用crypto模塊,能夠在我以前的一篇文章裏看一下相關介紹node數據加密crypto

xss攻擊


在這裏補充一下有關於xss的一點內容
xss本質是html注入,和sql注入差很少. SQL,HTML,人類語言都是指令和數據混在一塊兒的,都存在注入風險(程序根據分隔符,標籤識別指令和數據,人類則是根據語境,語義和平常經驗判斷)
好比註冊用戶時,用戶輸入"張三"並提交,服務端會生成"

<p>歡迎新用戶,張三</p>
複製代碼

"傳給瀏覽器.若是用戶輸入

<script>alert('逗你玩')</script>
複製代碼

服務端就會生成

<p>歡迎新用戶,<script>alert('逗你玩')</script></p>
複製代碼

輸入用戶內容就會被瀏覽器識別爲指令執行,這就是xss注入;
小偷也是根據這個原理,輸入一個有特殊語義的名字,被其餘客戶端識別爲指令,從而完成了一次漂亮的存儲型xss注入式攻擊.

xss詳細的一些內容,童鞋們能夠去查閱相關資料,這裏就暫不贅述

結語

經評論區小夥伴提醒,行文邏輯考慮不周,作了點小調整
很感謝各位看到了最後,若是喜歡本片文章的話,點個贊鼓勵一下

參考資料

  1. csurf
  2. 地表最強面試圖譜
相關文章
相關標籤/搜索