cookie和CSRF、xss攻击

cookie是什么

首先需要明白的是,

  1. cookie是储存在浏览器中的一段字符串,它本身是没有任何危害的,不包含任何可执行的代码。
  2. 储存cookie是浏览器的功能,浏览器的安装目录下会有一个专门存放不同域名下的cookie的文件夹。
  3. 当网页发起http请求的时候,浏览器首先会检查是否有对应域名的cookie,如果有,就会自动添加到request header中,发送给服务器。
  4. cookie的存放有大小限制,不可以超过4kb, 每一个域名下的cookie数量最多是20个

图解cookie的运行机制

我们以百度登录的cookie为例,当我们没有登录前,给www.baidu.com发送http请求,返回的数据

登录前.png

当我们登陆后,再访问百度的域名后


登录后.png

基本通讯流程: 登录的时候,百度服务器会response header会返回一个不同用户的一个标识符(cookie) => 登录完成后,访问百度的主页的时候,浏览器会自动在request header带上刚刚存放的cookie去请求百度的服务器 => 百度服务器接收到对应的cookie后,返回不同用户的数据给浏览器。

cookie的格式

获取cookie

JS原生的api提供了获取cookie的方法,document.cookie(注意,这个方法只能获取非 HttpOnly 类型的cookie

图片来源网络

打印出的结果是一个字符串类型,因为cookie本身就是存储在浏览器中的字符串。但这个字符串是有格式的,由键值对 key=value构成,键值对之间由一个分号和一个空格隔开。

cookie的参数

  1. expires 解释cookie在什么时间段内有效
  2. domainpath 限制cookie能被那些网站访问
  3. secure 设置cookie只在确保安全的请求中才会发送(https等安全协议)
  4. httpOnly 设置cookie能否通过js来访问,拥有httpOnly的cookie只能被服务器访问,客户端不能访问,可以用来防止XSS脚本攻击

实例操作cookie

静态服务器的搭建

// 安装依赖
mkdir demo-cookie && cd demo-cookie
npm init -y
npm install --save express 
// 监听本机3000端口
const express = require('express')
const app = express()

app.listen(3000, err => {
  if (err) {
    return console.log(err)
  }
  console.log('---- 打开 http://localhost:3000 吧----')
})

设置cookie

// 我们在根目录上面设置cookie
app.get('/', (req, res) => {
  res.cookie('name','hcc')
  res.send(`<h1>hello world!</h1>`)
})
app.get('/user', (req, res) => {
  res.send('<h1>hello world user!</h1>')
})

可以看到响应头response header中有Set Cookie设置了我们刚刚在服务器中写的对应的cookie,通过浏览器的Application 中的cookie我们可以看到已经存放了我们刚刚写的cookie

cookie一.png

存放cookie.png

设置多个cookie值

app.get('/', (req, res) => {
  res.cookie('name','hcc')
  res.cookie('name','yx')
  res.cookie('age',24)
  res.send(`<h1>hello world!</h1>`)
})
app.get('/user', (req, res) => {
  res.send('<h1>hello world user!</h1>')
})

我们可以看到response header中会出现多个set cookie,来对应我们在服务器中设置的cookie值


多个cookie.png

通过document.cookie获取我们设置的cookie的值,可以看出,重名的cookie会被后一个值覆盖,不同的cookie以分号结尾,中间有一个空格

document.cookie //
"name=yx; age=24"

expires和maxAge、httpOnly

app.get('/', (req, res) => {
  res.cookie('expires','5秒后消失',{
    expires: new Date(Date.now()+5000)
  })
  res.cookie('max-age','timeout',{
    maxAge: 5000
  })
  res.cookie('httpOnly','set',{
    httpOnly:true
  })
  res.cookie('name','yx')
  res.cookie('age',24)
  res.send(`<h1>hello world!</h1>`)
})
app.get('/user', (req, res) => {
  res.send('<h1>hello world user!</h1>')
})

我们分别给不同的cookie设置了时间限制和httpOnly,让我们看看他们在浏览器中的展示


expires和maxAge.png

expiresmaxAge上面已经讲述了,是用来设置cookie的有效时间的,maxAge的使用更加的方便和普遍,因为expires的时间限制是格林威治时间,写起来不方便,maxAge是根据你的当前时间+ 设置的时间(毫秒),更加的方便。

下面分别获取5秒前的cookie和5秒后的cookie

// 5秒前
document.cookie  
"expires=10%E7%A7%92%E5%90%8E%E6%B6%88%E5%A4%B1; max-age=timeout; name=yx; age=24"

// 5秒后
document.cookie  
"name=yx; age=24"

细心的同学已经发现了,我们之前设置了httpOnly=set的cookie值,但是通过document.cookie并没有获取到,我们看看浏览器是否已经存放了,下图展示了,浏览器已经存放了我们设置的httpOnly的cookie,并且后面还有一个勾出现,好像就是通过客户端不可以输出查看。

httpOnly.png

如果服务器在设置cookie的时候,添加了额外的属性httpOnly的话,就是限制了不能通过浏览器获得,这个对于防止攻击很有用。

额外的,当你5秒后刷新浏览器存放的cookie值,我们刚刚设置的时间限制的cookie都会被清除

5秒后查看cookie.png

删除cookie

只需要将对应的name的cookie的时间限制设置为0,就会被浏览器清除

let removeCookie = (name, path, domain) => {
  document.cookie = `${name}=; path=${path}; domain=${domain}; max-age=0`
}

子作用域

首先有一个大的概念,就像继承家产一样,父亲的会给儿子使用,但是儿子的不会给父亲使用。

图片来源网络

当 Cookie 的 domain 为 news.163.com,那么访问 news.163.com 的时候就会带上 Cookie;
当 Cookie 的 domain 为 163.com,那么访问 news.163.comsports.163.com就会带上 Cookie

实例

下面我们设置了一个根域名和一个根域名下面的子路径的请求

app.get('/', (req, res) => {
  res.cookie('httpOnly','set',{
    httpOnly:true
  })
  res.cookie('name','yx')
  res.cookie('age',24)
  res.send(`<h1>hello world!</h1>`)
})
app.get('/user', (req, res) => {
  res.cookie('child','user')
  res.cookie('user','hcc',{
    path: '/user',
    httpOnly: true
  })
  res.send('<h1>hello world user!</h1>')
})

访问根域名下面的cookie存放

根域名.png

访问/user下面的cookie存放


user路径.png

很清晰的发现,我们在/user下面设置的cookie并不会存放在根域名/下,但是我们在/设置的cookie,会存放在/user下面。

CSRF攻击

CSRF(cross-site request forgery),中文名:跨站请求伪造,也被称为:one click attack/session riding(很形象), 缩写为 CSRF/XSRF,就是你点击一个什么按钮,会触发一定的程序攻击。

CSRF有什么危害

CSRF可以理解为,在你不知情的情况下,攻击者盗用你的身份,恶意的像服务器发送请求。

  1. 以你的名义发送垃圾邮箱
  2. 购买商品
  3. 虚拟货币转账

CSRF的原理

CSRF攻击.png

从图中我们可以看出,一个CSRF攻击需要2个条件

  1. 登录了一个受信任的网站A,并且本地存放了cookie
  2. 在不关闭A的情况下,访问了危险网站B

你也可以自己做的一下要求来防止CSRF攻击,但是楼主是做不到的

  1. 你不能保证你登陆了一个网站后,不再打开一个tab 页面并访问另外的网站。(习惯)
  2. .你不能保证你关闭浏览器后,你本地的cookie 马上过期,你上次的会话已经结束 (服务器)

实例

实例一

银行网站A,它以GET请求来完成银行转账的操作,如:http://www.mybank.com/Transfe...

危险网站B,它里面有一段HTML的代码如下:

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

首先,你登录了银行网站A,然后访问危险网站B,噢,这时你会发现你的银行账户少了1000块。。。

为什么会这样呢?

原因是银行网站A违反了HTTP规范,使用GET请求更新资源。在访问危险网站B的之前,你已经登录了银行网站A,而B中的<img>以GET的方式请求第三方资源(这里的第三方就是指A网站了,原本这是一个合法的请求,但这里被不法分子利用了),所以你的浏览器会带上你的银行网站A的Cookie发出GET请求,去获取资源http://www.mybank.com/Transfer.php?toBankId=11&money=1000,结果银行网站服务器收到请求后,认为这是一个更新资源操作(转账操作),所以就立刻进行转账操作......

实例二:

为了杜绝上面的问题,银行决定改用POST请求完成转账操作。但是钓鱼网站也意识到银行应该不会那么傻逼,也与时俱进,钓鱼网站B的WEB表单如下:

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

  <body onload="steal()">
    <iframe name="steal" display="none">
      <form method="POST" name="transfer" 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>

如果用户仍是继续上面的操作,很不幸,结果将会是再次不见1000块......因为这里危险网站B暗地里发送了POST请求到银行!

我们看出来,CSRF攻击是源于WEB的隐式身份验证机制!WEB的身份验证机制(cookie)虽然可以保证一个请求是来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的!

CSRF防御

服务端的CSRF方式方法很多样,但总的思想都是一致的,就是在客户端页面增加伪随机数

  1. 验证 HTTP Referer 字段

  2. 在请求地址中添加 token 并验证


xss攻击

xss(cross site scripting)跨网页脚本攻击,是以前常见的一种攻击方式,主要是通过这几个步骤来实现:

  1. 攻击者通过页面恶意的编写一下脚本语言, 然后发送给服务器
  2. 服务器接收到攻击者发送的请求,但是没有处理。直接保存在数据库中。
  3. 当用户访问同一个网站的时候,由于服务器并没有处理攻击者发送的恶意脚步,所有会把恶意代码和原始代码都发送给用户,这样攻击者的代码就成功的显示在用户的页面上面了。
![](aaa.png)、<a href="javascript:alert('xss');">xss</a>

如果恶意代码写上某一个网站的地址,什么的,恶意付账什么的,想想后果。

防御

请记住一句:不要相信用户的输入。
XSS防御的总体思路是:对输入(和URL参数)进行过滤,对输出进行转义。

参考链接:

CSRF 攻击的应对之道

浅谈�CSRF 攻击方式

聊一聊 cookie

Cookie 在前端中的实践

浅谈xss攻击

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容