关于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. 地表最强面试图谱
相关文章
相关标签/搜索