• XSS 和 CSRF



    1. XSS

    涉及面试题:什么是 XSS 攻击?如何防范 XSS 攻击?什么是 CSP

    • XSS 简单点来说,就是攻击者想尽一切办法将可以执行的代码注入到网页中。
    • XSS 可以分为多种类型,但是总体上我认为分为两类:持久型和非持久型。
    • 持久型也就是攻击的代码被服务端写入进数据库中,这种攻击危害性很大,因为如果网站访问量很大的话,就会导致大量正常访问页面的用户都受到攻击。

    举个例子,对于评论功能来说,就得防范持久型 XSS 攻击,因为我可以在评论中输入以下内容

    image.png

    • 这种情况如果前后端没有做好防御的话,这段评论就会被存储到数据库中,这样每个打开该页面的用户都会被攻击到。
    • 非持久型相比于前者危害就小的多了,一般通过修改 URL 参数的方式加入攻击代码,诱导用户访问链接从而进行攻击。

    举个例子,如果页面需要从 URL 中获取某些参数作为内容的话,不经过过滤就会导致攻击代码被执行

    
    <div>{{name}}div>                                                  
    
    • 1
    • 2

    但是对于这种攻击方式来说,如果用户使用 Chrome 这类浏览器的话,浏览器就能自动帮助用户防御攻击。但是我们不能因此就不防御此类攻击了,因为我不能确保用户都使用了该类浏览器。

    对于 XSS 攻击来说,通常有两种方式可以用来防御。

    1. 转义字符

    首先,对于用户的输入应该是永远不信任的。最普遍的做法就是转义输入输出的内容,对于引号、尖括号、斜杠进行转义

    function escape(str) {
      str = str.replace(/&/g, '&')
      str = str.replace(/</g, '<')
      str = str.replace(/>/g, '>')
      str = str.replace(/"/g, '&quto;')
      str = str.replace(/'/g, ''')
      str = str.replace(/`/g, '`')
      str = str.replace(/\//g, '/')
      return str
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    通过转义可以将攻击代码 变成

    // -> <script>alert(1)</script>
    escape('')
    
    • 1
    • 2

    但是对于显示富文本来说,显然不能通过上面的办法来转义所有字符,因为这样会把需要的格式也过滤掉。对于这种情况,通常采用白名单过滤的办法,当然也可以通过黑名单过滤,但是考虑到需要过滤的标签和标签属性实在太多,更加推荐使用白名单的方式

    const xss = require('xss')
    let html = xss('

    XSS Demo

    '
    ) // ->

    XSS Demo

    <script>alert("xss");</script>
    console.log(html)
    • 1
    • 2
    • 3
    • 4

    以上示例使用了 js-xss 来实现,可以看到在输出中保留了 h1 标签且过滤了 script标签

    1. CSP

    CSP 本质上就是建立白名单,开发者明确告诉浏览器哪些外部资源可以加载和执行。我们只需要配置规则,如何拦截是由浏览器自己实现的。我们可以通过这种方式来尽量减少 XSS 攻击。

    通常可以通过两种方式来开启 CSP

    • 设置 HTTP Header 中的 Content-Security-Policy
    • 设置 meta 标签的方式

    这里以设置 HTTP Header 来举例

    只允许加载本站资源

    Content-Security-Policy: default-src ‘self’
    
    • 1

    只允许加载 HTTPS 协议图片

    Content-Security-Policy: img-src https://*
    
    • 1

    允许加载任何来源框架

    Content-Security-Policy: child-src 'none'
    
    • 1

    当然可以设置的属性远不止这些,你可以通过查阅 文档 (opens new window) 的方式来学习,这里就不过多赘述其他的属性了。

    对于这种方式来说,只要开发者配置了正确的规则,那么即使网站存在漏洞,攻击者也不能执行它的攻击代码,并且 CSP 的兼容性也不错。

    2 CSRF

    跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法

    CSRF 就是利用用户的登录态发起恶意请求

    如何攻击

    假设网站中有一个通过 Get 请求提交用户评论的接口,那么攻击者就可以在钓鱼网站中加入一个图片,图片的地址就是评论接口

    <img src="http://www.domain.com/xxx?comment='attack'"/>
    
    • 1

    res.setHeader('Set-Cookie', `username=poetry2;sameSite = strict;path=/;httpOnly;expires=${getCookirExpires()}`)
    
    • 1

    在B网站,危险网站向A网站发起请求

    DOCTYPE html>
    <html>
      <body>
      
        <img src="http://localhost:8000/api/user/login" />
      body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    会带上A网站的cookie

    // 在A网站下发cookie的时候,加上sameSite=strict,这样B网站在发送A网站请求,不会自动带上A网站的cookie,保证了安全
    
    
    // NAME=VALUE    赋予Cookie的名称及对应值
    // expires=DATE  Cookie 的有效期
    // path=PATH     赋予Cookie的名称及对应值
    // domain=域名   作为 Cookie 适用对象的域名 (若不指定则默认为创建 Cookie 的服务器的域名) (一般不指定)
    // Secure        仅在 HTTPS 安全通信时才会发送 Cookie
    // HttpOnly      加以限制,使 Cookie 不能被 JavaScript 脚本访问
    // SameSite      Lax|Strict|None  它允许您声明该Cookie是否仅限于第一方或者同一站点上下文
    
    res.setHeader('Set-Cookie', `username=poetry;sameSite=strict;path=/;httpOnly;expires=${getCookirExpires()}`)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    如何防御

    • Get 请求不对数据进行修改
    • 不让第三方网站访问到用户 Cookie
    • 阻止第三方网站请求接口
    • 请求时附带验证信息,比如验证码或者 token
    • SameSite Cookies: 只能当前域名的网站发出的http请求,携带这个Cookie。当然,由于这是新的cookie属性,在兼容性上肯定会有问题

    CSRF攻击,仅仅是利用了http携带cookie的特性进行攻击的,但是攻击站点还是无法得到被攻击站点的cookie。这个和XSS不同,XSS是直接通过拿到Cookie等信息进行攻击的

    在CSRF攻击中,就Cookie相关的特性:

    • http请求,会自动携带Cookie。
    • 携带的cookie,还是http请求所在域名的cookie。

    3 密码安全

    加盐

    对于密码存储来说,必然是不能明文存储在数据库中的,否则一旦数据库泄露,会对用户造成很大的损失。并且不建议只对密码单纯通过加密算法加密,因为存在彩虹表的关系

    • 通常需要对密码加盐,然后进行几次不同加密算法的加密
    // 加盐也就是给原密码添加字符串,增加原密码长度
    sha256(sha1(md5(salt + password + salt)))
    
    • 1
    • 2

    但是加盐并不能阻止别人盗取账号,只能确保即使数据库泄露,也不会暴露用户的真实密码。一旦攻击者得到了用户的账号,可以通过暴力破解的方式破解密码。对于这种情况,通常使用验证码增加延时或者限制尝试次数的方式。并且一旦用户输入了错误的密码,也不能直接提示用户输错密码,而应该提示账号或密码错误

    前端加密

    虽然前端加密对于安全防护来说意义不大,但是在遇到中间人攻击的情况下,可以避免明文密码被第三方获取

    4. 总结

    • XSS:跨站脚本攻击,是一种网站应用程序的安全漏洞攻击,是代码注入的一种。常见方式是将恶意代码注入合法代码里隐藏起来,再诱发恶意代码,从而进行各种各样的非法活动

    防范:记住一点 “所有用户输入都是不可信的”,所以得做输入过滤和转义

    • CSRF:跨站请求伪造,也称 XSRF,是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。与 XSS 相比,XSS利用的是用户对指定网站的信任,CSRF利用的是网站对用户网页浏览器的信任。

    防范:用户操作验证(验证码),额外验证机制(token使用)等

  • 相关阅读:
    一个关于 i++ 和 ++i 的面试题打趴了所有人
    mac 上配置 git send-email
    操作系统-进程与线程(互斥锁,信号量,信号量实现进程同步与互斥)
    HashMap
    jsp旅行社管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
    Centos 源码编译 tigervnc
    通过Dapr实现一个简单的基于.net的微服务电商系统(二十)——Saga框架实现思路分享
    Linux内核完全注释(基于Linux0.11)_笔记_Linux0.11执行流程
    L2TP客户端之Strongswan移植(一)
    Python 数据结构与算法
  • 原文地址:https://blog.csdn.net/php_martin/article/details/125869573