MLuminary/Blog

前端安全

Opened this issue · 6 comments

引言

最近一直在准备面试,被问到了解 XSS 时答出不了解还是很惭愧的,作为前端开发人员,安全这方面是必须要非常重视的,因此决定拿出了一段时间来重点了解一下关于前端的安全问题,在这里以 XSS 和 CSRF 为主

XSS

XSS「Cross-site script」因为与 CSS 简写重合所以改为 XSS

其原理是向网站中插入恶意的 HTML 代码。当其他用户浏览该网站的时候,该段 HTML 代码会自动执行,从而达到攻击的目的。如盗取用户的 Cookie,页面重定向,破坏页面结构

举个栗子🌰

网站的评论系统没有过滤 XSS 攻击,当有用户添加评论为

<script>
  while(true) {
    alert("1");
  }
</script>

这段代码就会插入到此网站的 DOM 结构中,因为没有过滤掉或进行处理,此段代码也会执行。

XSS 分类

XSS 分为两种类型:「持久型 XSS」 和 「非持久型 XSS」

持久型 XSS「存储型」

持久型 XSS 就是对客户端攻击的脚本直接植入到服务器上,从而导致每个用户访问此网站都会遭到 XSS 的攻击

非持久型 XSS「反射型」

非持久型 XSS 是对一个页面的某个参数做文章,把精心构造好的恶意脚本包装在 URL 参数中,再讲 URL 发布到网上,骗取用户访问

手段主要有

  • HTML 节点内容的注入 例如 添加评论
  • HTML 属性 例如 通过 url 传值动态修改 imgsrc
  • javascript 代码 例如 传递的变量添加双引号并在双引号后面添加要注入的脚本

防御 XSS

对于非持久型 XSS

  • 现代浏览器都对 xss 有了一定的防范作用,但也仅限于 html 节点和属性的注入。
  • Web 页面渲染的所有内容和数据必须来自于服务器
  • 尽量不使用 eval, new Function(),window.setTimeout(),innerHTML等可执行字符串的方法
  • 前端渲染的时候要对任何字段都需要做转义
  • 对于用户输入的要添加限制,比如用户名和密码只允许字符和数字,email 必须为 email 格式
  • 对于富文本采用过滤,可以通过国人写的 xss

对于持久型 XSS

  • 后端在入库的时候不相信任何前端的数据,将所有的字段统一进行转义处理
  • 后端在传递给前端数据的时候统一做转义处理
  • 前端不相信后端传来的数据,任何字段也都需要做转义处理

举个栗子🌰

先看一下后台的代码「node.js」

app.get('/api/xss', function(req, res) {
  res.setHeader('X-XSS-Protection', 0); //关闭浏览器 XSS

  res.json('hutchins <script>console.log(1)</script>'); //模拟XSS攻击,后台返回了带脚本的字符串
});

前台代码

$.ajax({
  type:'get',
  url:"http://localhost:3003/api/xss",
  dataType:'json',
  success:function(data){
    $('#uname').html(data); //这样在前台就会插入 script 标签
  }
})

这样便会在前台插入脚本代码并在控制台打印 1,那么对于此类代码就需要将其转义,让其无法运行,在 success 方法中改为如下代码

//进行HTML转义后便会插入正常的内容
var str = data;
str = str.replace(/</g,'&lt')
str = str.replace(/>/g,'&gt')
$('#uname').html(str);

//但其实这样也可以完美插入
$('#uname').text(data); 

CSRF

CSRF 「Cross-site request forgery」中文名称为跨站请求伪造

攻击者盗用了你的登录信息,以你的身份模拟发送各种请求。

完成 CSRF 攻击有三个条件

  • 用户已经登录了站点 A,并且在本地保留了 cookie
  • 在用户没有登出站点的情况下也就是 cookie 还在生效的情况下访问了攻击者提供的危险站点 B
  • 站点 A 没有任何 CSRF 防御

CSRF 手段

拿发表评论为例,就是用户登录后编写评论点击发表这种操作,如果发表评论是 get 请求

那 CSRF 攻击者可以通过在自制的 B 危险网站上面写一个 a 标签,然后由 a 标签模拟你点击评论发起的 get 请求,当你点击时,就会在 A 网站添加一个评论,这也是为什么 CSRF 叫 「one click attack 一点就爆炸」,当然也可以直接写一个图片在你不知情时发送 get 请求

那你此刻会想,那把添加评论改成 post 请求应该就安全了吧

改成 post 请求,攻击者可以在 B 网站用 js 动态生成表单,然后发送 post 请求,更高级点可以再生成一个隐藏的 iframe 让表单 target 指向其 name,让你在完全没有察觉的情况下以你的名义干一些羞羞的事情

CSRF 防御

从 cookie 方面下手

  • 禁止止第三方网站使用 cookie,使用 sameSite:Strict 目前仅有 chrome 支持

从绕过前端页面下手

  • 在前端页面加入验证信息,可以使用 ccap
  • 加入 token,token 在前端页面 cookie 和 后端必须保持一致,如果是 ajax 请求的话可以在前端页面 meta 处添加一个 token 属性,然后用 js 动态获取

referer 为 B 网站

验证 referer /^域名/,这里注意一下,如果你是用本地文件测试的话,file 协议是没有 referer 的

学到了老哥!

@AbrahamJay 一起学习,共同进步 😂

还记得我吗?天赐0_o

@AbrahamJay 哇你去哪工作了啊

你看我主页有个组织 就是他家了

@AbrahamJay 你还用之前的那个微信吗