helmet.hsts()
,网站会在未来的90天内使用 HTTPS。我们还可以传入配置对象 {maxAge: timeInSeconds, force: true}
。Repl.it 默认已经开启 hsts,但你仍然可以通过添加 {force: true}
来覆盖它。我们会拦截 Glitch 请求的 header 来进行此挑战的测试,然后恢复此项配置。
+注意: 配置 HTTPS 需要域名以及 SSL/TSL 证书。
app.use(helmet({
frameguard: { // configure
action: 'deny'
},
contentSecurityPolicy: { // enable and configure
directives: {
defaultSrc: ["self"],
styleSrc: ['style.com'],
}
},
dnsPrefetchControl: false // disable
}))
我们分别为教学目的引入了每个中间件,并且易于测试。使用“父”头盔()中间件对于真实项目来说是最简单,更清洁的。 app.use(helmet())
会自动加载除了 noCache()
和 contentSecurityPolicy()
以外的,上面所有提到的中间件。但如果需要的话,我们也可以手动加入这两个中间件。通过修改配置对象,你还可以启用或禁用其它中间件。
+helmet()
来实现是最清晰和简洁的。
+bcrypt.hash(myPlaintextPassword, saltRounds, (err, hash) => { /*Store hash in your db*/ });
bcrypt.compare(myPlaintextPassword, hash, (err, res) => { /*res == true or false*/ });
。在记录完成的哈希并将“res”记录到比较中的控制台之后,将其添加到现有哈希函数中(因为您需要在调用比较函数之前等待哈希完成)。您应该在控制台中看到一个哈希值,然后打印出“true”!如果您将compare函数中的'myPlaintextPassword'更改为'someOtherPlaintextPassword',那么它应该为false。 bcrypt.hash('passw0rd!',13,(错误,哈希)=> { - 的console.log(散列); //$2a$12$Y.PHPE15wR25qrrtgGkiYe2sXo98cjuMCG1YwSI5rJW1DSJp0gEYS - bcrypt.compare('passw0rd!',hash,(err,res)=> { - 的console.log(RES); //真正 - }); -});当您认为自己已经做对时,请提交您的页面。
true
。如果将比较函数中的 "myPlaintextPassword" 更改为 "someOtherPlaintextPassword",则比较的结果应显示 false
。
+
+```js
+bcrypt.hash('passw0rd!', 13, (err, hash) => {
+ console.log(hash);
+ //$2a$12$Y.PHPE15wR25qrrtgGkiYe2sXo98cjuMCG1YwSI5rJW1DSJp0gEYS
+ bcrypt.compare('passw0rd!', hash, (err, res) => {
+ console.log(res); //true
+ });
+});
+
+```
+
+请在完成挑战后提交你的页面。
var hash = bcrypt.hashSync(myPlaintextPassword, saltRounds);
var result = bcrypt.compareSync(myPlaintextPassword, hash);
结果是布尔值true或false。添加此功能并登录控制台结果以查看其是否正常工作。当您认为自己已经做对时,请提交您的页面。如果您在这些挑战期间遇到错误,可以在此处查看示例完成的代码。 true
或 false
+X-Powered-By: Express
默认情况下会添加到所有响应的 header。不过 helmet.hidePoweredBy()
中间件可以帮你把 header 中的 X-Powered-By 字段移除。你甚至可以把它设置成其它的值来骗过黑客,比如 app.use(helmet.hidePoweredBy({ setTo: 'PHP 4.2.0' }))
+package.json
中应存在版本号为 3.21.3
的 helmet
依赖项'
+ testString: getUserInput => $.get(getUserInput('url') + '/_api/package.json').then(data => { var packJson = JSON.parse(data); assert(packJson.dependencies.helmet === '3.21.3' ); }, xhr => { throw new Error(xhr.responseText); })
```
@@ -34,7 +39,11 @@ tests:
<frame>
或<iframe>
。除其他外,这可能导致点击劫持攻击。点击劫持是一种欺骗用户与不同于用户认为的页面进行交互的技术。这可以通过iframing在恶意上下文中执行您的页面获得。在这种情况下,黑客可以在页面上放置隐藏层。隐藏按钮可用于运行错误的脚本。此中间件设置X-Frame-Options标头。它限制了谁可以将您的网站放在框架中。它有三种模式:DENY,SAMEORIGIN和ALLOW-FROM。我们不需要我们的应用程序框架。您应该使用配置对象{action: 'deny'}
传递的helmet.frameguard()
。
或者
标签里,用以实现“点击劫持”。点击劫持是一种视觉上的欺骗手段,让用户误以为自己在与所看到的网页交互。通过 iframe,黑客可以在你的页面上添加一个透明的“层”,然后把自己的恶意代码放在一个用户看不到的按钮中。这样一来,你网站的执行环境就被黑客设置成了他想要的效果。helmet 中间件可以设置 header 中的 X-Frame-Options 字段,这样我们就能设置哪些人才可以通过 frame/iframe 引入我们的页面了。这个配置有三个选项:DENY、SAMEORIGIN、ALLOW-FROM。
+在这个挑战中,我们的应用不需要被 iframe 引用。
+helmet.frameguard()
,并传入配置对象 {action: 'deny'}
。
helmet.contentSecurityPolicy()
,并将其配置为将defaultSrc指令
设置为["self"]
(允许的列表) 来源必须位于一个数组中,以便默认情况下仅信任您的网站地址。 还设置scriptSrc
指令,以便您允许从您的网站以及"trusted-cdn.com"域下载脚本。
-提示:在self
关键字中,单引号是关键字本身的一部分,因此需要使用双引号将其括起来才能起作用。
+helmet.contentSecurityPolicy()
并配置 defaultSrc
为 ["self"]
(允许的资源列表必须在一个数组当中)。这样做表示只信任自己网站的域名。另外,配置 scriptSrc
指令可以限制脚本只能本网站域名上或者信任的域名 'trusted-cdn.com' 上下载。
+提示: 在 self
关键词中, 单引号也是关键词的一部分, 所以你应该用双引号来包起它才能正常工作。
$2a$13$ZyprE5MRw2Q3WpNOGZWGbeG7ADUre1Q8QO.uUUtcbqloU0yvzavOm
确实有一个结构。第一小部分数据$2a
定义了使用何种哈希算法。下一部分$13
定义了成本 。成本是计算哈希值所需的功率。它具有2 ^成本的对数标度,并确定通过散列算法放置数据的次数。例如,以10为代价,您可以在普通计算机上每秒散列10个密码,但是每个散列需要花费3秒才能进行散乱...并且需要花费更多时间,成本为31需要多天才能完成哈希。目前,12的成本被认为是非常安全的。哈希$ZyprE5MRw2Q3WpNOGZWGbeG7ADUre1Q8QO.uUUtcbqloU0yvzavOm
的最后一部分看起来像$ZyprE5MRw2Q3WpNOGZWGbeG7ADUre1Q8QO.uUUtcbqloU0yvzavOm
数字,句号和字母,但它实际上是两条独立的信息。前22个字符是纯文本的盐,其余的是哈希密码! $2a$13$ZyprE5MRw2Q3WpNOGZWGbeG7ADUre1Q8QO.uUUtcbqloU0yvzavOm
。它遵循固定的结构,前面一小节 $2a
说明了该哈希采用什么算法。下一部分 $13
定义了 cost。cost 就是生成此哈希结果所用到的资源数量级;它是 2^cost 的对数,可以表说单位时间内数据放入哈希算法的次数。举个例子,cost 为 10 的意思就是说你能够在一个普通的计算机上每秒钟计算出 10 个密码的哈希结果。然而,如果 cost 为 15,那计算每个哈希结果就要 3 秒钟。再举例子,如果 cost 是 31,那每次哈希运算需要话费好几天才能完成。通常 cost 为 12 的哈希运算就已经足够安全。哈希结果的最后一部分 $ZyprE5MRw2Q3WpNOGZWGbeG7ADUre1Q8QO.uUUtcbqloU0yvzavOm
看起来像是由随机数字、点和字母组成的字符串,但实际上它有两部分内容。前面 22 个字符是加入的盐,剩下的就是加密过的密码!
+