概述
事实上,许多运维团队和后端团队的视角里,对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,或者其他工具去扫描,具体看下面的地址:
应用安全风险:目录遍历攻击
许多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值,和窗口期应该怎么定合适。