fix(i18n): update Chinese translation of information security with helmetjs (#38908)

This commit is contained in:
ZhichengChen
2020-08-16 04:50:30 +08:00
committed by GitHub
parent 4326253440
commit f35e7de03e
14 changed files with 298 additions and 95 deletions

View File

@ -2,15 +2,21 @@
id: 587d8248367417b2b2512c3c id: 587d8248367417b2b2512c3c
title: Ask Browsers to Access Your Site via HTTPS Only with helmet.hsts() title: Ask Browsers to Access Your Site via HTTPS Only with helmet.hsts()
challengeType: 2 challengeType: 2
videoUrl: '' isHidden: false
localeTitle: 要求浏览器通过HTTPS访问您的站点仅限于使用helmet.hsts forumTopicId: 301573
localeTitle: 使用 helmet.hsts() 要求浏览器只通过HTTPS访问你的网站
--- ---
## Description ## Description
<section id="description">提醒一下,这个项目是基于<a href="https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-infosec/">Glitch</a>的以下入门项目构建的,或者是从<a href="https://github.com/freeCodeCamp/boilerplate-infosec/">GitHub</a>克隆的。 HTTP严格传输安全HSTS是一种Web安全策略可帮助保护网站免受协议降级攻击和cookie劫持。如果您的网站可以通过HTTPS访问您可以要求用户的浏览器避免使用不安全的HTTP。通过设置标头Strict-Transport-Security您可以告诉浏览器在指定的时间内对将来的请求使用HTTPS。这将适用于初始请求之后的请求。配置helmet.hsts以在接下来的90天内使用HTTPS。传递配置对象{maxAgetimeInSecondsforcetrue}。 Glitch已经启用了hsts。要覆盖其设置您需要在配置对象中将字段“force”设置为true。在检查Glitch标头进行测试后我们将拦截并恢复Glitch标头。注意在自定义网站上配置HTTPS需要获取域和SSL / TSL证书。 </section> <section id='description'>
温馨提醒,本项目在 <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-infosec/'>这个 Glitch 项目</a> 的基础上进行开发。你也可以从 <a href='https://github.com/freeCodeCamp/boilerplate-infosec/'>GitHub</a> 上克隆。
HTTP严格安全传输 (HSTS) 是一个能帮助我们防护网站被协议降低攻击和 Cookie 挟持的 WEB 安全协议。如果你的网站支持 HTTPS 的话你可以让你的用户停止使用不安全的 HTTP。通过设置头部 ``Strict-Transport-Security``, 你告诉浏览器使用在未来的某段指定时间内使用 HTTPS 来请求网站内容。首次请求之后所以的后续请求都将使用 HTTPS
</section>
## Instructions ## Instructions
<section id="instructions"> <section id='instructions'>
配置 helmet.hsts() 在未来的90天内使用 HTTPS。传递配置对象 {maxAge: timeInMilliseconds, force: true}. Glitch 默认已经开启 ``hsts``. 但你仍然可以通过 "force" 来覆盖它的配置。为了测试,我们会审查 Glitch 请求头部,然后拦截并恢复。
注意: 配置 HTTPS 需要域名以及 SSL/TSL 证书。
</section> </section>
## Tests ## Tests
@ -18,9 +24,9 @@ localeTitle: 要求浏览器通过HTTPS访问您的站点仅限于使用helmet.h
```yml ```yml
tests: tests:
- text: helmet.hsts中间件应正确安装 - text: helmet.hsts() 中间件应该被正确加载
testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { assert.include(data.appStack, 'hsts'); assert.property(data.headers, 'strict-transport-security'); }, xhr => { throw new Error(xhr.responseText); }) testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { assert.include(data.appStack, 'hsts'); assert.property(data.headers, 'strict-transport-security'); }, xhr => { throw new Error(xhr.responseText); })
- text: maxAge应该等于7776000毫秒90天 - text: maxAge 应该等于 7776000 ms (90天)
testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { assert.match(data.headers['strict-transport-security'], /^max-age=7776000;?/); }, xhr => { throw new Error(xhr.responseText); }) testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { assert.match(data.headers['strict-transport-security'], /^max-age=7776000;?/); }, xhr => { throw new Error(xhr.responseText); })
``` ```
@ -36,6 +42,11 @@ tests:
<section id='solution'> <section id='solution'>
```js ```js
// solution required /**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
``` ```
</section> </section>

View File

@ -2,15 +2,20 @@
id: 587d8248367417b2b2512c3a id: 587d8248367417b2b2512c3a
title: Avoid Inferring the Response MIME Type with helmet.noSniff() title: Avoid Inferring the Response MIME Type with helmet.noSniff()
challengeType: 2 challengeType: 2
videoUrl: '' isHidden: false
localeTitle: 避免使用helmet.noSniff推断响应MIME类型 forumTopicId: 301574
localeTitle: 使用 helment.noSniff() 避免推断响应的 MIME 类型
--- ---
## Description ## Description
<section id="description">提醒一下,这个项目是基于<a href="https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-infosec/">Glitch</a>的以下入门项目构建的,或者是从<a href="https://github.com/freeCodeCamp/boilerplate-infosec/">GitHub</a>克隆的。浏览器可以使用内容或MIME嗅探来适应来自响应的不同数据类型。它们覆盖Content-Type标头以猜测和处理数据。虽然这在某些情况下可能很方便但它也可能导致一些危险的攻击。此中间件将X-Content-Type-Options标头设置为nosniff。这指示浏览器不绕过提供的Content-Type。 </section> <section id='description'>
温馨提醒,本项目在 <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-infosec/'>这个 Glitch 项目</a> 的基础上进行开发。你也可以从 <a href='https://github.com/freeCodeCamp/boilerplate-infosec/'>GitHub</a> 上克隆。
浏览器可以通过探查 ``content`` 或者 ``MIME`` 头部来判断不同的响应内容。这两个的优先级比 ``Content-Type`` 还高,浏览器可以通过这两个头部来猜测并处理响应。这个在某些情况下非常实用,但也会造成一定的潜在风险。我们可以通过中间件来设置 ``X-Content-Type-Options`` 头部为 ``nosniff``。 这样,浏览器就不会绕过 ``Content-Type`` 这个头了。
</section>
## Instructions ## Instructions
<section id="instructions"> <section id='instructions'>
</section> </section>
## Tests ## Tests
@ -18,7 +23,7 @@ localeTitle: 避免使用helmet.noSniff推断响应MIME类型
```yml ```yml
tests: tests:
- text: helmet.noSniff中间件应该正确安装 - text: helmet.noSniff() 中间件应该正确加载
testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { assert.include(data.appStack, 'nosniff'); assert.equal(data.headers['x-content-type-options'], 'nosniff'); }, xhr => { throw new Error(xhr.responseText); }) testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { assert.include(data.appStack, 'nosniff'); assert.equal(data.headers['x-content-type-options'], 'nosniff'); }, xhr => { throw new Error(xhr.responseText); })
``` ```
@ -34,6 +39,11 @@ tests:
<section id='solution'> <section id='solution'>
```js ```js
// solution required /**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
``` ```
</section> </section>

View File

@ -2,15 +2,38 @@
id: 587d8249367417b2b2512c40 id: 587d8249367417b2b2512c40
title: Configure Helmet Using the parent helmet() Middleware title: Configure Helmet Using the parent helmet() Middleware
challengeType: 2 challengeType: 2
videoUrl: '' isHidden: false
localeTitle: 配置头盔使用“父”头盔()中间件 forumTopicId: 301575
localeTitle: 使用 helmet() 中间件来配置 Helmet
--- ---
## Description ## Description
<section id="description">提醒一下,这个项目是基于<a href="https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-infosec/">Glitch</a>的以下入门项目构建的,或者是从<a href="https://github.com/freeCodeCamp/boilerplate-infosec/">GitHub</a>克隆的。 app.usehelmet将自动包含上面介绍的所有中间件noCache和contentSecurityPolicy除外但如果需要可以启用这些中间件。您还可以使用配置对象单独禁用或配置任何其他中间件。 //示例<code>app.use(helmet({</code> <code>frameguard: { // configure</code> <code>action: &#39;deny&#39;</code> <code>},</code> <code>contentSecurityPolicy: { // enable and configure</code> <code>directives: {</code> <code>defaultSrc: [&quot;self&quot;],</code> <code>styleSrc: [&#39;style.com&#39;],</code> <code>}</code> <code>},</code> <code>dnsPrefetchControl: false // disable</code> <code>}))</code>我们分别为教学目的引入了每个中间件,并且易于测试。使用“父”头盔()中间件对于真实项目来说是最简单,更清洁的。 </section> <section id='description'>
温馨提醒,本项目在 <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-infosec/'>这个 Glitch 项目</a> 的基础上进行开发。你也可以从 <a href='https://github.com/freeCodeCamp/boilerplate-infosec/'>GitHub</a> 上克隆。
app.use(helmet()) 会自动加载除 noCache() 和 contentSecurityPolicy() 外上面所有提到的中间件,但有需要的话这两个中间件也被启用。你也可以使用配置对象来一个个地禁用或者配置中间件。
<h3>例子:</h3>
```js
app.use(helmet({
frameguard: { // configure
action: 'deny'
},
contentSecurityPolicy: { // enable and configure
directives: {
defaultSrc: ["self"],
styleSrc: ['style.com'],
}
},
dnsPrefetchControl: false // disable
}))
```
为了教学和方便测试我们是一个个地讲解中间件,但通过使用 parent helmet() 是最清晰和简洁的,特别是在真实的项目中。
</section>
## Instructions ## Instructions
<section id="instructions"> <section id='instructions'>
</section> </section>
## Tests ## Tests
@ -18,7 +41,7 @@ localeTitle: 配置头盔使用“父”头盔()中间件
```yml ```yml
tests: tests:
- text: 没有测试 - 这是一个描述性的挑战 - text: 没有测试 - 这是一个介绍关卡
testString: assert(true) testString: assert(true)
``` ```
@ -34,6 +57,11 @@ tests:
<section id='solution'> <section id='solution'>
```js ```js
// solution required /**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
``` ```
</section> </section>

View File

@ -2,15 +2,20 @@
id: 587d8249367417b2b2512c3e id: 587d8249367417b2b2512c3e
title: Disable Client-Side Caching with helmet.noCache() title: Disable Client-Side Caching with helmet.noCache()
challengeType: 2 challengeType: 2
videoUrl: '' isHidden: false
localeTitle: 使用helmet.noCache禁用客户端缓存 forumTopicId: 301576
localeTitle: 使用 helment.noCache() 禁用客户端缓存
--- ---
## Description ## Description
<section id="description">提醒一下,这个项目是基于<a href="https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-infosec/">Glitch</a>的以下入门项目构建的,或者是从<a href="https://github.com/freeCodeCamp/boilerplate-infosec/">GitHub</a>克隆的。如果您要为您的网站发布更新,并且您希望用户始终下载较新的版本,您可以(尝试)在客户端的浏览器上禁用缓存。它在开发中也很有用。缓存具有性能优势,您将失去这些优势,因此只有在真正需要时才使用此选项。 </section> <section id='description'>
温馨提醒,本项目在 <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-infosec/'>这个 Glitch 项目</a> 的基础上进行开发。你也可以从 <a href='https://github.com/freeCodeCamp/boilerplate-infosec/'>GitHub</a> 上克隆。
如果你为你的网站发布了一个更新,你想要用户永远使用最新的版本。你可以通过禁用浏览器的缓存来实现。这个功能在开发环境中也非常有用。当然你会失去缓存在性能上的优势,所以你应该在真正有必要的时候才用这个功能
</section>
## Instructions ## Instructions
<section id="instructions"> <section id='instructions'>
</section> </section>
## Tests ## Tests
@ -18,7 +23,7 @@ localeTitle: 使用helmet.noCache禁用客户端缓存
```yml ```yml
tests: tests:
- text: 应该正确安装helmet.noCache()中间件 - text: helmet.noCache() 中间件应该被正确加载
testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { assert.include(data.appStack, 'nocache'); assert.equal(data.headers['cache-control'], 'no-store, no-cache, must-revalidate, proxy-revalidate'); }, xhr => { throw new Error(xhr.responseText); }) testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { assert.include(data.appStack, 'nocache'); assert.equal(data.headers['cache-control'], 'no-store, no-cache, must-revalidate, proxy-revalidate'); }, xhr => { throw new Error(xhr.responseText); })
``` ```
@ -34,6 +39,11 @@ tests:
<section id='solution'> <section id='solution'>
```js ```js
// solution required /**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
``` ```
</section> </section>

View File

@ -2,15 +2,20 @@
id: 587d8248367417b2b2512c3d id: 587d8248367417b2b2512c3d
title: Disable DNS Prefetching with helmet.dnsPrefetchControl() title: Disable DNS Prefetching with helmet.dnsPrefetchControl()
challengeType: 2 challengeType: 2
videoUrl: '' isHidden: false
localeTitle: 使用helmet.dnsPrefetchControl禁用DNS预取 forumTopicId: 301577
localeTitle: 使用 helmet.dnsPrefetchControl() 禁用 DNS 预取
--- ---
## Description ## Description
<section id="description">提醒一下,这个项目是基于<a href="https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-infosec/">Glitch</a>的以下入门项目构建的,或者是从<a href="https://github.com/freeCodeCamp/boilerplate-infosec/">GitHub</a>克隆的。为了提高性能大多数浏览器都会为页面中的链接预取DNS记录。以这种方式当用户点击链接时目标IP已知。这可能导致过度使用DNS服务如果您拥有一个大网站数百万人访问......隐私问题一个窃听者可能会推断您在某个页面上或者页面统计信息更改某些链接可能会即使他们不是也会出现。如果您有高安全性需求则可以以性能损失为代价禁用DNS预取。 </section> <section id='description'>
温馨提醒,本项目在 <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-infosec/'>这个 Glitch 项目</a> 的基础上进行开发。你也可以从 <a href='https://github.com/freeCodeCamp/boilerplate-infosec/'>GitHub</a> 上克隆。
为了提高性能,大部分浏览器都会为页面上的链接预先加载 DNS 记录。这样当用户点击一个链接的时候浏览器已经提前知道 IP 地址了。但这也会造成 DNS 服务的过度使用(如果你是一个大型网站,有这千万级的用户的情况下),隐私问题 (窃听者可以推测出你在哪个页面上),和页面数据准确性(有些没访问过的链接会被标记成已访问)。如果你对安全性要求比较高,你应该禁用 DNZ 预加载。当然,这样做性能上会有一点点损失.
</section>
## Instructions ## Instructions
<section id="instructions"> <section id='instructions'>
</section> </section>
## Tests ## Tests
@ -18,7 +23,7 @@ localeTitle: 使用helmet.dnsPrefetchControl禁用DNS预取
```yml ```yml
tests: tests:
- text: 应该正确安装helmet.dnsPrefetchControl()中间件 - text: helmet.dnsPrefetchControl() 中间件应该被正确加载
testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { assert.include(data.appStack, 'dnsPrefetchControl'); assert.equal(data.headers['x-dns-prefetch-control'], 'off'); }, xhr => { throw new Error(xhr.responseText); }) testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { assert.include(data.appStack, 'dnsPrefetchControl'); assert.equal(data.headers['x-dns-prefetch-control'], 'off'); }, xhr => { throw new Error(xhr.responseText); })
``` ```
@ -34,6 +39,11 @@ tests:
<section id='solution'> <section id='solution'>
```js ```js
// solution required /**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
``` ```
</section> </section>

View File

@ -2,20 +2,48 @@
id: 58a25bcff9fc0f352b528e7d id: 58a25bcff9fc0f352b528e7d
title: Hash and Compare Passwords Asynchronously title: Hash and Compare Passwords Asynchronously
challengeType: 2 challengeType: 2
videoUrl: '' isHidden: false
localeTitle: 哈希和异步比较密码 localeTitle: 异步哈希和比较密码
--- ---
## Description ## Description
<section id="description">提醒一下,这个项目是基于<a href="https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-bcrypt/">Glitch</a>的以下入门项目构建的,或者是从<a href="https://github.com/freeCodeCamp/boilerplate-bcrypt/">GitHub</a>克隆的。由于散列设计为计算密集型,因此建议在服务器上异步执行此操作,以避免在散列时阻止传入连接。所有你需要做的就是异步散列密码是调用<code>bcrypt.hash(myPlaintextPassword, saltRounds, (err, hash) =&gt; { /*Store hash in your db*/ });</code> <hr>将此散列函数添加到服务器(我们已经定义了函数中使用的变量供您使用)并将其记录到控制台以供您查看!此时,您通常会将哈希值保存到数据库中。现在,当您需要确定新输入是否与散列相同时,您只需使用比较函数<code>bcrypt.compare(myPlaintextPassword, hash, (err, res) =&gt; { /*res == true or false*/ });</code> 。在记录完成的哈希并将“res”记录到比较中的控制台之后将其添加到现有哈希函数中因为您需要在调用比较函数之前等待哈希完成。您应该在控制台中看到一个哈希值然后打印出“true”如果您将compare函数中的&#39;myPlaintextPassword&#39;更改为&#39;someOtherPlaintextPassword&#39;那么它应该为false。 <pre> bcrypt.hash&#39;passw0rd&#39;13错误哈希=&gt; { <section id='description'>
的console.log散列; //$2a$12$Y.PHPE15wR25qrrtgGkiYe2sXo98cjuMCG1YwSI5rJW1DSJp0gEYS 温馨提醒,本项目在 <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-bcrypt/'>这个 Glitch 项目</a> 的基础上进行开发。你也可以从 <a href='https://github.com/freeCodeCamp/boilerplate-bcrypt/'> GitHub </a>上克隆。
bcrypt.compare&#39;passw0rd&#39;hasherrres=&gt; { 哈希会占用很大计算机资源并且会耗费比较多时间,比较推荐的做法是用异步的方法用调用哈希算法这样就不会阻挡其他的访问了。异步调用哈希方法非常简单,只需要 <code>bcrypt.hash(myPlaintextPassword, saltRounds, (err, hash) => { /*Store hash in your db*/ });</code>
的console.logRES; //真正
}; ```js
}; </pre>当您认为自己已经做对时,请提交您的页面。 </section> bcrypt.hash(myPlaintextPassword, saltRounds, (err, hash) => {
/*Store hash in your db*/
});
```
</section>
## Instructions ## Instructions
<section id="instructions"> <section id='instructions'>
把这段哈希方法添加到你的服务器(我们已经定义好这个方法的变量给你直接使用了) 然后输入到控制台! 完成之后你通常需要把哈希过的值保存到数据库。
当你需要对比用户输入的值是否和之前哈希过的值一样的时候,你只需要调用对比函数 <code>bcrypt.compare(myPlaintextPassword, hash, (err, res) => { /*res == true or false*/ });</code>. 把这个添加到你已有的哈希方法(你需要等哈希完成之后才能调用对比方法) 在你输入哈希过的值之后在对比方法里面输入 'res' 到控制台. 你会看到一个哈希值和 ``true`` 被打印出来。如果你在对比方法里面把 'myPlaintextPassword' 改变成 'someOtherPlaintextPassword' 那么应该会输出 ``false``
```js
bcrypt.compare(myPlaintextPassword, hash, (err, res) => {
/*res == true or false*/
});
```
当控制台打印哈希完成并且在对比的 console 里打印 res 后,将其添加到现有的哈希函数中(因为要等待哈希完成才能调用 compare 函数)。 控制台中应该打印一个哈希,然后打印 “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
});
});
```
提交页面当你觉得已经完成的时候。
</section> </section>
## Tests ## Tests
@ -23,7 +51,7 @@ localeTitle: 哈希和异步比较密码
```yml ```yml
tests: tests:
- text: 异步哈希生成并正确比较 - text: 异步生成哈希并正确地对比
testString: getUserInput => $.get(getUserInput('url')+ '/_api/server.js') .then(data => { assert.match(data, /START_ASYNC[^]*bcrypt.hash.*myPlaintextPassword( |),( |)saltRounds( |),( |).*err( |),( |)hash[^]*END_ASYNC/gi, 'You should call bcrypt.hash on myPlaintextPassword and saltRounds and handle err and hash as a result in the callback'); assert.match(data, /START_ASYNC[^]*bcrypt.hash[^]*bcrypt.compare.*myPlaintextPassword( |),( |)hash( |),( |).*err( |),( |)res[^]*}[^]*}[^]*END_ASYNC/gi, 'Nested within the hash function should be the compare function comparing myPlaintextPassword to hash'); }, xhr => { throw new Error(xhr.statusText); }) testString: getUserInput => $.get(getUserInput('url')+ '/_api/server.js') .then(data => { assert.match(data, /START_ASYNC[^]*bcrypt.hash.*myPlaintextPassword( |),( |)saltRounds( |),( |).*err( |),( |)hash[^]*END_ASYNC/gi, 'You should call bcrypt.hash on myPlaintextPassword and saltRounds and handle err and hash as a result in the callback'); assert.match(data, /START_ASYNC[^]*bcrypt.hash[^]*bcrypt.compare.*myPlaintextPassword( |),( |)hash( |),( |).*err( |),( |)res[^]*}[^]*}[^]*END_ASYNC/gi, 'Nested within the hash function should be the compare function comparing myPlaintextPassword to hash'); }, xhr => { throw new Error(xhr.statusText); })
``` ```
@ -39,6 +67,11 @@ tests:
<section id='solution'> <section id='solution'>
```js ```js
// solution required /**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
``` ```
</section> </section>

View File

@ -2,15 +2,34 @@
id: 58a25bcff9fc0f352b528e7e id: 58a25bcff9fc0f352b528e7e
title: Hash and Compare Passwords Synchronously title: Hash and Compare Passwords Synchronously
challengeType: 2 challengeType: 2
videoUrl: '' isHidden: false
localeTitle: 哈希并同步比较密码 forumTopicId: 301579
localeTitle: 同步哈希和比较密码
--- ---
## Description ## Description
<section id="description">提醒一下,这个项目是基于<a href="https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-bcrypt/">Glitch</a>的以下入门项目构建的,或者是从<a href="https://github.com/freeCodeCamp/boilerplate-bcrypt/">GitHub</a>克隆的。同步散列也很容易,但如果使用服务器端成本高或经常进行散列会导致延迟。使用此方法进行散列与调用<code>var hash = bcrypt.hashSync(myPlaintextPassword, saltRounds);</code> <hr>将此散列方法添加到代码中,然后将结果记录到控制台。同样,使用的变量已在服务器中定义,因此您无需调整它们。您可能会注意到即使您使用与异步函数相同的密码进行哈希处理,控制台中的结果也不同 - 这是由于每次哈希值随机生成如第三个哈希字符串中的前22个字符所示。现在将密码输入与新的同步散列进行比较您将使用compareSync方法 <code>var result = bcrypt.compareSync(myPlaintextPassword, hash);</code>结果是布尔值true或false。添加此功能并登录控制台结果以查看其是否正常工作。当您认为自己已经做对时请提交您的页面。如果您在这些挑战期间遇到错误可以在<a href="https://gist.github.com/JosephLivengood/9a2698fb63e42d9d8b4b84235c08b4c4">此处</a>查看示例完成的代码。 </section> <section id='description'>
温馨提醒,本项目在 <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-bcrypt/'>这个 Glitch 项目</a> 的基础上进行开发。你也可以从 <a href='https://github.com/freeCodeCamp/boilerplate-bcrypt/'> GitHub </a>上克隆。
同步哈希也是非常简单的,但是会造成延迟特别是在哈希计算量大并且次数多的情况下。同步进行哈希是通过调用
```js
var hash = bcrypt.hashSync(myPlaintextPassword, saltRounds);
```
<hr>把同步哈希添加到你的代码并输入到控制台和之前一样需要用到的变量已经提前定义好你不需要做任何改动。你可能已经注意到即使你是用异步的方式哈希同一个密码结果也是不一样的。这是因为每次哈希的盐都是随机生成的你可以通过第三个哈希字符串的头22的字符来验证。
当你需要对比用户输入的值, 你只需要使用 compareSync 方法:
```js
var result = bcrypt.compareSync(myPlaintextPassword, hash);
```
返回的结果为 ``true`` 或者 ``false``。
</section>
## Instructions ## Instructions
<section id="instructions"> <section id='instructions'>
添加这个方法并输出把控制台来验证同步哈希已经成功了。
提交页面当你觉得已经完成的时候。如果你遇到任何错误,你可以参考这个<a href='https://gist.github.com/JosephLivengood/9a2698fb63e42d9d8b4b84235c08b4c4'>链接</a>中已经完成的代码。
</section> </section>
## Tests ## Tests
@ -18,7 +37,7 @@ localeTitle: 哈希并同步比较密码
```yml ```yml
tests: tests:
- text: 同步哈希生成并正确比较 - text: 同步生成哈希并正确地对比
testString: getUserInput => $.get(getUserInput('url')+ '/_api/server.js') .then(data => { assert.match(data, /START_SYNC[^]*hash.*=.*bcrypt.hashSync.*myPlaintextPassword( |),( |)saltRounds[^]*END_SYNC/gi, 'You should call bcrypt.hashSync on myPlaintextPassword with saltRounds'); assert.match(data, /START_SYNC[^]*result.*=.*bcrypt.compareSync.*myPlaintextPassword( |),( |)hash[^]*END_SYNC/gi, 'You should call bcrypt.compareSync on myPlaintextPassword with the hash generated in the last line'); }, xhr => { throw new Error(xhr.statusText); }) testString: getUserInput => $.get(getUserInput('url')+ '/_api/server.js') .then(data => { assert.match(data, /START_SYNC[^]*hash.*=.*bcrypt.hashSync.*myPlaintextPassword( |),( |)saltRounds[^]*END_SYNC/gi, 'You should call bcrypt.hashSync on myPlaintextPassword with saltRounds'); assert.match(data, /START_SYNC[^]*result.*=.*bcrypt.compareSync.*myPlaintextPassword( |),( |)hash[^]*END_SYNC/gi, 'You should call bcrypt.compareSync on myPlaintextPassword with the hash generated in the last line'); }, xhr => { throw new Error(xhr.statusText); })
``` ```
@ -34,6 +53,11 @@ tests:
<section id='solution'> <section id='solution'>
```js ```js
// solution required /**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
``` ```
</section> </section>

View File

@ -2,15 +2,20 @@
id: 587d8247367417b2b2512c37 id: 587d8247367417b2b2512c37
title: Hide Potentially Dangerous Information Using helmet.hidePoweredBy() title: Hide Potentially Dangerous Information Using helmet.hidePoweredBy()
challengeType: 2 challengeType: 2
videoUrl: '' isHidden: false
localeTitle: 使用helmet.hidePoweredBy隐藏潜在的危险信息 forumTopicId: 301580
localeTitle: 使用 helmet.hidePoweredBy() 隐藏潜在的危险信息
--- ---
## Description ## Description
<section id="description">提醒一下,这个项目是基于<a href="https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-infosec/">Glitch</a>的以下入门项目构建的,或者是从<a href="https://github.com/freeCodeCamp/boilerplate-infosec/">GitHub</a>克隆的。如果黑客看到您的网站由Express提供支持他们可以利用Express / Node中的已知漏洞。 X-Powered-ByExpress默认发送来自Express的每个请求。 helmet.hidePoweredBy中间件将删除X-Powered-By标头。您还可以将标头显式设置为其他内容以便让人们离开。例如app.usehelmet.hidePoweredBy{setTo&#39;PHP 4.2.0&#39;} </section> <section id='description'>
温馨提醒,本项目在 <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-infosec/'>这个 Glitch 项目</a> 的基础上进行开发。你也可以从 <a href='https://github.com/freeCodeCamp/boilerplate-infosec/'>GitHub</a> 上克隆。
如果黑客发现你的网站是用 Express 搭建的,那么他们就可以利用 Express 或 Node 现存的漏洞来攻击你的网站。<code>X-Powered-By: Express</code> 默认情况下会被添加到所有响应的头部。不过 helmet.hidePoweredBy() 中间件可以帮你移除 X-Powered-By 头。你甚至可以把头设置成其它的值。 如 <code>app.use(helmet.hidePoweredBy({ setTo: 'PHP 4.2.0' }))</code>
</section>
## Instructions ## Instructions
<section id="instructions"> <section id='instructions'>
</section> </section>
## Tests ## Tests
@ -18,7 +23,7 @@ localeTitle: 使用helmet.hidePoweredBy隐藏潜在的危险信息
```yml ```yml
tests: tests:
- text: helmet.hidePoweredBy中间件应正确安装 - text: helmet.hidePoweredBy() 中间件应该被正确加载
testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { assert.include(data.appStack, 'hidePoweredBy'); assert.notEqual(data.headers['x-powered-by'], 'Express')}, xhr => { throw new Error(xhr.responseText); }) testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { assert.include(data.appStack, 'hidePoweredBy'); assert.notEqual(data.headers['x-powered-by'], 'Express')}, xhr => { throw new Error(xhr.responseText); })
``` ```
@ -34,6 +39,11 @@ tests:
<section id='solution'> <section id='solution'>
```js ```js
// solution required /**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
``` ```
</section> </section>

View File

@ -2,15 +2,20 @@
id: 587d8247367417b2b2512c36 id: 587d8247367417b2b2512c36
title: Install and Require Helmet title: Install and Require Helmet
challengeType: 2 challengeType: 2
videoUrl: '' isHidden: false
localeTitle: 安装并需要头盔 forumTopicId: 301581
localeTitle: 安装和引入 Helmet
--- ---
## Description ## Description
<section id="description">提醒一下,这个项目是基于<a href="https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-infosec/">Glitch</a>的以下入门项目构建的,或者是从<a href="https://github.com/freeCodeCamp/boilerplate-infosec/">GitHub</a>克隆的。 Helmet通过设置各种HTTP标头来帮助您保护Express应用程序。安装包然后需要它。 </section> <section id='description'>
注意,本项目在 <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-infosec/'>这个 Glitch 项目</a> 的基础上进行开发。你也可以从 <a href='https://github.com/freeCodeCamp/boilerplate-infosec/'>GitHub</a> 上克隆。
Helmet 通过配置不同的 HTTP 头部信息来使你的 Express 应用更加安全。
</section>
## Instructions ## Instructions
<section id="instructions"> <section id='instructions'>
安装,并引入 Helmet 这个包。
</section> </section>
## Tests ## Tests
@ -18,7 +23,7 @@ localeTitle: 安装并需要头盔
```yml ```yml
tests: tests:
- text: “helmet”依赖应该在package.json中 - text: "package.json 文件应该有 'helmet' 这个依赖包"
testString: getUserInput => $.get(getUserInput('url') + '/_api/package.json').then(data => { var packJson = JSON.parse(data); assert.property(packJson.dependencies, 'helmet'); }, xhr => { throw new Error(xhr.responseText); }) testString: getUserInput => $.get(getUserInput('url') + '/_api/package.json').then(data => { var packJson = JSON.parse(data); assert.property(packJson.dependencies, 'helmet'); }, xhr => { throw new Error(xhr.responseText); })
``` ```
@ -34,6 +39,11 @@ tests:
<section id='solution'> <section id='solution'>
```js ```js
// solution required /**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
``` ```
</section> </section>

View File

@ -2,15 +2,21 @@
id: 587d8247367417b2b2512c38 id: 587d8247367417b2b2512c38
title: Mitigate the Risk of Clickjacking with helmet.frameguard() title: Mitigate the Risk of Clickjacking with helmet.frameguard()
challengeType: 2 challengeType: 2
videoUrl: '' isHidden: false
localeTitle: 使用helmet.frameguard降低点击劫持的风险 forumTopicId: 301582
localeTitle: 使用 helmet.frameguard() 降低点击劫持的风险
--- ---
## Description ## Description
<section id="description">提醒一下,这个项目是基于<a href="https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-infosec/">Glitch</a>的以下入门项目构建的,或者是从<a href="https://github.com/freeCodeCamp/boilerplate-infosec/">GitHub</a>克隆的。未经您的同意,您的页面可以放在<code>&lt;frame&gt;</code><code>&lt;iframe&gt;</code> 。除其他外这可能导致点击劫持攻击。点击劫持是一种欺骗用户与不同于用户认为的页面进行交互的技术。这可以通过iframing在恶意上下文中执行您的页面获得。在这种情况下黑客可以在页面上放置隐藏层。隐藏按钮可用于运行错误的脚本。此中间件设置X-Frame-Options标头。它限制了谁可以将您的网站放在框架中。它有三种模式DENYSAMEORIGIN和ALLOW-FROM。我们不需要我们的应用程序框架。您应该使用配置对象<code>{action: &#39;deny&#39;}</code>传递的<code>helmet.frameguard()</code></section> <section id='description'>
温馨提醒,本项目在 <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-infosec/'>这个 Glitch 项目</a> 的基础上进行开发。你也可以从 <a href='https://github.com/freeCodeCamp/boilerplate-infosec/'>GitHub</a> 上克隆。
黑客可能会不经过你的允许,把你的页面嵌套在 <code><frame></code> 或者 <code><iframe></code> 标签里,用以实现“点击劫持”。点击劫持是一种视觉上的欺骗手段,让用户误以为自己在与所看到的网页交互。通过 iframe黑客可以在你的页面上添加一个透明的“层”然后把自己的恶意代码放在一个用户看不到的按钮中。这样一来你网站的执行环境就被黑客设置成了他想要的效果。helmet 中间件可以设置 X-Frame-Options 这个头部。这样就能限制谁可以通过 iframe 引入你的页面了。 有三个模式可供配置: DENY, SAMEORIGIN, 和 ALLOW-FROM.
我们的应用不需要被 iframe 引用。
</section>
## Instructions ## Instructions
<section id="instructions"> <section id='instructions'>
你可以调用 <code>helmet.frameguard()</code> 这个方法,然后传入配置对象 <code>{action: 'deny'}</code> 就可以了。
</section> </section>
## Tests ## Tests
@ -18,9 +24,9 @@ localeTitle: 使用helmet.frameguard降低点击劫持的风险
```yml ```yml
tests: tests:
- text: helmet.frameguard中间件应正确安装 - text: helmet.frameguard() 中间件应该被正确加载
testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { assert.include(data.appStack, 'frameguard', 'helmet.frameguard() middleware is not mounted correctly'); }, xhr => { throw new Error(xhr.responseText); }) testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { assert.include(data.appStack, 'frameguard', 'helmet.frameguard() middleware is not mounted correctly'); }, xhr => { throw new Error(xhr.responseText); })
- text: helmet.frameguard'action'应该设置为'DENY' - text: '<code>helmet.frameguard()</code> 中的 <code>action</code> 属性的值应该为 "DENY"'
testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { assert.property(data.headers, 'x-frame-options'); assert.equal(data.headers['x-frame-options'], 'DENY');}, xhr => { throw new Error(xhr.responseText); }) testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { assert.property(data.headers, 'x-frame-options'); assert.equal(data.headers['x-frame-options'], 'DENY');}, xhr => { throw new Error(xhr.responseText); })
``` ```
@ -36,6 +42,11 @@ tests:
<section id='solution'> <section id='solution'>
```js ```js
// solution required /**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
``` ```
</section> </section>

View File

@ -2,15 +2,24 @@
id: 587d8247367417b2b2512c39 id: 587d8247367417b2b2512c39
title: Mitigate the Risk of Cross Site Scripting (XSS) Attacks with helmet.xssFilter() title: Mitigate the Risk of Cross Site Scripting (XSS) Attacks with helmet.xssFilter()
challengeType: 2 challengeType: 2
videoUrl: '' isHidden: false
localeTitle: 使用helmet.xssFilter降低跨站点脚本XSS攻击的风险 forumTopicId: 301583
localeTitle: 使用 helmet.xssFilter() 降低跨站点脚本XSS攻击的风险
--- ---
## Description ## Description
<section id="description">提醒一下,这个项目是基于<a href="https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-infosec/">Glitch</a>的以下入门项目构建的,或者是从<a href="https://github.com/freeCodeCamp/boilerplate-infosec/">GitHub</a>克隆的。跨站点脚本XSS是一种常见的攻击类型其中恶意脚本被注入易受攻击的页面目的是窃取会话cookie或密码等敏感数据。降低XSS攻击风险的基本规则很简单“绝不信任用户的输入”。作为开发人员您应该始终清理来自外部的所有输入。这包括来自表单GET查询URL甚至来自POST主体的数据。消毒意味着您应该找到并编码可能有危险的字符例如&lt;&gt;。现代浏览器可以通过采用更好的软件策略来帮助降低风险。通常这些都可以通过http标头进行配置。 X-XSS-Protection HTTP标头是一种基本保护。浏览器使用启发式过滤器检测潜在的注入脚本。如果启用了标头则浏览器会更改脚本代码从而中和它。它仍然有限的支持。 </section> <section id='description'>
温馨提醒,本项目在 <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-infosec/'>这个 Glitch 项目</a> 的基础上进行开发。你也可以从 <a href='https://github.com/freeCodeCamp/boilerplate-infosec/'>GitHub</a> 上克隆。
跨站脚本攻击 (XSS) 是一种比较常见的攻击手段,通过给页面注入恶意脚本来获取用户的 session, 密码等信息。
防止这类型的攻击也非常简单:“永远不要相信用户的输入”。 作为一名开发人员你一定要对所有外部的输入进行审查其中包括来自表单GET 请求POST 请求主体的内容。审核就是说你需要查找并给有潜在风险的字符进行编码,例如:<, >.
现代浏览器已经有非常好的软件策略来应对着类型问题。通常是通过配置 http 头部来实现.
X-XSS-Protection HTTP 头部是一个基本的防护。浏览器通过启发式过滤法则来检测有潜在风险的注入脚本,这是有如果这个头部被启用了,浏览器就能改成脚本里面的代码从而使恶意代码不再生效。
但是浏览器对这个功能的支持有限。
</section>
## Instructions ## Instructions
<section id="instructions"> <section id='instructions'>
</section> </section>
## Tests ## Tests
@ -18,7 +27,7 @@ localeTitle: 使用helmet.xssFilter降低跨站点脚本XSS攻击的
```yml ```yml
tests: tests:
- text: helmet.xssFilter()中间件应该正确安装 - text: helmet.xssFilter() 应该正确地加载
testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { assert.include(data.appStack, 'xXssProtection'); assert.property(data.headers, 'x-xss-protection'); }, xhr => { throw new Error(xhr.responseText); }) testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { assert.include(data.appStack, 'xXssProtection'); assert.property(data.headers, 'x-xss-protection'); }, xhr => { throw new Error(xhr.responseText); })
``` ```
@ -34,6 +43,11 @@ tests:
<section id='solution'> <section id='solution'>
```js ```js
// solution required /**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
``` ```
</section> </section>

View File

@ -2,15 +2,20 @@
id: 587d8248367417b2b2512c3b id: 587d8248367417b2b2512c3b
title: Prevent IE from Opening Untrusted HTML with helmet.ieNoOpen() title: Prevent IE from Opening Untrusted HTML with helmet.ieNoOpen()
challengeType: 2 challengeType: 2
videoUrl: '' isHidden: false
localeTitle: 使用helmet.ieNoOpen阻止IE打开不受信任的HTML forumTopicId: 301584
localeTitle: 使用 helment.ieNoOpen() 防止 IE 打开不受信任的 HTML
--- ---
## Description ## Description
<section id="description">提醒一下,这个项目是基于<a href="https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-infosec/">Glitch</a>的以下入门项目构建的,或者是从<a href="https://github.com/freeCodeCamp/boilerplate-infosec/">GitHub</a>克隆的。某些Web应用程序将提供不受信任的HTML以供下载。默认情况下某些版本的Internet Explorer会在您的站点上下文中打开这些HTML文件。这意味着不受信任的HTML页面可能会在您的页面上下文中开始做坏事。此中间件将X-Download-Options标头设置为noopen。这将阻止IE用户在受信任站点的上下文中执行下载。 </section> <section id='description'>
温馨提醒,本项目在 <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-infosec/'>这个 Glitch 项目</a> 的基础上进行开发。你也可以从 <a href='https://github.com/freeCodeCamp/boilerplate-infosec/'>GitHub</a> 上克隆。
有些网站会下载不安全的 HTML 文件,某些版本的 IE 默认情况下还会在你网站的作用域下打开这些 HTML 文件。换句话说,这些不安全的 HTML 页面可以在你的网站做恶意行为。我们可以通过中间件来设置 ``X-Download-Options`` 头部为 ``noopen``。这样就可以防治 IE 在不信任的网站下执行下载的文件。
</section>
## Instructions ## Instructions
<section id="instructions"> <section id='instructions'>
</section> </section>
## Tests ## Tests
@ -18,7 +23,7 @@ localeTitle: 使用helmet.ieNoOpen阻止IE打开不受信任的HTML
```yml ```yml
tests: tests:
- text: helmet.ieNoOpen中间件应正确安装 - text: helmet.ieNoOpen() 中间件应该被正确加载
testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { assert.include(data.appStack, 'ienoopen'); assert.equal(data.headers['x-download-options'], 'noopen'); }, xhr => { throw new Error(xhr.responseText); }) testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { assert.include(data.appStack, 'ienoopen'); assert.equal(data.headers['x-download-options'], 'noopen'); }, xhr => { throw new Error(xhr.responseText); })
``` ```
@ -34,6 +39,11 @@ tests:
<section id='solution'> <section id='solution'>
```js ```js
// solution required /**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
``` ```
</section> </section>

View File

@ -2,17 +2,22 @@
id: 587d8249367417b2b2512c3f id: 587d8249367417b2b2512c3f
title: Set a Content Security Policy with helmet.contentSecurityPolicy() title: Set a Content Security Policy with helmet.contentSecurityPolicy()
challengeType: 2 challengeType: 2
videoUrl: '' isHidden: false
localeTitle: 使用helmet.contentSecurityPolicy设置内容安全策略 forumTopicId: 301585
localeTitle: 使用 helment.contentSecurityPolicy() 设置内容安全策略
--- ---
## Description ## Description
<section id="description">提醒一下,这个项目是基于<a href="https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-infosec/">Glitch</a>的以下入门项目构建的,或者是从<a href="https://github.com/freeCodeCamp/boilerplate-infosec/">GitHub</a>克隆的。这一挑战突出了一个有希望的新防御它可以显着降低现代浏览器中许多类型攻击的风险和影响。通过设置和配置内容安全策略您可以防止在页面中无意中注入任何内容。这样可以保护您的应用免受XSS漏洞不受欢迎的跟踪恶意帧等攻击。 CSP通过定义受信任的内容源的白名单来工作。您可以为网页可能需要的每种资源脚本样式表字体框架媒体等等配置它们。有多个指令可用因此网站所有者可以拥有精细控制。有关详细信息请参阅HTML 5 RocksKeyCDN。不幸的是旧版浏览器不支持CSP。默认情况下指令是全开的因此将defaultSrc指令设置为回退非常重要。 Helmet支持defaultSrc和default-src命名样式。回退适用于大多数未指定的指令。在本练习中使用helmet.contentSecurityPolicy并将其配置为将defaultSrc指令设置为["self"]允许的源列表必须在数组中以便默认只信任您的网站地址。同时设置scriptSrc指令以便允许从您的网站和域"trusted-cdn.com"下载脚本。提示:在"&#39;self&#39;"关键字中,单引号是关键字本身的一部分,因此需要用双引号括起来才能生效。 </section> <section id='description'>
温馨提醒,本项目在 <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-infosec/'>这个 Glitch 项目</a> 的基础上进行开发。你也可以从 <a href='https://github.com/freeCodeCamp/boilerplate-infosec/'>GitHub</a> 上克隆。
这个挑战重点讨论一种现代浏览器中有效并且能大幅度减轻安全风险和很多种类型常见攻击的安全防护。通过配置内容安全策略你可以防止很多类型的脚本恶意注入。这会让你的应用远离 XSS 漏洞、恶意追踪、恶意 frames 和很多很多其他攻击。CSP 通过配置资源白名单来避免这些问题。 你可以给任何一种类型的页面资源 (脚本、样式文件、字体、frames、媒体文件等等等做这个配置它支持很多指令所以网站管理员可以做细致的控制。更多详情请参考 HTML 5 RocksKeyCDN。不幸的是。一些旧的浏览器不支持 CSP。
默认的指令很容易受到攻击, 所以设置 defaultSrc 指令作为降级方案很重要。Helmet 同时支持 defaultSrc 和 default-src 命名规范。降级方案可以被应用在大部分指令上。
</section>
## Instructions ## Instructions
<section id="instructions"> <section id='instructions'>
练习中,使用<code>helmet.contentSecurityPolicy()</code>,并将其配置为将<code>defaultSrc指令</code>设置为<code>["self"]</code>(允许的列表) 来源必须位于一个数组中,以便默认情况下仅信任您的网站地址。 还设置<code>scriptSrc</code>指令,以便您允许从您的网站以及"trusted-cdn.com"域下载脚本。 这个练习中,我们使用 helmet.contentSecurityPolicy(),并配置 defaultSrc 指令为 ["self"] (允许的资源列表必须在一个数组当中), 这样做表示只信任自己的网站域名。另外配置 scriptSrc 指令可以限制脚本只能本网站域名上或者信任的域名‘trusted-cdn.com’上下载
提示:在<code>self</code>关键字中,单引号是关键字本身的一部分,因此需要使用双引号将其括起来才能起作用 提示: 在 "'self'" 关键词, 单引号是关键的一部分, 所以你应该用双引号来包起它才能正常工作
</section> </section>
## Tests ## Tests
@ -20,9 +25,9 @@ localeTitle: 使用helmet.contentSecurityPolicy设置内容安全策略
```yml ```yml
tests: tests:
- text: helmet.csp()中间件应该正确安装。 - text: helmet.csp() 中间件应该正确加载
testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { assert.include(data.appStack, 'csp'); }, xhr => { throw new Error(xhr.responseText); }) testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { assert.include(data.appStack, 'csp'); }, xhr => { throw new Error(xhr.responseText); })
- text: 你的csp配置不正确 defaultSrc应该是["self"]而scriptSrc应该是["self""trusted-cdn.com"] - text: '你的 csp 配置不正确. defaultSrc 应该是 [""self""] 并且scriptSrc 应该是 [""self"", "trusted-cdn.com"]'
testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { var cspHeader = Object.keys(data.headers).filter(function(k){ return k === 'content-security-policy' || k === 'x-webkit-csp' || k === 'x-content-security-policy' })[0]; assert.equal(data.headers[cspHeader], "default-src 'self'; script-src 'self' trusted-cdn.com"); }, xhr => { throw new Error(xhr.responseText); }) testString: getUserInput => $.get(getUserInput('url') + '/_api/app-info').then(data => { var cspHeader = Object.keys(data.headers).filter(function(k){ return k === 'content-security-policy' || k === 'x-webkit-csp' || k === 'x-content-security-policy' })[0]; assert.equal(data.headers[cspHeader], "default-src 'self'; script-src 'self' trusted-cdn.com"); }, xhr => { throw new Error(xhr.responseText); })
``` ```
@ -38,6 +43,11 @@ tests:
<section id='solution'> <section id='solution'>
```js ```js
// solution required /**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
``` ```
</section> </section>

View File

@ -2,15 +2,22 @@
id: 58a25bcef9fc0f352b528e7c id: 58a25bcef9fc0f352b528e7c
title: Understand BCrypt Hashes title: Understand BCrypt Hashes
challengeType: 2 challengeType: 2
videoUrl: '' isHidden: false
localeTitle: 了解BCrypt Hashes forumTopicId: 301586
localeTitle: 了解加密哈希
--- ---
## Description ## Description
<section id="description">提醒一下,这个项目是基于<a href="https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-bcrypt/">Glitch</a>的以下入门项目构建的,或者是从<a href="https://github.com/freeCodeCamp/boilerplate-bcrypt/">GitHub</a>克隆的。 BCrypt哈希非常安全。哈希基本上是原始数据的指纹 - 始终是唯一的。这是通过将原始数据馈送到算法中并返回固定长度的结果来实现的。为了进一步使这个过程复杂化并使其更安全,您还可以<em>加入哈希</em>值。对哈希进行盐析涉及在哈希处理之前将随机数据添加到原始数据,这使得更难破解哈希。 BCrypt哈希总是看起来像<code>$2a$13$ZyprE5MRw2Q3WpNOGZWGbeG7ADUre1Q8QO.uUUtcbqloU0yvzavOm</code>确实有一个结构。第一小部分数据<code>$2a</code>定义了使用何种哈希算法。下一部分<code>$13</code>定义了<em>成本</em> 。成本是计算哈希值所需的功率。它具有2 ^成本的对数标度并确定通过散列算法放置数据的次数。例如以10为代价您可以在普通计算机上每秒散列10个密码但是每个散列需要花费3秒才能进行散乱...并且需要花费更多时间成本为31需要多天才能完成哈希。目前12的成本被认为是非常安全的。哈希<code>$ZyprE5MRw2Q3WpNOGZWGbeG7ADUre1Q8QO.uUUtcbqloU0yvzavOm</code>的最后一部分看起来像<code>$ZyprE5MRw2Q3WpNOGZWGbeG7ADUre1Q8QO.uUUtcbqloU0yvzavOm</code>数字句号和字母但它实际上是两条独立的信息。前22个字符是纯文本的盐其余的是哈希密码 <hr>要开始使用BCrypt请将其作为项目中的依赖项添加并在服务器中将其命名为“bcrypt”。当您认为自己已经做对时请提交您的页面。 </section> <section id='description'>
温馨提醒,本项目在 <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-bcrypt/'>这个 Glitch 项目</a> 的基础上进行开发。你也可以从 <a href='https://github.com/freeCodeCamp/boilerplate-bcrypt/'> GitHub </a>上克隆。
BCrypt 哈希非常安全. 哈希其实就是原数据的加密形式,非常安全,这通过把原始数据放进哈希算法然后返回固定长度的字符串实现。为了让这个过程更复杂跟安全,你还可以加你的哈希添加 <em></em>。加盐其实就是给在哈希算法工作前给源数据添加随机的字符串数据,这会让破解哈希更加复杂
BCrypt 看起来像这样子 <code>$2a$13$ZyprE5MRw2Q3WpNOGZWGbeG7ADUre1Q8QO.uUUtcbqloU0yvzavOm</code>,它遵循固定的结构. 前面一小节 <code>$2a</code> 说明了该哈希采用什么算法。下一部分 <code>$13</code> 定义了 <em>代价</em>. 代价就是用多少计算资源来生成哈希。 它的对数刻度是 2^cost 它决定了数据被放入哈希算法多少次。举个例子如果代价为10也就是说你能够在一个普通的计算机上每秒钟哈希10个密码。然而如果代价为15那每个哈希都要3秒钟再举例子如果代价是31at a cost of 31那每次哈希能耗费好几天。通常代价为12就已经足够安全。哈希的最后一部分 <code>$ZyprE5MRw2Q3WpNOGZWGbeG7ADUre1Q8QO.uUUtcbqloU0yvzavOm</code>, 看起来像随机字符、句号、字母组成的随机字符串。但实际上它有两部分内容。前面22个字符就是纯文本的盐剩下的就是加密过的密码
</section>
## Instructions ## Instructions
<section id="instructions"> <section id='instructions'>
要开始使用 BCrypt, 只需添加到你的依赖列表,然后在你的服务器引入 'bcrypt'
在你觉得已经完成的时候提交页面。
</section> </section>
## Tests ## Tests
@ -18,9 +25,9 @@ localeTitle: 了解BCrypt Hashes
```yml ```yml
tests: tests:
- text: BCrypt是一个依赖 - text: BCyrpt 已被添加到依赖列表
testString: getUserInput => $.get(getUserInput('url')+ '/_api/package.json') .then(data => { var packJson = JSON.parse(data); assert.property(packJson.dependencies, 'bcrypt', 'Your project should list "bcrypt" as a dependency'); }, xhr => { throw new Error(xhr.statusText); }) testString: getUserInput => $.get(getUserInput('url')+ '/_api/package.json') .then(data => { var packJson = JSON.parse(data); assert.property(packJson.dependencies, 'bcrypt', 'Your project should list "bcrypt" as a dependency'); }, xhr => { throw new Error(xhr.statusText); })
- text: 已经适当地要求BCrypt - text: BCrypt 已经被正确引入
testString: getUserInput => $.get(getUserInput('url')+ '/_api/server.js').then(data => {assert.match(data, /bcrypt.*=.*require.*('|")bcrypt('|")/gi, 'You should correctly require and instantiate socket.io as io.');}, xhr => { throw new Error(xhr.statusText); }) testString: getUserInput => $.get(getUserInput('url')+ '/_api/server.js').then(data => {assert.match(data, /bcrypt.*=.*require.*('|")bcrypt('|")/gi, 'You should correctly require and instantiate socket.io as io.');}, xhr => { throw new Error(xhr.statusText); })
``` ```
@ -36,6 +43,11 @@ tests:
<section id='solution'> <section id='solution'>
```js ```js
// solution required /**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
``` ```
</section> </section>