使用nodejs express框架搭建网站应用,在处理安全问题的时候就离不开helmet中间件了,为什么这么讲呢?
主要是因为helmet集成了各种HTTP头信息来帮助保护Express应用程序, 如:XSS攻击、CSP内容安全策略、dns保护、iframe同源限制等,省得开发一个个处理了。
一、安装使用
> npm install helmet --save
在app.js引入使用,如果不想特殊设置就使用默认即可
const express = require("express");
const helmet = require("helmet");
const app = express();
app.use(helmet());
如果使用的是Koa框架,安装koa-helmet即可
二、方法介绍
helmet总共结合了11个小中间件
app.use(helmet());
等同于
app.use(helmet.contentSecurityPolicy());
app.use(helmet.dnsPrefetchControl());
app.use(helmet.expectCt());
app.use(helmet.frameguard());
app.use(helmet.hidePoweredBy());
app.use(helmet.hsts());
app.use(helmet.ieNoOpen());
app.use(helmet.noSniff());
app.use(helmet.permittedCrossDomainPolicies());
app.use(helmet.referrerPolicy());
app.use(helmet.xssFilter());
1、helmet(option)
option键为包含方法的方法名,值为该方法的选项值,不过里加了一个true/false用来启用/禁用该功能
app.use(
helmet({
frameguard: {
action: 'sameorigin' // iframe设置同源
},
contentSecurityPolicy: false, // 关闭内容安全策略
expectCt: {
maxAge: 86400 // 证书透明化最大时间为1天,单位秒
}
})
);
2、helmet.contentSecurityPolicy(options)
CSP(Content Security Policy)内容安全策略
主要用来预防跨站脚本攻击,不过这个中间件很少执行验证,完全依赖CSP设置
options.directives
是一个对象,键为规则为defaultSrc
或default-src
。options.reportOnly
只读,是一个boolean值,默认为false
如果没有提供指令,则设置以下策略:
default-src 'self';
base-uri 'self';
block-all-mixed-content;
font-src 'self' https: data:;
frame-ancestors 'self';
img-src 'self' data:;
object-src 'none';
script-src 'self';
script-src-attr 'none';
style-src 'self' https: 'unsafe-inline';
upgrade-insecure-requests
示例:
// Sets "Content-Security-Policy: default-src 'self';script-src 'self' example.com;object-src 'none';upgrade-insecure-requests"
app.use(
helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "example.com"],
objectSrc: ["'none'"],
upgradeInsecureRequests: [],
},
})
);
// Sets "Content-Security-Policy: default-src 'self';script-src 'self' example.com;object-src 'none'"
app.use(
helmet.contentSecurityPolicy({
directives: {
"default-src": ["'self'"],
"script-src": ["'self'", "example.com"],
"object-src": ["'none'"],
},
})
);
// Sets the "Content-Security-Policy-Report-Only" header instead
app.use(
helmet.contentSecurityPolicy({
directives: {
/* ... */
},
reportOnly: true,
})
);
// Sets "Content-Security-Policy: default-src 'self';script-src 'self' 'nonce-e33ccde670f149c1789b1e1e113b0916'"
app.use((req, res, next) => {
res.locals.cspNonce = crypto.randomBytes(16).toString("hex");
next();
});
app.use(
helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", (req, res) => `'nonce-${res.locals.cspNonce}'`],
},
})
);
可以单独安装helmet-csp
3、helmet.expectCt(options)
helmet.expectCt
设置了Expect-CT
头,有助于减轻错误颁发的SSL证书,更多信息请参考MDN上的Expect-CT介绍
options.maxAge
期望证书透明化的秒数,默认为0options.enforce
是一个布尔值。如果为true,用户代理(通常是浏览器)应该拒绝违反其证书透明策略的连接。默认值为falseoptions.reportUri
是一个字符串,如果失败则向该URI报告
示例:
// Sets "Expect-CT: max-age=86400"
app.use(
helmet.expectCt({
maxAge: 86400,
})
);
// Sets "Expect-CT: max-age=86400, enforce, report-uri="https://example.com/report"
app.use(
helmet.expectCt({
maxAge: 86400,
enforce: true,
reportUri: "https://example.com/report",
})
);
可以单独安装expect-ct
4、helmet.referrerPolicy(options)
helmet.referrerPolicy
设置Referrer-Policy
头,更多信息请参考:Referer
options.policy
字符串/数组,默认为no-referrer
示例:
// Sets "Referrer-Policy: no-referrer"
app.use(
helmet.referrerPolicy({
policy: "no-referrer",
})
);
// Sets "Referrer-Policy: origin,unsafe-url"
app.use(
helmet.referrerPolicy({
policy: ["origin", "unsafe-url"],
})
);
可以单独安装referrer-policy
5、helmet.hsts(options)
helmet.hsts
设置Strict-Transport-Security头,告诉浏览器使用安全的https协议而不是http
options.maxAge
浏览器应该记住使用HTTPS的秒数。如果传递的是非整数,则该值四舍五入。它的默认值是15552000,也就是180天。options.includeSubDomains
是一个布尔值,指定是否包含includeSubDomains指令,该指令使此策略扩展到子域。它默认为true。options.preload
是一个布尔值。如果为真,它会添加preload指令,表示将HSTS策略添加到浏览器。更多信息请参考Preloading Strict Transport Security。默认为false。
示例:
// Sets "Strict-Transport-Security: max-age=123456; includeSubDomains"
app.use(
helmet.strictTransportSecurity({
maxAge: 123456,
})
);
// Sets "Strict-Transport-Security: max-age=123456"
app.use(
helmet.strictTransportSecurity({
maxAge: 123456,
includeSubDomains: false,
})
);
// Sets "Strict-Transport-Security: max-age=123456; includeSubDomains; preload"
app.use(
helmet.strictTransportSecurity({
maxAge: 63072000,
preload: true,
})
);
可以单独安装hsts
6、helmet.noSniff()
helmet.noSniff
设置X-Content-Type-Options
头为nosniff
,这减轻了MIME type sniffing
可能导致安全漏洞的影响。
示例:
// Sets "X-Content-Type-Options: nosniff"
app.use(helmet.noSniff());
可以单独安装dont-sniff-mimetype
7、helmet.dnsPrefetchControl(options)
helmet.dnsPrefetchControl
设置X-DNS-Prefetch-Control
头帮助控制DNS预取,这会以牺牲性能为代价提高用户隐私。
更多信息请参考:X-DNS-Prefetch-Control
options.allow
是一个布尔值,指定是否启用DNS预取。默认为false。
示例:
// Sets "X-DNS-Prefetch-Control: off"
app.use(
helmet.dnsPrefetchControl({
allow: false,
})
);
// Sets "X-DNS-Prefetch-Control: on"
app.use(
helmet.dnsPrefetchControl({
allow: true,
})
);
可以单独安装dns-prefetch-control
8、helmet.ieNoOpen()
helmet.ieNoOpen
设置X-Download-Options
头,这是Internet Explorer 8特有的。强制保存潜在不安全的下载,减少了HTML在站点上下文中的执行。更多信息请参考:IE8 Security
示例:
// Sets "X-Download-Options: noopen"
app.use(helmet.ieNoOpen());
可以单独安装ienoopen
9、helmet.frameguard(options)
helmet.frameguard
设置X-Frame-Options
头来预防点击劫持,这个功能被CSP的frame-ancestors替代了,不过对旧的浏览器仍然有用。更多信息请参考:X-Frame-Options
options.action
是一个字符串,指定使用哪个安全策略(DENY
或SAMEORIGIN
)不支持ALLOW-FROM
,默认是SAMEORIGIN
示例:
// Sets "X-Frame-Options: DENY"
app.use(
helmet.frameguard({
action: "deny",
})
);
// Sets "X-Frame-Options: SAMEORIGIN"
app.use(
helmet.frameguard({
action: "sameorigin",
})
);
可以单独安装frameguard
10、helmet.permittedCrossDomainPolicies(options)
helmet.permittedCrossDomainPolicies
设置X-Permitted-Cross-Domain-Policies
头,告诉一些客户端(主要是Adobe产品)加载跨域内容策略。
options.permittedPolicies
是一个字符串,值有:none
、master-only
、by-content-type
和all
,默认为none
示例:
// Sets "X-Permitted-Cross-Domain-Policies: none"
app.use(
helmet.permittedCrossDomainPolicies({
permittedPolicies: "none",
})
);
// Sets "X-Permitted-Cross-Domain-Policies: by-content-type"
app.use(
helmet.permittedCrossDomainPolicies({
permittedPolicies: "by-content-type",
})
);
可以单独安装helmet-crossdomain
11、helmet.hidePoweredBy(options)
helmet.hidePoweredBy
删除X-Powered-By
头,这在Express
框架是默认设置的,安全作用有限,主要是为了节省带宽。
示例:
// Removes the X-Powered-By header if it was set.
app.use(helmet.hidePoweredBy());
Express框架内置使用
app.disable("x-powered-by");
可以单独安装hide-powered-by
12、helmet.xssFilter(options)
helmet.xssFilter
设置X-XSS-Protection
头为0来禁用浏览器的错误XSS
过滤,更多信息请参考:X-XSS-Protection
示例:
// Sets "X-XSS-Protection: 0"
app.use(helmet.xssFilter());
可以单独安装x-xss-protection
以上是关于helmet的总体介绍,在处理常规安全上基本都覆盖了,帮助开发者省了不少工作量。
参考链接: