fix: QA/Infosec update and python to chinese
This commit is contained in:
committed by
Mrugesh Mohapatra
parent
2c78402837
commit
1cfa09adc4
@@ -0,0 +1,62 @@
|
||||
---
|
||||
id: 587d824a367417b2b2512c45
|
||||
title: Anonymous Message Board
|
||||
challengeType: 4
|
||||
isRequired: true
|
||||
videoUrl: ''
|
||||
localeTitle: 匿名留言板
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">构建一个功能类似于此的完整堆栈JavaScript应用程序: <a href='https://spiky-well-vein.glitch.me/' target='_blank'>https://spiky-well-vein.glitch.me/</a> 。在这个项目上工作将涉及您在我们的入门项目上在Glitch上编写代码。完成此项目后,您可以将公共故障网址(到应用程序的主页)复制到此屏幕进行测试!您可以选择在另一个平台上编写项目,但必须公开显示我们的测试。使用<a href="https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-project-messageboard/">此链接</a>在Glitch上启动此项目或在GitHub上克隆<a href="https://github.com/freeCodeCamp/boilerplate-project-messageboard/">此存储库</a> !如果您使用Glitch,请记住将项目链接保存到安全的地方! </section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 只允许您的网站加载到您自己网页上的iFrame中。
|
||||
testString: ''
|
||||
- text: 不允许DNS预取。
|
||||
testString: ''
|
||||
- text: 只允许您的网站为您自己的网页发送引荐来源。
|
||||
testString: ''
|
||||
- text: '我可以通过将表单数据文本和deletepassword_传递给/api/threads/ {board}将一个帖子发布到一个特定的留言板。(推荐res.redirect到电路板页面/ b / {board})保存的至少是_id,text ,createdon_(日期和时间),bumpedon_(日期和时间,与created_on相同),报告(布尔值),deletepassword_和回复(数组)。'
|
||||
testString: ''
|
||||
- text: '我可以通过将表单数据文本,deletepassword_和threadid_传递给/ api / replies / {board}来对特定板上的线程发送回复,并且还会将bumped_on日期更新到注释日期。(推荐res.redirect到thread page / b / {board} / {thread_id})在线程的回复数组中将保存_id,text,createdon_,deletepassword_,并报告。'
|
||||
testString: ''
|
||||
- text: '我可以在电路板上获取最近10个凸起线程的数组,其中最近只有来自/ api / threads / {board}的3个回复。 report和deletepasswords_字段不会发送到客户端。'
|
||||
testString: ''
|
||||
- text: '我可以使用/ api / replies / {board}的所有回复获取整个帖子吗?thread_id = {thread_id}。同样隐藏客户端应该看到的相同字段。'
|
||||
testString: ''
|
||||
- text: '如果我向/ api / threads / {board}发送DELETE请求并传递threadid_&deletepassword_,我可以完全删除一个线程。 (文字回复将是“密码不正确”或“成功”)'
|
||||
testString: ''
|
||||
- text: '如果我向/ api / replies / {board}发送DELETE请求并传递threadid_,replyid_和deletepassword_,我可以删除帖子(只是将文本更改为“[已删除]”而不是像线程一样完全删除)。 (文字回复将是“密码不正确”或“成功”)'
|
||||
testString: ''
|
||||
- text: '我可以通过向/ api / threads / {board}发送PUT请求并传递threadid_来报告一个线程并将其报告值更改为true。 (文字回复将是“成功”)'
|
||||
testString: ''
|
||||
- text: '我可以通过向/ api / replies / {board}发送PUT请求并传递threadid_&replyid_来报告回复并将其报告值更改为true。 (文字回复将是“成功”)'
|
||||
testString: ''
|
||||
- text: 完整的功能测试,完全测试路线和通过。
|
||||
testString: ''
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,60 @@
|
||||
---
|
||||
id: 5e46f979ac417301a38fb932
|
||||
title: Port Scanner
|
||||
challengeType: 10
|
||||
isHidden: false
|
||||
isRequired: true
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Create a port scanner using Python.
|
||||
|
||||
You can access <a href='https://repl.it/@freeCodeCamp/fcc-port-scanner' target='_blank'>the full project description and starter code on repl.it</a>.
|
||||
|
||||
After going to that link, fork the project. Once you complete the project based on the instructions in 'README.md', submit your project link below.
|
||||
|
||||
We are still developing the interactive instructional part of the Python curriculum. For now, here are some videos on the freeCodeCamp.org YouTube channel that will teach you some of the Python skills required for this project:
|
||||
<ul>
|
||||
<li>
|
||||
<a href='https://www.freecodecamp.org/news/python-for-everybody/'>Python for Everybody Video Course</a> (14 hours)
|
||||
</li>
|
||||
<li>
|
||||
<a href='https://www.freecodecamp.org/news/learn-python-basics-in-depth-video-course/'>Learn Python Video Course</a> (2 hours)
|
||||
</li>
|
||||
<ul>
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 'It should pass all Python tests.'
|
||||
testString: ''
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```py
|
||||
# Python 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>
|
@@ -0,0 +1,87 @@
|
||||
---
|
||||
id: 5e601c775ac9d0ecd8b94aff
|
||||
title: Secure Real Time Multiplayer Game
|
||||
challengeType: 4
|
||||
isHidden: false
|
||||
isRequired: true
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Develop a 2D real time multiplayer game using the HTML Canvas API and <a href='https://socket.io/' target='_blank'>Socket.io</a> that is functionally similar to this: <a href='https://thread-valley-lipstick.glitch.me/' target='_blank'>https://thread-valley-lipstick.glitch.me/</a>.
|
||||
|
||||
Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but it must be publicly visible for our testing.
|
||||
|
||||
Start this project on Glitch using <a href='https://glitch.com/edit/#!/remix/clone-from-repo?REPO_URL=https://github.com/freeCodeCamp/boilerplate-project-secure-real-time-multiplayer-game/'>this link</a> or clone <a href='https://github.com/freeCodeCamp/boilerplate-project-secure-real-time-multiplayer-game'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: Multiple players can connect to a server and play.
|
||||
testString: ''
|
||||
- text: Each player has an avatar.
|
||||
testString: ''
|
||||
- text: Each player is represented by an object created by the <code>Player</code> class in <code>Player.mjs</code>.
|
||||
testString: ''
|
||||
- text: At a minimum, each player object should contain a unique <code>id</code>, a <code>score</code>, and <code>x</code> and <code>y</code> coordinates representing the player's current position.
|
||||
testString: ''
|
||||
- text: The game has at least one type of collectible item. Complete the <code>Collectible</code> class in <code>Collectible.mjs</code> to implement this.
|
||||
testString: ''
|
||||
- text: At a minimum, each collectible item object created by the <code>Collectible</code> class should contain a unique <code>id</code>, a <code>value</code>, and <code>x</code> and <code>y</code> coordinates representing the item's current position.
|
||||
testString: ''
|
||||
- text: Players can use the WASD and/or arrow keys to move their avatar. Complete the <code>movePlayer</code> method in <code>Player.mjs</code> to implement this.
|
||||
testString: ''
|
||||
- text: |
|
||||
The <code>movePlayer</code> method should accept two arguments: a string of "up", "down", "left", or "right", and a number for the amount of pixels the player's position should change. <code>movePlayer</code> should adjust the <code>x</code> and <code>y</code> coordinates of the player object it's called from.
|
||||
testString: ''
|
||||
- text: The player's score should be used to calculate their rank among the other players. Complete the <code>calculateRank</code> method in the <code>Player</code> class to implement this.
|
||||
testString: ''
|
||||
- text: |
|
||||
The <code>calculateRank</code> method should accept an array of objects representing all connected players and return the string <code>Rank: currentRanking/totalPlayers</code>. For example, in a game with two players, if Player A has a score of 3 and Player B has a score of 5, <code>calculateRank</code> for Player A should return <code>Rank: 2/2</code>.
|
||||
testString: ''
|
||||
- text: Players can collide with a collectible item. Complete the <code>collision</code> method in <code>Player.mjs</code> to implement this.
|
||||
testString: ''
|
||||
- text: The <code>collision</code> method should accept a collectible item's object as an argument. If the player's avatar intersects with the item, the <code>collision</code> method should return <code>true</code>.
|
||||
testString: ''
|
||||
- text: All players are kept in sync.
|
||||
testString: ''
|
||||
- text: Players can disconnect from the game at any time.
|
||||
testString: ''
|
||||
- text: Prevent the client from trying to guess / sniff the MIME type.
|
||||
testString: ''
|
||||
- text: Prevent cross-site scripting (XSS) attacks.
|
||||
testString: ''
|
||||
- text: Nothing from the website is cached in the client.
|
||||
testString: ''
|
||||
- text: The headers say that the site is powered by "PHP 7.4.3" even though it isn't (as a security measure).
|
||||
testString: ''
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
/**
|
||||
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>
|
@@ -0,0 +1,59 @@
|
||||
---
|
||||
id: 5e46f983ac417301a38fb933
|
||||
title: SHA-1 Password Cracker
|
||||
challengeType: 10
|
||||
isHidden: false
|
||||
isRequired: true
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
For this project you will learn about the importance of good security by creating a password cracker to figure out passwords that were hashed using SHA-1.
|
||||
|
||||
You can access <a href='https://repl.it/@freeCodeCamp/fcc-brute-force-password-cracker' target='_blank'>the full project description and starter code on repl.it</a>.
|
||||
|
||||
After going to that link, fork the project. Once you complete the project based on the instructions in 'README.md', submit your project link below.
|
||||
|
||||
We are still developing the interactive instructional part of the Python curriculum. For now, here are some videos on the freeCodeCamp.org YouTube channel that will teach you some of the Python skills required for this project:
|
||||
<ul>
|
||||
<li>
|
||||
<a href='https://www.freecodecamp.org/news/python-for-everybody/'>Python for Everybody Video Course</a> (14 hours)
|
||||
</li>
|
||||
<li>
|
||||
<a href='https://www.freecodecamp.org/news/learn-python-basics-in-depth-video-course/'>Learn Python Video Course</a> (2 hours)
|
||||
</li>
|
||||
<ul>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 'It should pass all Python tests.'
|
||||
testString: ''
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```py
|
||||
# Python 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>
|
@@ -0,0 +1,52 @@
|
||||
---
|
||||
id: 587d824a367417b2b2512c44
|
||||
title: Stock Price Checker
|
||||
challengeType: 4
|
||||
isRequired: true
|
||||
videoUrl: ''
|
||||
localeTitle: 股票价格检查
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">构建一个功能类似于此的完整堆栈JavaScript应用程序: <a href="https://sphenoid-crater.glitch.me/" target="_blank">https</a> : <a href="https://sphenoid-crater.glitch.me/" target="_blank">//giant-chronometer.glitch.me/</a> 。在这个项目上工作将涉及您在我们的入门项目上在Glitch上编写代码。完成此项目后,您可以将公共故障网址(到应用程序的主页)复制到此屏幕进行测试!您可以选择在另一个平台上编写项目,但必须公开显示我们的测试。使用<a href="https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-project-stockchecker/">此链接</a>在Glitch上启动此项目或在GitHub上克隆<a href="https://github.com/freeCodeCamp/boilerplate-project-stockchecker/">此存储库</a> !如果您使用Glitch,请记住将项目链接保存到安全的地方! </section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 将内容安全策略设置为仅允许从服务器加载脚本和css。
|
||||
testString: ''
|
||||
- text: 我可以使用包含纳斯达克股票代码的表格数据获得/ api /股票价格并收回一个对象stockData。
|
||||
testString: ''
|
||||
- text: 在stockData中,我可以看到股票(字符串,股票代码),价格(字符串格式的小数)和喜欢(int)。
|
||||
testString: ''
|
||||
- text: 我也可以传递像true(boolean)这样的字段来将我的喜欢添加到股票中。每个IP应该只接受1个。
|
||||
testString: ''
|
||||
- text: 如果我传递2只股票,则返回对象将是一个包含股票信息的数组。而不是喜欢,它将显示两者上的rel_likes(两只股票之间的差异)。
|
||||
testString: ''
|
||||
- text: 获得当前价格的一个好方法是使用以下外部API(用您的股票替换“GOOG”):https://finance.google.com/finance/info?q = NASDAQ%3AOGOOG
|
||||
testString: ''
|
||||
- text: 所有5个功能测试都已完成并通过。
|
||||
testString: ''
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,41 @@
|
||||
---
|
||||
id: 587d8248367417b2b2512c3c
|
||||
title: Ask Browsers to Access Your Site via HTTPS Only with helmet.hsts()
|
||||
challengeType: 2
|
||||
videoUrl: ''
|
||||
localeTitle: 要求浏览器通过HTTPS访问您的站点仅限于使用helmet.hsts()
|
||||
---
|
||||
|
||||
## 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。传递配置对象{maxAge:timeInSeconds,force:true}。 Glitch已经启用了hsts。要覆盖其设置,您需要在配置对象中将字段“force”设置为true。在检查Glitch标头进行测试后,我们将拦截并恢复Glitch标头。注意:在自定义网站上配置HTTPS需要获取域和SSL / TSL证书。 </section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- 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); })
|
||||
- text: maxAge应该等于7776000毫秒(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); })
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,39 @@
|
||||
---
|
||||
id: 587d8248367417b2b2512c3a
|
||||
title: Avoid Inferring the Response MIME Type with helmet.noSniff()
|
||||
challengeType: 2
|
||||
videoUrl: ''
|
||||
localeTitle: 避免使用helmet.noSniff()推断响应MIME类型
|
||||
---
|
||||
|
||||
## 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>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- 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); })
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,39 @@
|
||||
---
|
||||
id: 587d8249367417b2b2512c40
|
||||
title: Configure Helmet Using the ‘parent’ helmet() Middleware
|
||||
challengeType: 2
|
||||
videoUrl: ''
|
||||
localeTitle: 配置头盔使用“父”头盔()中间件
|
||||
---
|
||||
|
||||
## 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.use(helmet())将自动包含上面介绍的所有中间件,noCache()和contentSecurityPolicy()除外,但如果需要,可以启用这些中间件。您还可以使用配置对象单独禁用或配置任何其他中间件。 //示例<code>app.use(helmet({</code> <code>frameguard: { // configure</code> <code>action: 'deny'</code> <code>},</code> <code>contentSecurityPolicy: { // enable and configure</code> <code>directives: {</code> <code>defaultSrc: ["self"],</code> <code>styleSrc: ['style.com'],</code> <code>}</code> <code>},</code> <code>dnsPrefetchControl: false // disable</code> <code>}))</code>我们分别为教学目的引入了每个中间件,并且易于测试。使用“父”头盔()中间件对于真实项目来说是最简单,更清洁的。 </section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 没有测试 - 这是一个描述性的挑战
|
||||
testString: assert(true)
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,39 @@
|
||||
---
|
||||
id: 587d8249367417b2b2512c3e
|
||||
title: Disable Client-Side Caching with helmet.noCache()
|
||||
challengeType: 2
|
||||
videoUrl: ''
|
||||
localeTitle: 使用helmet.noCache()禁用客户端缓存
|
||||
---
|
||||
|
||||
## 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>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- 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); })
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,39 @@
|
||||
---
|
||||
id: 587d8248367417b2b2512c3d
|
||||
title: Disable DNS Prefetching with helmet.dnsPrefetchControl()
|
||||
challengeType: 2
|
||||
videoUrl: ''
|
||||
localeTitle: 使用helmet.dnsPrefetchControl()禁用DNS预取
|
||||
---
|
||||
|
||||
## 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>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- 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); })
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,44 @@
|
||||
---
|
||||
id: 58a25bcff9fc0f352b528e7d
|
||||
title: Hash and Compare Passwords Asynchronously
|
||||
challengeType: 2
|
||||
videoUrl: ''
|
||||
localeTitle: 哈希和异步比较密码
|
||||
---
|
||||
|
||||
## 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) => { /*Store hash in your db*/ });</code> <hr>将此散列函数添加到服务器(我们已经定义了函数中使用的变量供您使用)并将其记录到控制台以供您查看!此时,您通常会将哈希值保存到数据库中。现在,当您需要确定新输入是否与散列相同时,您只需使用比较函数<code>bcrypt.compare(myPlaintextPassword, hash, (err, res) => { /*res == true or false*/ });</code> 。在记录完成的哈希并将“res”记录到比较中的控制台之后,将其添加到现有哈希函数中(因为您需要在调用比较函数之前等待哈希完成)。您应该在控制台中看到一个哈希值,然后打印出“true”!如果您将compare函数中的'myPlaintextPassword'更改为'someOtherPlaintextPassword',那么它应该为false。 <pre> bcrypt.hash('passw0rd!',13,(错误,哈希)=> {
|
||||
的console.log(散列); //$2a$12$Y.PHPE15wR25qrrtgGkiYe2sXo98cjuMCG1YwSI5rJW1DSJp0gEYS
|
||||
bcrypt.compare('passw0rd!',hash,(err,res)=> {
|
||||
的console.log(RES); //真正
|
||||
});
|
||||
}); </pre>当您认为自己已经做对时,请提交您的页面。 </section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- 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); })
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,39 @@
|
||||
---
|
||||
id: 58a25bcff9fc0f352b528e7e
|
||||
title: Hash and Compare Passwords Synchronously
|
||||
challengeType: 2
|
||||
videoUrl: ''
|
||||
localeTitle: 哈希并同步比较密码
|
||||
---
|
||||
|
||||
## 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>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- 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); })
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,39 @@
|
||||
---
|
||||
id: 587d8247367417b2b2512c37
|
||||
title: Hide Potentially Dangerous Information Using helmet.hidePoweredBy()
|
||||
challengeType: 2
|
||||
videoUrl: ''
|
||||
localeTitle: 使用helmet.hidePoweredBy()隐藏潜在的危险信息
|
||||
---
|
||||
|
||||
## 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-By:Express默认发送来自Express的每个请求。 helmet.hidePoweredBy()中间件将删除X-Powered-By标头。您还可以将标头显式设置为其他内容,以便让人们离开。例如app.use(helmet.hidePoweredBy({setTo:'PHP 4.2.0'})) </section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- 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); })
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,39 @@
|
||||
---
|
||||
id: 587d8247367417b2b2512c36
|
||||
title: Install and Require Helmet
|
||||
challengeType: 2
|
||||
videoUrl: ''
|
||||
localeTitle: 安装并需要头盔
|
||||
---
|
||||
|
||||
## 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>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: “helmet”依赖应该在package.json中
|
||||
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); })
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,41 @@
|
||||
---
|
||||
id: 587d8247367417b2b2512c38
|
||||
title: Mitigate the Risk of Clickjacking with helmet.frameguard()
|
||||
challengeType: 2
|
||||
videoUrl: ''
|
||||
localeTitle: 使用helmet.frameguard()降低点击劫持的风险
|
||||
---
|
||||
|
||||
## 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><frame></code>或<code><iframe></code> 。除其他外,这可能导致点击劫持攻击。点击劫持是一种欺骗用户与不同于用户认为的页面进行交互的技术。这可以通过iframing在恶意上下文中执行您的页面获得。在这种情况下,黑客可以在页面上放置隐藏层。隐藏按钮可用于运行错误的脚本。此中间件设置X-Frame-Options标头。它限制了谁可以将您的网站放在框架中。它有三种模式:DENY,SAMEORIGIN和ALLOW-FROM。我们不需要我们的应用程序框架。您应该使用配置对象<code>{action: 'deny'}</code>传递的<code>helmet.frameguard()</code> 。 </section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- 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); })
|
||||
- text: helmet.frameguard()'action'应该设置为'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); })
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,39 @@
|
||||
---
|
||||
id: 587d8247367417b2b2512c39
|
||||
title: Mitigate the Risk of Cross Site Scripting (XSS) Attacks with helmet.xssFilter()
|
||||
challengeType: 2
|
||||
videoUrl: ''
|
||||
localeTitle: 使用helmet.xssFilter()降低跨站点脚本(XSS)攻击的风险
|
||||
---
|
||||
|
||||
## 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主体的数据。消毒意味着您应该找到并编码可能有危险的字符,例如<,>。现代浏览器可以通过采用更好的软件策略来帮助降低风险。通常这些都可以通过http标头进行配置。 X-XSS-Protection HTTP标头是一种基本保护。浏览器使用启发式过滤器检测潜在的注入脚本。如果启用了标头,则浏览器会更改脚本代码,从而中和它。它仍然有限的支持。 </section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- 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); })
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,39 @@
|
||||
---
|
||||
id: 587d8248367417b2b2512c3b
|
||||
title: Prevent IE from Opening Untrusted HTML with helmet.ieNoOpen()
|
||||
challengeType: 2
|
||||
videoUrl: ''
|
||||
localeTitle: 使用helmet.ieNoOpen()阻止IE打开不受信任的HTML
|
||||
---
|
||||
|
||||
## 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>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- 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); })
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,43 @@
|
||||
---
|
||||
id: 587d8249367417b2b2512c3f
|
||||
title: Set a Content Security Policy with helmet.contentSecurityPolicy()
|
||||
challengeType: 2
|
||||
videoUrl: ''
|
||||
localeTitle: 使用helmet.contentSecurityPolicy()设置内容安全策略
|
||||
---
|
||||
|
||||
## 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 Rocks,KeyCDN。不幸的是旧版浏览器不支持CSP。默认情况下,指令是全开的,因此将defaultSrc指令设置为回退非常重要。 Helmet支持defaultSrc和default-src命名样式。回退适用于大多数未指定的指令。在本练习中,使用helmet.contentSecurityPolicy(),并将其配置为将defaultSrc指令设置为["self"](允许的源列表必须在数组中),以便默认只信任您的网站地址。同时设置scriptSrc指令,以便允许从您的网站和域"trusted-cdn.com"下载脚本。提示:在"'self'"关键字中,单引号是关键字本身的一部分,因此需要用双引号括起来才能生效。 </section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">
|
||||
在本练习中,使用<code>helmet.contentSecurityPolicy()</code>,并将其配置为将<code>defaultSrc指令</code>设置为<code>["self"]</code>(允许的列表) 来源必须位于一个数组中,以便默认情况下仅信任您的网站地址。 还设置<code>scriptSrc</code>指令,以便您允许从您的网站以及"trusted-cdn.com"域下载脚本。
|
||||
提示:在<code>self</code>关键字中,单引号是关键字本身的一部分,因此需要使用双引号将其括起来才能起作用。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: helmet.csp()中间件应该正确安装。
|
||||
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"]
|
||||
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); })
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,41 @@
|
||||
---
|
||||
id: 58a25bcef9fc0f352b528e7c
|
||||
title: Understand BCrypt Hashes
|
||||
challengeType: 2
|
||||
videoUrl: ''
|
||||
localeTitle: 了解BCrypt Hashes
|
||||
---
|
||||
|
||||
## 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>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: BCrypt是一个依赖
|
||||
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
|
||||
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); })
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,32 @@
|
||||
---
|
||||
id: 5ea9997bbec2e9bc47e94db0
|
||||
title: Creating a TCP Client
|
||||
challengeType: 11
|
||||
isHidden: false
|
||||
videoId: ugYfJNTawks
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
question:
|
||||
text: |
|
||||
Which socket object method lets you set the maximum amount of data your client accepts at once?
|
||||
|
||||
answers:
|
||||
- |
|
||||
`.recv(1024)`
|
||||
- |
|
||||
`.decode('ascii')`
|
||||
- |
|
||||
`.connect(host, port)`
|
||||
solution: 1
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@@ -0,0 +1,45 @@
|
||||
---
|
||||
id: 5ea9997bbec2e9bc47e94db3
|
||||
title: Developing a Banner Grabber
|
||||
challengeType: 11
|
||||
isHidden: false
|
||||
videoId: CeGW761BIsA
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
question:
|
||||
text: |
|
||||
Fill in the blanks to complete the `banner` function below:
|
||||
|
||||
```py
|
||||
def banner(ip, port):
|
||||
s = socket.socket()
|
||||
s.__A__((ip, __B__))
|
||||
print(s.recv(1024))
|
||||
```
|
||||
|
||||
answers:
|
||||
- |
|
||||
A: `connect`
|
||||
|
||||
B: `port`
|
||||
- |
|
||||
A: `getsockname`
|
||||
|
||||
B: `'1-1024'`
|
||||
- |
|
||||
A: `connect`
|
||||
|
||||
B: `int(port)`
|
||||
solution: 3
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@@ -0,0 +1,33 @@
|
||||
---
|
||||
id: 5ea9997bbec2e9bc47e94db4
|
||||
title: Developing a Port Scanner
|
||||
challengeType: 11
|
||||
isHidden: false
|
||||
videoId: z_qkqZS7KZ4
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<section id='description'>
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
question:
|
||||
text: |
|
||||
What is the main difference between the `.connect()` and `.connect_ex()` methods?
|
||||
|
||||
answers:
|
||||
- |
|
||||
There is no difference between the two methods.
|
||||
- |
|
||||
If there is an error or if no host is found, `.connect()` returns an error code while `.connect_ex()` raises an exception.
|
||||
- |
|
||||
If there is an error or if no host is found, `.connect()` raises an exception while `.connect_ex()` returns an error code.
|
||||
solution: 3
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,32 @@
|
||||
---
|
||||
id: 5ea9997bbec2e9bc47e94db1
|
||||
title: Developing an Nmap Scanner part 1
|
||||
challengeType: 11
|
||||
isHidden: false
|
||||
videoId: jYk9XaGoAnk
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
question:
|
||||
text: |
|
||||
What is the correct command to install the Python 3 version of the `python-nmap` library?
|
||||
|
||||
answers:
|
||||
- |
|
||||
`sudo apt install python-nmap`
|
||||
- |
|
||||
`pip install python-nmap`
|
||||
- |
|
||||
`pip3 install python-nmap`
|
||||
solution: 3
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@@ -0,0 +1,32 @@
|
||||
---
|
||||
id: 5ea9997bbec2e9bc47e94db2
|
||||
title: Developing an Nmap Scanner part 2
|
||||
challengeType: 11
|
||||
isHidden: false
|
||||
videoId: a98PscnUsTg
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
question:
|
||||
text: |
|
||||
Which of the following allows you to scan for UDP ports between 21 to 443?
|
||||
|
||||
answers:
|
||||
- |
|
||||
`.scan(ip_addr, '21-443', '-v -sU')`
|
||||
- |
|
||||
`.scan(ip_addr, '1-1024', '-v -sS')`
|
||||
- |
|
||||
`.scan(ip_addr, '21-443', '-v -sS')`
|
||||
solution: 1
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@@ -0,0 +1,33 @@
|
||||
---
|
||||
id: 5ea9997bbec2e9bc47e94dae
|
||||
title: Introduction and Setup
|
||||
challengeType: 11
|
||||
isHidden: false
|
||||
videoId: XeQ7ZKtb998
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<section id='description'>
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
question:
|
||||
text: |
|
||||
What code editor and extension does the instructor recommend for developing penetration testing tools in Python?
|
||||
|
||||
answers:
|
||||
- |
|
||||
Atom and the atom-python-run extension.
|
||||
- |
|
||||
VSCode and Microsoft's Python extension.
|
||||
- |
|
||||
Sublime Text and the Anaconda package.
|
||||
solution: 2
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,32 @@
|
||||
---
|
||||
id: 5ea9997bbec2e9bc47e94daf
|
||||
title: Understanding Sockets and Creating a TCP Server
|
||||
challengeType: 11
|
||||
isHidden: false
|
||||
videoId: F1QI9tNuDQg
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
question:
|
||||
text: |
|
||||
Which of the following functions creates a socket object?
|
||||
|
||||
answers:
|
||||
- |
|
||||
`socket.bind((host, port))`
|
||||
- |
|
||||
`socket.gethostbyname()`
|
||||
- |
|
||||
`socket.socket(socket.AF_INET, socket.SOCK_STREAM)`
|
||||
solution: 3
|
||||
```
|
||||
|
||||
</section>
|
||||
|
Reference in New Issue
Block a user