服务端的安全十分重要,所以防止网络攻击是必须进行。一般攻击方式有CSRF,XSS,SQL注入等。服务端原理大致就是增加过滤条件及合法验证
这里不对XSS/CSRF攻击方式及原理描述
不做详细介绍。各种技术博客已经讲的很详细了,如果不了解的话,可以自行搜索查看。
默认你对
class-validator,class-transformer,guard,interceptor等已经了解
在这之前,先了解XSS一些基本知识
XSS,全称是Cross-Site Scripting(跨站脚本攻击),是一种常见的网络安全漏洞。它允许攻击者将恶意脚本注入到正常用户会看到的页面中。当其他用户浏览这些页面时,嵌入其中的恶意脚本将在他们的浏览器中执行,这可能导致用户数据被盗取、会话被劫持、恶意软件被下载等一系列问题。
防御
对于XSS,常见的防御手段包括
- 对用户输入进行严格的
过滤和转义 - 使用
内容安全策略(CSP)等。
Code it
在NestJS中,有一些配置是开箱即用,引用对应的插件会默认处理,如果你有自定义的需要,你可以在插件处配置一些自定义配置
下面分为两部分处理
1.过滤危险Html内容
这里使用到dompurify,用来将文本中的一些危险html清除或者替换。
它暂不支持转义html,我建议转义的操作前端处理,如果前端传递接口中出现了未转义的html标签内容,则表示是非正常提交传递直接清除即可。
代码逻辑
为了保证代码的可复用性和解耦,我们将使用class-transformer自定义一个转换的装饰器,在需要转换的Dto字段使用装饰器即可完成,无需在服务层进行特定的代码处理。
定义装饰器
注意:因为dompurify是在broswer环境上使用的,所以在服务端使用需要使用jsdom
// DOMPurify.transform.decorator.ts
import { TransformFnParams } from 'class-transformer';
import { JSDOM } from 'jsdom';
import * as DOMPurify from 'dompurify';
export const DOMPurifyTransform = ({ value }: TransformFnParams) => {
if (typeof value === 'string') {
const window = new JSDOM('').window;
const purify = DOMPurify(window);
const result = purify.sanitize(value);
// 这里可以加入日志记录有XSS攻击出现
// if(result !== value){
// console.log('XSS攻击', value)
// }
return result;
}
return value;
};
使用装饰器
import { DOMPurifyTransform } from '@/decorators/DOMPurify.transform.decorator';
import { Transform } from 'class-transformer';
import { IsNotEmpty, IsOptional, IsString, Length } from 'class-validator';
export class CreateArticleDto {
@IsNotEmpty()
@Length(5, 30)
title: string;
@Length(5, 8000)
@IsNotEmpty()
@Transform(DOMPurifyTransform)
content: string;
@IsNotEmpty()
categoryId: string;
creatorId?: string;
}
2.使用helmet增加csp头部
Helmet除了增加CSP头部,其实默认设置了以下头部信息:
Content-Security-Policy:一个强大的白名单,规定了页面上可以发生什么,从而减轻了许多攻击。- Cross-Origin-Opener-Policy:帮助对你的页面进行进程隔离。
- Cross-Origin-Resource-Policy:阻止其他来源加载你的资源。
- Origin-Agent-Cluster:将进程隔离更改为基于来源的。
- Referrer-Policy:控制Referer头部信息。
- Strict-Transport-Security:告诉浏览器偏好HTTPS。
- X-Content-Type-Options:避免MIME类型嗅探。
- X-DNS-Prefetch-Control:控制DNS预获取。
- X-Download-Options:强制下载被保存(仅限Internet Explorer)。
- X-Frame-Options:一个减轻点击劫持攻击的旧头部信息。
- X-Permitted-Cross-Domain-Policies:控制Adobe产品(如Acrobat)的跨域行为。
- X-Powered-By:关于Web服务器的信息。由于它可能被用于简单的攻击,因此被移除。
- X-XSS-Protection:一个旨在减轻XSS攻击的旧头部信息,但实际上可能会使情况变得更糟,因此Helmet将其禁用。
引用及注册
因为我的项目使用的是Fastify,已经有官方插件所以这一步很简单 安装fastify-helmet包:
$ npm i --save fastify-helmet
fastify-helmet需要作为Fastify插件使用
import * as helmet from 'fastify-helmet';
app.register(helmet);
效果
引入Helmet后,你会发现你的Reponse中会出现如下头部,表示helmet正常工作啦
完结,撒花❀❀❀❀❀❀
下一部分是CSRF