Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

前端安全 #5

Open
MLuminary opened this issue May 8, 2018 · 6 comments
Open

前端安全 #5

MLuminary opened this issue May 8, 2018 · 6 comments
Labels

Comments

@MLuminary
Copy link
Owner

MLuminary commented May 8, 2018

引言

最近一直在准备面试,被问到了解 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
Copy link

学到了老哥!

@MLuminary
Copy link
Owner Author

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

@AbrahamJay
Copy link

还记得我吗?天赐0_o

@MLuminary
Copy link
Owner Author

@AbrahamJay 哇你去哪工作了啊

@AbrahamJay
Copy link

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

@MLuminary
Copy link
Owner Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants