JS 安全策略 101

news2025/1/20 10:52:21

依赖审计

依赖审计其实就是利用 npm 或是 yarn 自带的一个 audit 命令检测 node_module 里存在的一些具有安全隐患的依赖项。我习惯用yarn audit, 所以给大家放了张自己博客的 yarn 审计结果。这里显示:一个叫 trim 的包太老了,有很高的安全风险。

有风险的依赖应该尽快解决。有些开发人员会因为“客户环境一年才更新一次,所以不心急”这种 naive 的理由忽视安全审计,这是违背开发常识的行为——依赖问题一旦堆积将很难修复。

跳回正题,生产环境中我们不大可能频繁使用手工 audit 的方式,通常的做法是:在 CI 中加入yarn audit 这一步;如果识别到漏洞,立马告警——发消息到工作群里,并更新相关依赖项。

如果大家使用 github 开发的话,它提供了一个叫 Dependabot 的机器人,:该机器人会帮你自动检测依赖并报告风险;一定设置后,它还能自动提交 PR 修复相关漏洞。

启动次要版本和补丁更新

上文提到依靠 CI 来提醒我们更新依赖,这相对来说比较被动;很多三方库会频繁地通过升级次要版本或是打补丁的形式来快速修复一些安全隐患,yarn audit 很难及时追踪这类安全报告;我们最好在开发的阶段就主动跟进这类修复,及早规避一些没必要的风险。上面说得有玄乎了,实操上就是经常 yarn upgrade 一下。

这里科普一个小知识,依赖的版本规则:

状态开发阶段规则示例
首次发布新产品从 1.0.0 开始1.0.0
向后兼容的错误修复补丁发布增加第三位数字1.0.1
向后兼容的新功能次要版本增加中间数字并将最后一位置零1.1.0
不须要具备向后兼容性的更改主要版本增加第一位数字并将后两位置零2.0.0

上表可知,主版本更新影响向后兼容,兹事体大,所以通常的升级策略是:只开启次要版本或是补丁更新,这样 yarn upgrade 时不会触碰到兼容问题。那如何指定依赖项的更新类型呢?在 package.json 依赖项的版本前加 ^ 或是 ~ 号就行了。例如,我们指定 1.0.4 版本可升级范围:

  • 只升级补丁版本:1.01.0.x~1.0.4
  • 升级次要及补丁版本:11.x^1.0.4
  • 主版本可升级:*x

例子:

"dependencies": {"my_dep": "^1.0.4","another_dep": "~2.2.0"
}, 

Integrity & nonce 检测

关于 Integrity, 我在《一文搞懂 script 标签》提到过,就是利用一个 hash 值来校验加载的 JS 文件是否完整。如下标签中, integrity 作用就是告诉浏览器:在加载引 react.production.min.js 时,使用 sha256 算法计算该文件的摘要签名;之后将该签名与预设的 integrity 值作比较,如果不一致就不执行该资源。它的主要功能就是防止托管在 CDN 上的资源被篡改。

<scriptsrc="https://unpkg.com/react@17/umd/react.production.min.js"integrity="sha384-7Er69WnAl0+tY5MWEvnQzWHeDFjgHSnlQfDDeWUvv8qlRXtzaF/pNo18Q2aoZNiO"crossorigin="anonymous"
></script> 

同理,nonce 也是一个预设的值,与 http 头里的 CSP 做校验,防止那些被串改过的 script 标签执行脚本。

<script nonce="nonce-EfNBf03nceIOAn39fn389h3sdfa" src="./hello.js"></script> 

Trusted Types

上面提到了 nonce 与 CSP;不得不说,CSP 是每一个前端开发必须熟知的知识点,我之前也写过 101 文章——《Content Security Policy 101》,大家有兴趣的话可以看一看。这里再补充一个现在主流浏览器都支持的新特性——Trusted Types。它事实上就是一条 CSP 规则:

Content-Security-Policy: require-trusted-types-for 'script' 

主要功能是限制使用一些有风险的手段操作 Web API。比如,开启 Trusted Types 后,直接修改 html 的方式就会抛出异常:

el.innerHTML = "<img src=x onerror=alert(1)>"; // This throws an exception. 

而所谓受信任的操作手段就是:只允许浏览器厂商提供的 trustedTypes 相关的 API 来操作 Web 页面。如下案例中,通过使用 trustedTypes,让开发人员有意识地把 inner html 中的 tag 标签——<>——替换为特殊符号(&lt&gt)以防止 XSS 注入。

const policy = trustedTypes.createPolicy("escapePolicy", {createHTML: (str) => {return str.replace(/\</g, "&lt;").replace(/>/g, "&gt;");},
});

// accepted operation
const escaped = policy.createHTML("<img src=x onerror=alert(1)>");
el.innerHTML = escaped; // '&lt;img src=x onerror=alert(1)&gt;' 

启用 strict 模式

我们再看 JS 本身的安全策略。现代 JS 开发基本都会强制开启严格模式——use strict。一则是 JS 有些语法设计得过于粗糙,不适合生产使用;二则严格模式下一些不安全的操作方法会在运行阶段抛出异常,比如:

  • 修改 global 对象
  • this 指向全局
  • 使用 eval 这种存在注入危险的方法
  • 使用转义字符
  • 变量重名或删除变量

压缩和混淆

除此之外,前端页面还不可避免地会暴露 JS 文件,有些黑客会试图通过了解你的代码去发起攻击(虽然很多垃圾代码我们自己都看不懂);因此使代码难以阅读可以有效地减少这类风险。通常的做法就是使用 webpack 这类构件工具压缩以及混淆源代码;压缩后的代码还能带来额外的好处——提升加载速度。当然,某些特别敏感的源代码最好还是使用后端渲染的技术,以避免直接暴露给客户端。

lint 代码

常见的 lint 工具都提供了静态分析的功能;除了提供统一格式、提高代码质量这种基础功能外,它还能提醒开发人员一些易犯的错误。从某种意义上来说也能减少一些安全风险(个人觉得垃圾代码才是最大的风险)。开发阶段最常用的就是 eslint 了;到了 CI 阶段,还会用到 SonarCloud 这种工具,它绘制出一个报表,显示代码“臭味”以及一些可能的安全漏洞。

小结

本文列举了几个前端开发中最最常见的网络安全措施。这些手段都比较基础,但是最基础的往往也是最有效的;毕竟这些措施经过多年验证,确实能防范绝大多数的安全漏洞。作为 101 文章,事实上也够了。当然,更深层次的“网络安全”技术就变成了一个非常专业的领域问题;知识点与我们通常的“网络开发”大相径庭;本文就不具体展开了,有兴趣的朋友可以自己深入了解一下,这也是一份非常抢手的工作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/152111.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构初阶】5. 栈和队列

栈 1.1 栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。**进行数据插入和删除操作的一端 称为栈顶&#xff0c;另一端称为栈底。**栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则…

win7安装onenote2016时碰到30094-1011(0)的 问题

安装办法用途【1】中所有的更新【1】中下载IE11的依赖IE11360软件管家解决OneNote的登录界面不显示问题微软常用运行库360软件管家kernalbase.dll等文件的缺失windowsupdateagent-7.6-x64官网下载Windows6.1-KB4474419-v3-ia64.msu控制面板的update中选择安装支持sha-2校验【3】…

【算法】差分数组

目录1.概述2.代码实现3.应用本文参考&#xff1a; LABULADONG 的算法网站 1.概述 &#xff08;1&#xff09;差分数组的思想与前缀和算法的非常近似&#xff08;有关前置和算法的具体细节可以参考前缀和算法这篇文章&#xff09;&#xff0c;其主要适用于频繁地对原始数组的某…

国产单通道直流有刷马达驱动芯片型号推荐

直流有刷马达驱动芯片是一款适应消费类、工业类的单通道直流有刷驱动IC&#xff0c;适用于各类玩具&#xff0c;智能家居&#xff0c;智能三表。小封装&#xff0c;低功耗&#xff0c;内置完善的保护机制&#xff08;过温/过流/过压&#xff09;。具有一个PWM&#xff08;INA/I…

写了2年文章的我,昨天第一次露脸直播。

作为一名不知名的技术博主&#xff0c;上周六晚上在视频号第一次做露脸直播。 勇敢的迈出视频号开播的第一步&#xff0c;并且数据不错&#xff0c;这个感觉很爽&#xff0c;和写作输出完全是两回事。 写这篇文章的目的是鼓励技术博主们&#xff0c;也尝试一下直播和做视频。 …

ClickHouse 挺快,esProc SPL 更快

开源分析数据库ClickHouse以快著称&#xff0c;真的如此吗&#xff1f;我们通过对比测试来验证一下。 ClickHouse vs Oracle 先用ClickHouse&#xff08;简称CH&#xff09;、Oracle数据库&#xff08;简称ORA&#xff09;一起在相同的软硬件环境下做对比测试。测试基准使用国…

基于ESP8266和SU-03T的离线语音红外遥控器设计

一. 系统设计及框图 之前设计了基于ESP32模块的智能红外遥控器&#xff0c;具体功能见以下CSDN链接&#xff1a; 智能红外遥控器&#xff08;一&#xff09;&#xff1a;功能简介_远望创客学堂的博客-CSDN博客 上面这款智能红外遥控器可以实现红外的远程控制&#xff0c;也可…

【从零开始学习深度学习】44. 图像增广的几种常用方式并使用图像增广训练模型【Pytorch】

大规模数据集是成功应用深度神经网络的前提&#xff0c;图像增广&#xff08;image augmentation&#xff09;技术通过对训练图像做一系列随机改变&#xff0c;来产生相似但又不同的训练样本&#xff0c;从而扩大训练数据集的规模。图像增广的另一种解释是&#xff0c;随机改变…

PCB入门学习—PCB封装的创建2

3.2 IC类PCB封装的创建注&#xff1a;PCB封装的名字一定要和原理图上填写的封装名字一样&#xff0c;不然对不上。规格书里有最大值最小值&#xff0c;就按最大值来做。快捷键EA是特殊粘贴。SOP-8:焊盘比较多时(BGA)可以利用向导去创建。做封装从规格书需要读取的数据&#xff…

19-FreeRTOS 任务通知API

1-xTaskNotifyGive / xTaskNotifyGiveIndexed task.hBaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );BaseType_t xTaskNotifyGiveIndexed( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify );每个任务都有一组“任务通知” &#xff08;或仅“通知” &a…

Tomcat Connector运行模式

目录 1 Tomcat Connector运行模式 1.1 BIO 模式 1.2 NIO 模式 1.3 APR模式 2 修改Tomcat Connector运行模式为apr 或者解决问题The APR not found 问题 2.1 linux系统 2.2 windows处理 1 Tomcat Connector运行模式 1.1 BIO 模式 BIO模式&#xff08;blocking I/O&am…

[C语言]运用函数指针数组构建一个简单计算器

1.函数指针数组 函数指针数组&#xff0c;即为存放函数首地址的数组&#xff0c;类型为函数指针类型。 2.运用函数指针数组构建简单计算器 1.人机交互&#xff0c;首先要用选择加减或乘除的菜单&#xff0c;再分别写出其功能 void menu() {printf("****************…

嵌入式实时操作系统的设计与开发(五)

线程退出 当线程代码执行完后&#xff0c;系统会隐式地调用acoral_thread_exit()函数进行线程退出相关的操作。 acoral_thread_exit()本质上是要执行acoral_kill_thread()。 void acoral_thread_exit(){acoral_kill_thread(acoral_cur_thread); }void acoral_kill_thread(aco…

ccbill 代码分析

ccbill目录概述需求&#xff1a;设计思路实现思路分析1.BillState2.DBList3.DBListAttr4.DBListDBSrc5.DBListDBSrcsDBListsSurvive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better result,wai…

每日一题:Leetcode59. 螺旋矩阵 II

文章目录 系列&#xff1a;数组专练 语言&#xff1a;java & go 题目来源&#xff1a;Leetcode59. 螺旋矩阵 II 难度&#xff1a;中等 考点&#xff1a;边界问题的处理 & 圈数处理 思路和参考答案文章目录题目描述思路java解法&#xff1a;java参考代码go参考代码&…

OceanBase 4.0解读:从TPC-H性能测评看4.0与3.x差异

关于作者 肖帆 OceanBase技术专家 OceanBase技术专家&#xff0c;开源生态团队成员。毕业于华中科技大学软件工程专业&#xff0c;从事数据库领域的质量保障工作&#xff0c;曾就职于有赞、网易&#xff0c;参与关系型数据库、缓存数据库、对象存储相关产品的测试开发&#x…

.net core api调用webserver接口(详细)

这里废话不多说&#xff0c;我就不简述什么事webserver了&#xff0c;相信点进本博客的大佬都是为了解决问题。 .net core 调用webserver的话还挺简单。首先我们先有个.net core api的项目。 1.我们先注入这个HttpClient 这个内置对象&#xff0c;一会要用到。 // 注入HttpC…

Vue Hook Event 解读

前言 Hook Event (钩子事件)相信很多 Vue 开发者都没有使用过&#xff0c;甚至没听过&#xff0c;毕竟 Vue 官方文档中也没有提及。 Vue 提供了一些生命周期钩子函数&#xff0c;供开发者在特定的逻辑点添加额外的处理逻辑&#xff0c;比如: 在组件挂载阶段提供了beforeMount 和…

代码随想录day34

1005. K 次取反后最大化的数组和 题目 给你一个整数数组 nums 和一个整数 k &#xff0c;按以下方法修改该数组&#xff1a; 选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。 重复这个过程恰好 k 次。可以多次选择同一个下标 i 。 以这种方式修改数组后&#xff0c;返回数…

linux笔记(9):MangoPi-MQ(芒果派麻雀D1s)Tina系统编译烧录

文章目录1.下载相关资料1.1 WhyCan Forum(哇酷开发者社区)提供的sdk1.1.1 SDK解压过程1.2 WhyCan Forum(哇酷开发者社区)提供的补丁1.2.1 补丁包含的文件1.2.2 补丁文件和D1下面的相同文件进行合并1.2.3 引脚PD17被复用&#xff0c;导致LCD变暗&#xff0c;修改设备树2. 编译ti…