HTTP深入浅出之鉴权与安全

Posted by weite122 on 2019-03-13

谈谈Session/cookie机制,如何实现会话跟踪?

https://www.cnblogs.com/andy-zhou/p/5360107.html#_caption_0

Cookie 理解

进公园

背景: 这个公园有一个总公园, 总公园里有许多小公园(总公园是登录页面, 小公园是域名相同的页面)

  1. 第一次进总公园, (第一次请求某个服务器)

    工作人员检查你的入园是否符合条件(后端查看是否是注册以后的用户)

    通过条件的话工作人员会给你一张票(后端会给你一个响应头, 这个响应头的作用是设置一个 cookie )

    票的内容是只有工作人员才知道是否可以入园的字符串

  2. 第二次进总公园(第二次请求相同的域名)

    你要带上这个票进公园(浏览器会在请求头带上cookie)

    工作人员看到这个票, 确认里面的内容正确就给你进去(后端看到这个cookie就会让你直接进入登录后的页面)

Cookie 的实现

  1. 服务器通过 Set-Cookie 头给客户端一串字符串(背)
  2. 客户端每次访问相同域名的网页时,必须带上这段字符串(背)
  3. 客户端要在一段时间内保存这个Cookie(背)
  4. Cookie 默认在用户关闭页面后就失效,后台代码可以任意设置 Cookie 的过期时间
  5. 大小大概在 4kb 以内

Session的理解

进公园

​ 背景: 我是一个坏游客, 我知道什么样的字符串就可以进入公园, 于是我可以伪造假的门票, 工作人员发现了这个问题, 所以工作人员采用更安全的方法来审查门票

  1. 第一次进总公园, (第一次请求某个服务器)

    工作人员检查你的入园是否符合条件(后端查看是否是注册以后的用户)

    通过条件的话工作人员会给你一张票(后端会给你一个响应头, 这个响应头的作用是设置一个 cookie , cookie 的值是一个随机数)

    并且工作人员把票的字符串和你的名字写到一张表里(后端设置一个session, 保存在服务器内存中, session的内容是之前的随机数对应你的用户信息)

    票的内容是只有工作人员才知道是否可以入园的字符串

  2. 第二次进总公园(第二次请求相同的域名)

    你要带上这个票进公园(浏览器会在请求头带上cookie)

    工作人员看到这个票, 通过判断票的字符串是否和表的字符串匹配, 如果匹配,那么说明可以进入(后端拿到请求内容的cookie的随机数, 会和sessions的内容进行比对, 看请求的cookie的随机数有没有在sessions上出现,如果出现了, 就会让你进入登录后的页面)

    比cookie多做两件事情(标了粗体)

    sessions其实就是服务器的一块内存, key:value, 分别是随机数和用户的信息

Session的实现

  1. 将 SessionID(随机数)通过 Cookie 发给客户端

  2. 客户端访问服务器时,服务器读取 SessionID

  3. 服务器有一块内存(哈希表)保存了所有 session

  4. 通过 SessionID 我们可以得到对应用户的隐私信息,如 id、email

  5. 这块内存(哈希表)就是服务器上的所有 session

Web安全中有哪些常见的攻击方式?

XSS

  • 概念

    • XSS(Cross Site Scripting),即跨站脚本攻击,是一种常见于web应用程序中的计算机安全漏洞.XSS通过在用户端注入恶意的可运行脚本,若服务器端对用户输入不进行处理,直接将用户输入输出到浏览器,然后浏览器将会执行用户注入的脚本。
  • 举例

    • 有一个input输入框,需要用户输入名字,用户却输入一个恶意脚本,

    或者用户输入一个HTML,在标签中嵌入恶意脚本,如src,href,css style等。如:<IMG SRC="javascript:alert('XSS');">; <BODY BACKGROUND="javascript:alert('XSS')">

  • 防范

    • 其恶意脚本都是来自用户的输入。因此,可以使用过滤用户输入的方法对恶意脚本进行过滤。

      1. 获取用户输入,不用.innerHTML,用innerText。

      2. 对用户输入进行过滤,如 HTMLEncode 函数实现应该至少进行 & < > " ’ / 等符号转义成 &amp &lt &gt &quot &#x27 &#x2F;

CSRF

  • 概念
    • CSRF (Cross Site Request Forgery)攻击,中文名:跨站请求伪造。其原理是攻击者构造网站后台某个功能接口的请求地址,诱导用户去点击或者用特殊方法让该请求地址自动加载。用户在登录状态下这个请求被服务端接收后会被误以为是用户合法的操作。对于 GET 形式的接口地址可轻易被攻击,对于 POST 形式的接口地址也不是百分百安全,攻击者可诱导用户进入带 Form 表单可用POST方式提交参数的页面。
  • 防范
    1. 服务端在收到路由请求时,生成一个随机数,在渲染请求页面时把随机数埋入页面(一般埋入 form 表单内,
    2. 服务端设置setCookie,把该随机数作为cookie或者session种入用户浏览器
    3. 当用户发送 GET 或者 POST 请求时带上_csrf_token参数(对于 Form 表单直接提交即可,因为会自动把当前表单内所有的 input 提交给后台,包括_csrf_token)
    4. 后台在接受到请求后解析请求的cookie获取_csrf_token的值,然后和用户请求提交的_csrf_token做个比较,如果相等表示请求是合法的。
    5. Token 保存在 Session 中。假如 Token 保存在 Cookie 中,用户浏览器开了很多页面。在一些页面 Token 被使用消耗掉后新的Token 会被重新种入,但那些老的 Tab 页面对应的 HTML 里还是老 Token。这会让用户觉得为啥几分钟前打开的页面不能正常提交?
    6. 尽量少用 GET。假如攻击者在我们的网站上传了一张图片,用户在加载图片的时候实际上是向攻击者的服务器发送了请求,这个请求会带有referer表示当前图片所在的页面的 url。 而如果使用 GET 方式接口的话这个 URL 就形如:
      https://xxxx.com/gift?giftId=aabbcc&_csrf_token=xxxxx
      那相当于攻击者就获取了_csrf_token,短时间内可以使用这个 token 来操作其他 GET 接口。

常见的鉴权方式有哪些?

  1. session/cookie 鉴权
    v2-b4c952a1f71313670b94898b2bea4f6a_r.jpg
    • 缺点:
      • 小程序或其他APP没有cookie,不能用session鉴权
      • session 对象需要存储在服务器内存,如果数据量大内存会溢出
      • session需要建立一个数据库来存储,对于分布式的服务器,有可能会请求到了一台没有数据库的服务器
  2. JWT鉴权
    v2-e25cb900e0f30c5546a69f7a944a8085_r.jpg
    • 优点:
      • 使用范围广
      • 服务器压力小
    • 缺点:
      • 用户注销,token并未注销,依然有效
      • token有效期的需要设置,例如是2小时之内不用重新设置token,2小时到一天需要重新设置token,一天以上需要重新登录
  1. Auth2鉴权
    v2-e6660bb06127e350201f0875d5963f4b_r.jpg