【nodejs高可用】Nodejs应用安全防范的问题总结

概述

事实上,许多运维团队和后端团队的视角里,对Nodejs的开发可以总结为两个字"玩具",为什么这么说,很多传统的后端开发,认为Nodejs不够稳定,安全性不够,容易受到外部攻击,导致服务崩溃挂掉。

但是对于前端开发来说,NodeJs无疑是进军服务端领域的不二选择,笔主曾经也是从服务端转来的前端开发。

本文会针对NodeJs应用里常见的安全风险和防范方案,应对大流量,以及应用内系统异常处理的最佳实践,可以放心的使用Nodejs承载业务。

实际上,语言,api,中间件都只是工具而已,能够在对应的场景下,高效率的解决问题,他就是好东西,毕竟,并不是每个公司,都真的有那么大的体量,每个公司都不一定需要那么复杂的高并发架构啥的,所有讨论这些的前提,都是CURD做起来的基础上,再去往上完善的。

近些年来,由于nodejs使用的人越来越多了,安全问题频发,大多数开发,对于安全红线这块的意识都不够好。开发的过程中,往往会留下一些风险。

但是你要是知道了人家会怎么攻击的,你就知道怎么防御了,所有的安全风险,都和自己的代码,设计,实现这种有关,和语言无关,或者说,安全风险,存在各种语言当中。

目前依旧有无数的问题或者漏洞没有被公开,但是问题不大。。。。目前都是可控的,问题不大。

希望大家牢记下面三点。

(1)NodeJs属于新兴技术,安全问题更明显,更要注意。

(2)很多在传统web网站经历的问题,可能也会在Nodejs里出现。

(3)一般Nodejs出问题,都不是小事情,一定要引起重视。

应用安全风险:CSRF/XSS

这是nodejs里,危害最大的一个风险。

CSRF:跨站请求伪造,用户不知情的情况下执行了攻击者伪造的请求。

CSRF出现的位置和危害

(1)刷新购物车,刷新收藏夹,刷关注等。

(2)发送垃圾购买信息,回帖子。

(3)非本人转账,付款。

(4)非本人修改密码/找回密码。

(5)对外暴露的,带有身份认证的借口,都有CSRF的风险。

XSS:跨站脚本攻击。

(1)发帖子,发文章等。

(2)添加商品/预览商品等。

(3)低代码平台自定义的程序。(手写一些非常危险的代码放到低代码平台)

危害的详细介绍:zhuanlan.zhihu.com/p/796337127...

XSS与Nodejs的关系。

例如:

js 复制代码
<div>${response.template}</div>

由于Nodejs在应用层一般负责渲染页面模板,最常用的,XSS会出现在页面模板上,存在服务端渲染的场景都需要特别注意XSS问题。

XSS和CSRF的区别:

XSS:用户过分的信任网站的内容,导致打开网站通过浏览器发送恶意请求。

CSRF:网站过分信任用户,网站提供的api,没有做完善的校验。

应用安全风险:越权/SSRF/HPP

首先来介绍一下,什么叫做越权攻击。

一般越权,分为,水平越权/垂直越权。

水平越权:获取到跟访问者同级别的数据

垂直越权:拿到权限级别更高的数据或者权限。

可能会存在越权的场景?

(1)任何存在携带id的场景,如论坛,商品,帖子这种。(去年,阿里云盘曾经出现过这种问题。)

(2)任何容易被猜测的那种路由,URL路径随便改成admin/xxx,居然能进去的那种。

(3)网站退出登陆,登陆态还存在。(前几年有过)

当时的问题:baijiahao.baidu.com/s?id=182262...

对于公司来说,出现这种问题,就会造成很大的损失,用户的信任危机等。

出现这种问题,年终奖和绩效怕是也要清0了。

越权防范措施

(1)每个页面都需要做访问控制。

(2)禁止用一些危险的url:/admin /manage之类的

(3)ID的设计:唯一,尽量短,无规则,不可迭代和遍历。

(4)登陆态需要做过期时间,过期了就去重新登陆。

CSRF防范措施:

发送POST请求的时候,不光要携带Cookie,还要写代码一个Token。这个Token只能用户可以拿到。登陆之后,服务端给用户颁发这个Token,这个Token要有时效性。

如何给自己的程序添加一个CSRF的强服务端校验:

具体看这盘文章,楼主的实现方式跟他一样:

cloud.tencent.com/developer/i...

XSS防范措施:

针对前端来说,XSS漏洞是比较常见的。

总结来说,无论是前端还是后端,不要相信用户来源的任何输入。

a标签,img标签,这种携带URL的都比较危险。

这里可以用

js 复制代码
encodeURI(paramas)

一定要做相关的转义。

另外就是使用CSP技术,本章不过多赘述。

SSRF:服务端请求伪造。

像代理类,通过指定的url获取图片,保存后展示给用户这种。

或者开发者工具上会存在这样的隐患。

本质上就是能访问到公司/服务器内网的一些资源。

HPP:http参数污染

例如我随便猜测,get请求里,随便携带一些值。

比如我/action/testApi?id=1&id=2。

我就故意传两一样的id,猜测他会不会报错。

来个最简单的例子

js 复制代码
// POST name=小明&name=小明
req.body.name
//返回结果:
["小明","小明"]

这样就会产生报错了,业务逻辑直接崩了。。。

应用安全风险:不安全的跳转

伪造了一个假的网站,引诱用户去点击。

nodejs程序里,可能会使用.redirect这种去跳转重定向。

这样就有了比较危险的操作点。

还有一种情况,用一个假的iframe遮住网站。

这也是一种钓鱼手段。

应用安全风险:不安全的NPM包

经过检索。

大概有20%的npm包有各种安全漏洞。

NPM包是可以写各种各样的脚本和逻辑,会执行各种各样东西,去危害你的系统。

很多的包,带有挖矿脚本,跑到计算机后台去挖矿(这种影响不大,但是很难发现。)

使用NPM包也要格外注意安全问题。

用SNYK,或者其他工具去扫描,具体看下面的地址:

github.com/snyk/cli

应用安全风险:目录遍历攻击

许多web应用,会有文件读取查看的功能,说下几个存在问题的重灾区。

(1)带有文件上传和预览的服务。

(2)网盘,一定有这个问题。

(3)sass服务和云服务,效能平台这种,代码托管平台这种。

应用安全风险:API限流

限流的必要性:

应用级别的场景,控制客户端/app/网页到服务器的一个流量。

作用:

(1)降低风险。(减轻压力)

(2)控制服务能力。(比如按次收费,限制流量)

(3)节约成本。(降低机器成本)

熔断策略:直接拒绝服务。例如12306这种。

排队机制:被限制的访问加入队列。

等待:让给限制的访问,pending状态。

应用级限流规则介绍:

(1)固定窗口限制

例如一分钟请求1000次api。

请求一次,访问次数就++,窗口期师固定的。达到上限之后,达到1000次,开始做限流策略。

优点:实现起来很简单

缺点:对用户来说很不公平,先来先得的策略,对时间均匀的角度来看,也不公平。

(2)滑动窗口限制。

把单个窗口,视为多个时间片去做拆分。

例如我要限制1分钟,请求100次,第61s用户开始请求的时候,窗口并不是从60-120去创建的,而是从1s-61s去创建的,这样的限制,对所有用户都是公平的,解决了请求不均匀的问题。

时间分片越多,限流请求算法越精确。

优点:解决了访问不平衡的问题。

缺点:有内存占用的问题,时间分片设置太小,并发问题不好解决。

TCP的滑动窗口算法,也是类似这样的策略。

(3)漏斗策略

优点:实现起来比较简单,可以防止服务器过载

缺点:由于做了限制,用户比较容易感觉网站响应慢了,不能充分的利用网络资源。

注:具体该用什么策略,需要按照业务场景进行分析!

NodeJs-api限流

具体有开源出来的案例程序参考:github.com/jhurliman/n...

直接把代码拉下来就行了。

下面介绍下限流策略的实现:

安装下面这个包,限流插件。

js 复制代码
yarn add express-rate-limit

这里我写个简单的Case:

js 复制代码
const express = require('express');
const rateLimit  = require('express-rate-limit')
const app = express();

const rateLimitPlugin = rateLimit({
    windowMs:1000*60,//窗口期,
    max:10,//次数
    message:"超过了10次",
})

app.use(rateLimitPlugin)

app.get('/', (req, res) => {
  res.send('Hello World!');
});

const PORT = process.env.PORT || 3003
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

使用起来也非常简单,直接app.use就可以了。

当然也可以指定单个路由去做限流,上述例子限流会全局生效。

其他可以提供限流能力的思考

(1)数据库的连接池,线程池。

(2)Nginx的limit_conn模块,用来限制顺时的并发连接数。

(3)按照流量限流。

高可用的三大利器:限流/缓存/降级

(1)缓存:提升系统访问速度,增大系统处理容量。

(2)降级:当服务出现问题或者影响核心流程的时候,暂时屏蔽,合适的时候放开。

(3)限流:通过对并发访问/请求进行限制,来保护我们的服务器和系统。

有些场景,不能简单的通过缓存和降级来处理,比如一些抢票等,下单,发表评论这种业务操作。

这种场景只能限流。

总结起来就是

缓存是锦上添花,限流是居安思危,降级是及时止损。

当然这里还存在两个问题需要评论区一起讨论下?关于本期的一个思考。

(1)我们存在限流,缓存还有降级策略,为什么有时候12306抢票还是会挂掉?

(2)如何衡量这个限流的程度,上面那个Max值,和窗口期应该怎么定合适。

相关推荐
夕水8 分钟前
这个提升效率宝藏级工具一定要收藏使用
前端·javascript·trae
会飞的鱼先生22 分钟前
vue3 内置组件KeepAlive的使用
前端·javascript·vue.js
斯~内克36 分钟前
前端浏览器窗口交互完全指南:从基础操作到高级控制
前端
Mike_jia1 小时前
Memos:知识工作者的理想开源笔记系统
前端
前端大白话1 小时前
前端崩溃瞬间救星!10 个 JavaScript 实战技巧大揭秘
前端·javascript
loveoobaby1 小时前
Shadertoy着色器移植到Three.js经验总结
前端
蓝易云1 小时前
在Linux、CentOS7中设置shell脚本开机自启动服务
前端·后端·centos
浩龙不eMo1 小时前
前端获取环境变量方式区分(Vite)
前端·vite
一千柯橘1 小时前
Nestjs 解决 request entity too large
javascript·后端
土豆骑士1 小时前
monorepo 实战练习
前端