前端安全问题汇总

1、Nginx相关

1.1、升级Nginx版本

及时升级Nginx版本,新版本包含对旧版本的漏洞修复

1.2、版本号隐藏

版本号的显示也被扫描软件识为一种不安全的行为

2、具有不安全、不正确或缺少SameSite属性的Cookie

可以直接在Nginx下设置

location / {
    add_header Set-Cookie "Path=/; HttpOnly; SameSite=Strict";
}

3、加密会话(SSL)Cookie中缺少Secure属性

可以直接在Nginx下设置

location / {
    add_header Set-Cookie "Path=/; HttpOnly; SameSite=Strict; Secure";
}

4、跨站点脚本攻击

4.1、反射型

所谓反射,是指此种类型的注入脚本必须被包含在发往Web服务器的请求中,然后Web服务器以某种方式反射到用户浏览器执行。

一个简单例子

https://example.com/index.php?user=<script>恶意代码</script>

上述代码被攻击者加了恶意代码,当用户请求上述代码,服务器没有对用户输入进行充分的验证或转义,服务器可能会直接将这些代码插入到返回的HTML中

处理方式
  • 通过网关对输入进行转义;
  • 保证正确的响应Content-type;

对安全扫描软件来说,要保证过程和结果都不能有问题。即使携带恶意脚本的响应没有实际在页面被解析执行,但是如果接口响应Content-type此刻为html,这就满足了脚本可执行的基本条件,对于扫描软件来说,这就是有问题的case

4.2、存储型

注入的脚本永久存储在Web服务器上,如数据库、内存或文件系统中。只要注入脚本代码没有被清理,每次用户访问网页时都将加载恶意脚本。

这个最常见的就是富文本编辑器,富文本编辑器内携带了html元素,如果处理不当,很容易被攻击利用。当然解决方法比较简单,对于前端侧,可以直接利用类似sanitize-html这种内容处理库进行处理

5、“Content-Security-Policy”头中缺少“Script-Src”或“Default-src”策略或相应策略不安

此问题同“Content-Security-Policy”头缺失 一并处理。这个问题的处理要繁琐的多,先引用几个基本概念

内容安全策略

内容安全策略 (CSP) 对于保护应用程序免受各种安全威胁(例如跨站点脚本 (XSS)、点击劫持和其他代码注入攻击)至关重要。
通过使用 CSP,开发者可以指定哪些来源是允许的,例如内容来源、脚本、样式表、图片、字体、对象、媒体(音频、视频)、iframe 等等。

Nonce

一个 Nonce 是一个为一次性使用而创建的唯一随机字符串。它与 CSP 结合使用,可以选择性地允许某些内联脚本或样式执行,绕过严格的 CSP 指令。本修改主要涉及到Nonce的生成和配置。简单来说,Nonce为应用的各种资源生成了随机值,他们被加到脚本样式表的标签上,当值与响应头的Content-Security-Policy下配置的Nonce匹配的时候,浏览器才可加载此资源,否则阻止加载

使用Nonce可以以较为严格的方式解决此问题,算是推荐的做法

对于前端来说,Nonce的生成需要借助各种打包工具

打包工具Nonce生成Plugin
Webpackcsp-html-webpack-plugin
Vitevite-plugin-csp

下面以Webpack举例来详述配置步骤,Vite同理

安装依赖
配置Webpack
...
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CspHtmlWebpackPlugin = require('csp-html-webpack-plugin')
...
const crypto = require('crypto')
const emotionalNonce = crypto.randomBytes(16).toString('base64')
const emotionalNonce1 = crypto.randomBytes(16).toString('base64')
const emotionalNonce3 = crypto.randomBytes(16).toString('base64')

const webpackConfig = merge(baseWebpackConfig, {
  plugins: [
    new HtmlWebpackPlugin(),
    new CspHtmlWebpackPlugin(
      {
        'base-uri': "'self'",
        'object-src': "'none'",
        'script-src': ["'self'", `'nonce-${emotionalNonce1}'`],
        'style-src': ["'self'", `'nonce-${emotionalNonce}'`, `'nonce-${emotionalNonce3}'`]
      },
      {
        enabled: true,
        hashingMethod: 'sha256',
        hashEnabled: {
          'script-src': true,
          'style-src': true,
          'default-src': true
        },
        nonceEnabled: {
          'script-src': true,
          'style-src': true,
          'default-src': true
        }
      }
    )
  ],
})

module.exports = webpackConfig
生产打包

配置完毕,开始打包。如果过程顺利,你会发现,页面的js脚本的引入,会增加一串nonce值。同时,HTML meta标签下也新增了Content-Security-Policy 头:

<meta http-equiv="Content-Security-Policy" content="base-uri 'self'; object-src 'none'; script-src http://192.168.1.1:8080  'nonce-xxxxxxxxxxxxxxxxxxxxxxx==' 'sha256-xxxxxxxxxx=' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx'; style-src http://192.168.1.1:8080 'nonce-xxxxxxxxxxxxxxxxxxxxxxx==' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx==' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx==' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx==' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx==' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx=='">

这里单独解释下,按理来说,插件已经为我们设置了http-equiv,也就是浏览器在解析时,会把这部分视为头部进行对待

当浏览器加载包含 http-equiv 属性的 标签的 HTML 页面时,它会在解析该页面时读取 标签的内容,并将这些内容视为相应的 HTTP 头部

但对于安全检查软件来说,这是远远不够的,它把响应头Content-Security-Policy视为检查的一个case,因此,必须要设置Nginx,这也是这个安全问题的繁琐所在。

配置Nginx

index.html下生成的nonce取出,设置于Content-Security-Policy

location / {
    add_header Content-Security-Policy "Frame-ancestors 'none'; img-src 'self' data:;base-uri 'self'; object-src 'none'; default-src http://192.168.1.1:8080; script-src http://192.168.1.1:8080  'nonce-xxxxxxxxxxxxxxxxxxxxxxx==' 'sha256-xxxxxxxxxx=' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx'; style-src http://192.168.1.1:8080 'nonce-xxxxxxxxxxxxxxxxxxxxxxx==' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx==' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx==' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx==' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx==' 'nonce-xxxxxxxxxxxxxxxxxxxxxxx==';font-src http://192.168.1.1:8080 data:";
}
页面检查

初次配置完毕后,还有有很大概率页面无法访问或者安全检查不通过,有如下几个原因

  • Nginx在复制页面的Nonce导致两处不匹配;
  • 缺少其他的属性配置,如font-src 等;
参考

什么是跨站脚本攻击(XSS)

Next.js

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值