chore(i8n,learn): processed translations

This commit is contained in:
Crowdin Bot
2021-02-06 04:42:36 +00:00
committed by Mrugesh Mohapatra
parent 15047f2d90
commit e5c44a3ae5
3274 changed files with 172122 additions and 14164 deletions

View File

@@ -0,0 +1,146 @@
---
id: 587d824a367417b2b2512c45
title: Anonymous Message Board
challengeType: 4
forumTopicId: 301568
dashedName: anonymous-message-board
---
# --description--
Build a full stack JavaScript app that is functionally similar to this: <https://anonymous-message-board.freecodecamp.rocks/>.
Working on this project will involve you writing your code using one of the following methods:
- Clone [this GitHub repo](https://github.com/freeCodeCamp/boilerplate-project-messageboard/) and complete your project locally.
- Use [our repl.it starter project](https://repl.it/github/freeCodeCamp/boilerplate-project-messageboard) to complete your project.
- Use a site builder of your choice to complete the project. Be sure to incorporate all the files from our GitHub repo.
When you are done, make sure a working demo of your project is hosted somewhere public. Then submit the URL to it in the `Solution Link` field. Optionally, also submit a link to your projects source code in the `GitHub Link` field.
# --instructions--
1. Set `NODE_ENV` to test without quotes when ready to write tests and DB to your databases connection string (in `.env`)
2. Recommended to create controllers/handlers and handle routing in `routes/api.js`
3. You will add any security features to `server.js`
Write the following tests in `tests/2_functional-tests.js`:
- Creating a new thread: POST request to `/api/threads/{board}`
- Viewing the 10 most recent threads with 3 replies each: GET request to `/api/threads/{board}`
- Deleting a thread with the incorrect password: DELETE request to `/api/threads/{board}` with an invalid `delete_password`
- Deleting a thread with the correct password: DELETE request to `/api/threads/{board}` with a valid `delete_password`
- Reporting a thread: PUT request to `/api/threads/{board}`
- Creating a new reply: POST request to `/api/replies/{board}`
- Viewing a single thread with all replies: GET request to `/api/replies/{board}`
- Deleting a reply with the incorrect password: DELETE request to `/api/threads/{board}` with an invalid `delete_password`
- Deleting a reply with the correct password: DELETE request to `/api/threads/{board}` with a valid `delete_password`
- Reporting a reply: PUT request to `/api/replies/{board}`
# --hints--
You can provide your own project, not the example URL.
```js
(getUserInput) => {
assert(
!/.*\/anonymous-message-board\.freecodecamp\.rocks/.test(
getUserInput('url')
)
);
};
```
Only allow your site to be loaded in an iFrame on your own pages.
```js
async (getUserInput) => {
const data = await fetch(getUserInput('url') + '/_api/app-info');
const parsed = await data.json();
assert.isTrue(parsed.headers['x-frame-options']?.includes('SAMEORIGIN'));
};
```
Do not allow DNS prefetching.
```js
async (getUserInput) => {
const data = await fetch(getUserInput('url') + '/_api/app-info');
const parsed = await data.json();
assert.isTrue(parsed.headers['x-dns-prefetch-control']?.includes('off'));
};
```
Only allow your site to send the referrer for your own pages.
```js
async (getUserInput) => {
const data = await fetch(getUserInput('url') + '/_api/app-info');
const parsed = await data.json();
assert.isTrue(parsed.headers['referrer-policy']?.includes('same-origin'));
};
```
You can send a POST request to `/api/threads/{board}` with form data including `text` and `delete_password`. The saved database record will have at least the fields `_id`, `text`, `created_on`(date & time), `bumped_on`(date & time, starts same as `created_on`), `reported` (boolean), `delete_password`, & `replies` (array).
```js
```
You can send a POST request to `/api/replies/{board}` with form data including `text`, `delete_password`, & `thread_id`. This will update the `bumped_on` date to the comment's date. In the thread's `replies` array, an object will be saved with at least the properties `_id`, `text`, `created_on`, `delete_password`, & `reported`.
```js
```
You can send a GET request to `/api/threads/{board}`. Returned will be an array of the most recent 10 bumped threads on the board with only the most recent 3 replies for each. The `reported` and `delete_password` fields will not be sent to the client.
```js
```
You can send a GET request to `/api/replies/{board}?thread_id={thread_id}`. Returned will be the entire thread with all its replies, also excluding the same fields from the client as the previous test.
```js
```
You can send a DELETE request to `/api/threads/{board}` and pass along the `thread_id` & `delete_password` to delete the thread. Returned will be the string `incorrect password` or `success`.
```js
```
You can send a DELETE request to `/api/replies/{board}` and pass along the `thread_id`, `reply_id`, & `delete_password`. Returned will be the string `incorrect password` or `success`. On success, the text of the `reply_id` will be changed to `[deleted]`.
```js
```
You can send a PUT request to `/api/threads/{board}` and pass along the `thread_id`. Returned will be the string `success`. The `reported` value of the `thread_id` will be changed to `true`.
```js
```
You can send a PUT request to `/api/replies/{board}` and pass along the `thread_id` & `reply_id`. Returned will be the string `success`. The `reported` value of the `reply_id` will be changed to `true`.
```js
```
All 10 functional tests are complete and passing.
```js
```
# --solutions--
```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.
*/
```

View File

@@ -0,0 +1,42 @@
---
id: 5e46f979ac417301a38fb932
title: Port Scanner
challengeType: 10
helpCategory: Python
dashedName: port-scanner
---
# --description--
Create a port scanner using Python.
You can access [the full project description and starter code on Repl.it](https://repl.it/github/freeCodeCamp/boilerplate-port-scanner).
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>
# --hints--
It should pass all Python tests.
```js
```
# --solutions--
```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.
```

View File

@@ -0,0 +1,148 @@
---
id: 5e601c775ac9d0ecd8b94aff
title: Secure Real Time Multiplayer Game
challengeType: 4
dashedName: secure-real-time-multiplayer-game
---
# --description--
Develop a 2D real time multiplayer game using the HTML Canvas API and [Socket.io](https://socket.io/) that is functionally similar to this: <https://secure-real-time-multiplayer-game.freecodecamp.rocks/>. Working on this project will involve you writing your code using one of the following methods:
- Clone [this GitHub repo](https://github.com/freeCodeCamp/boilerplate-project-secure-real-time-multiplayer-game/) and complete your project locally.
- Use [our repl.it starter project](https://repl.it/github/freeCodeCamp/boilerplate-project-secure-real-time-multiplayer-game) to complete your project.
- Use a site builder of your choice to complete the project. Be sure to incorporate all the files from our GitHub repo.
When you are done, make sure a working demo of your project is hosted somewhere public. Then submit the URL to it in the `Solution Link` field. Optionally, also submit a link to your project's source code in the `GitHub Link` field.
# --hints--
You can provide your own project, not the example URL.
```js
(getUserInput) => {
assert(
!/.*\/secure-real-time-multiplayer-game\.freecodecamp\.rocks/.test(
getUserInput('url')
)
);
};
```
Multiple players can connect to a server and play.
```js
```
Each player has an avatar.
```js
```
Each player is represented by an object created by the `Player` class in `Player.mjs`.
```js
```
At a minimum, each player object should contain a unique `id`, a `score`, and `x` and `y` coordinates representing the player's current position.
```js
```
The game has at least one type of collectible item. Complete the `Collectible` class in `Collectible.mjs` to implement this.
```js
```
At a minimum, each collectible item object created by the `Collectible` class should contain a unique `id`, a `value`, and `x` and `y` coordinates representing the item's current position.
```js
```
Players can use the WASD and/or arrow keys to move their avatar. Complete the `movePlayer` method in `Player.mjs` to implement this.
```js
```
The `movePlayer` 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. `movePlayer` should adjust the `x` and `y` coordinates of the player object it's called from.
```js
```
The player's score should be used to calculate their rank among the other players. Complete the `calculateRank` method in the `Player` class to implement this.
```js
```
The `calculateRank` method should accept an array of objects representing all connected players and return the string `Rank: currentRanking/totalPlayers`. For example, in a game with two players, if Player A has a score of 3 and Player B has a score of 5, `calculateRank` for Player A should return `Rank: 2/2`.
```js
```
Players can collide with a collectible item. Complete the `collision` method in `Player.mjs` to implement this.
```js
```
The `collision` method should accept a collectible item's object as an argument. If the player's avatar intersects with the item, the `collision` method should return `true`.
```js
```
All players are kept in sync.
```js
```
Players can disconnect from the game at any time.
```js
```
Prevent the client from trying to guess / sniff the MIME type.
```js
```
Prevent cross-site scripting (XSS) attacks.
```js
```
Nothing from the website is cached in the client.
```js
```
The headers say that the site is powered by "PHP 7.4.3" even though it isn't (as a security measure).
```js
```
# --solutions--
```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.
*/
```

View File

@@ -0,0 +1,42 @@
---
id: 5e46f983ac417301a38fb933
title: SHA-1 Password Cracker
challengeType: 10
helpCategory: Python
dashedName: sha-1-password-cracker
---
# --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 [the full project description and starter code on Repl.it](https://repl.it/github/freeCodeCamp/boilerplate-SHA-1-password-cracker).
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>
# --hints--
It should pass all Python tests.
```js
```
# --solutions--
```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.
```

View File

@@ -0,0 +1,134 @@
---
id: 587d824a367417b2b2512c44
title: Stock Price Checker
challengeType: 4
forumTopicId: 301572
dashedName: stock-price-checker
---
# --description--
Build a full stack JavaScript app that is functionally similar to this: <https://stock-price-checker.freecodecamp.rocks/>.
Since all reliable stock price APIs require an API key, we've built a workaround. Use <https://stock-price-checker-proxy.freecodecamp.rocks/> to get up-to-date stock price information without needing to sign up for your own key.
Working on this project will involve you writing your code using one of the following methods:
- Clone [this GitHub repo](https://github.com/freeCodeCamp/boilerplate-project-stockchecker/) and complete your project locally.
- Use [our repl.it starter project](https://repl.it/github/freeCodeCamp/boilerplate-project-stockchecker) to complete your project.
- Use a site builder of your choice to complete the project. Be sure to incorporate all the files from our GitHub repo.
When you are done, make sure a working demo of your project is hosted somewhere public. Then submit the URL to it in the `Solution Link` field. Optionally, also submit a link to your projects source code in the `GitHub Link` field.
# --instructions--
1. SET `NODE_ENV` to `test` without quotes and set `DB` to your MongoDB connection string
2. Complete the project in `routes/api.js` or by creating a handler/controller
3. You will add any security features to `server.js`
4. You will create all of the functional tests in `tests/2_functional-tests.js`
Write the following tests in `tests/2_functional-tests.js`:
- Viewing one stock: GET request to `/api/stock-prices/`
- Viewing one stock and liking it: GET request to `/api/stock-prices/`
- Viewing the same stock and liking it again: GET request to `/api/stock-prices/`
- Viewing two stocks: GET request to `/api/stock-prices/`
- Viewing two stocks and liking them: GET request to `/api/stock-prices/`
# --hints--
You can provide your own project, not the example URL.
```js
(getUserInput) => {
assert(
!/.*\/stock-price-checker\.freecodecamp\.rocks/.test(getUserInput('url'))
);
};
```
You should set the content security policies to only allow loading of scripts and CSS from your server.
```js
async (getUserInput) => {
const data = await fetch(getUserInput('url') + '/_api/app-info');
const parsed = await data.json();
assert.isTrue(
parsed.headers['content-security-policy'].includes("script-src 'self'")
);
assert.isTrue(
parsed.headers['content-security-policy'].includes("style-src 'self'")
);
};
```
You can send a `GET` request to `/api/stock-prices` with form data containing a NASDAQ stock ticker. Returned will be an object with the property `stockData`.
```js
async (getUserInput) => {
const data = await fetch(
getUserInput('url') + '/api/stock-prices?stock=GOOG'
);
const parsed = await data.json();
assert.property(parsed, 'stockData');
};
```
The `stockData` property includes the `stock` ticker as a string, the `price` as a number, and `likes` as a number.
```js
async (getUserInput) => {
const data = await fetch(
getUserInput('url') + '/api/stock-prices?stock=GOOG'
);
const parsed = await data.json();
const ticker = parsed.stockData;
assert.typeOf(ticker.price, 'number');
assert.typeOf(ticker.likes, 'number');
assert.typeOf(ticker.stock, 'string');
};
```
You can also pass along a `like` field as `true` (boolean) to have your like added to the stock(s). Only 1 like per IP should be accepted.
```js
```
If you pass along 2 stocks, the returned value will be an array with information about both stocks. Instead of `likes`, it will display `rel_likes` (the difference between the likes on both stocks) for both `stockData` objects.
```js
async (getUserInput) => {
const data = await fetch(
getUserInput('url') + '/api/stock-prices?stock=GOOG&stock=MSFT'
);
const parsed = await data.json();
const ticker = parsed.stockData;
assert.typeOf(ticker, 'array');
assert.property(ticker[0], 'rel_likes');
assert.property(ticker[1], 'rel_likes');
};
```
All 5 functional tests are complete and passing.
```js
async (getUserInput) => {
const tests = await fetch(getUserInput('url') + '/_api/get-tests');
const parsed = await tests.json();
assert.isTrue(parsed.length >= 5);
parsed.forEach((test) => {
assert.equal(test.state, 'passed');
});
};
```
# --solutions--
```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.
*/
```

View File

@@ -0,0 +1,63 @@
---
id: 587d8248367417b2b2512c3c
title: Ask Browsers to Access Your Site via HTTPS Only with helmet.hsts()
challengeType: 2
forumTopicId: 301573
dashedName: ask-browsers-to-access-your-site-via-https-only-with-helmet-hsts
---
# --description--
As a reminder, this project is being built upon the following starter project on [Repl.it](https://repl.it/github/freeCodeCamp/boilerplate-infosec), or cloned from [GitHub](https://github.com/freeCodeCamp/boilerplate-infosec/).
HTTP Strict Transport Security (HSTS) is a web security policy which helps to protect websites against protocol downgrade attacks and cookie hijacking. If your website can be accessed via HTTPS you can ask users browsers to avoid using insecure HTTP. By setting the header Strict-Transport-Security, you tell the browsers to use HTTPS for the future requests in a specified amount of time. This will work for the requests coming after the initial request.
# --instructions--
Configure `helmet.hsts()` to use HTTPS for the next 90 days. Pass the config object `{maxAge: timeInSeconds, force: true}`. You can create a variable `ninetyDaysInSeconds = 90*24*60*60;` to use for the `timeInSeconds`. Repl.it already has hsts enabled. To override its settings you need to set the field "force" to true in the config object. We will intercept and restore the Repl.it header, after inspecting it for testing.
Note: Configuring HTTPS on a custom website requires the acquisition of a domain, and a SSL/TLS Certificate.
# --hints--
helmet.hsts() middleware should be mounted correctly
```js
(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);
}
);
```
maxAge should be equal to 7776000 s (90 days)
```js
(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);
}
);
```
# --solutions--
```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.
*/
```

View File

@@ -0,0 +1,42 @@
---
id: 587d8248367417b2b2512c3a
title: Avoid Inferring the Response MIME Type with helmet.noSniff()
challengeType: 2
forumTopicId: 301574
dashedName: avoid-inferring-the-response-mime-type-with-helmet-nosniff
---
# --description--
As a reminder, this project is being built upon the following starter project on [Repl.it](https://repl.it/github/freeCodeCamp/boilerplate-infosec), or cloned from [GitHub](https://github.com/freeCodeCamp/boilerplate-infosec/). Browsers can use content or MIME sniffing to override response `Content-Type` headers to guess and process the data using an implicit content type. While this can be convenient in some scenarios, it can also lead to some dangerous attacks. This middleware sets the X-Content-Type-Options header to `nosniff`, instructing the browser to not bypass the provided `Content-Type`.
# --instructions--
Use the `helmet.noSniff()` method on your server.
# --hints--
helmet.noSniff() middleware should be mounted correctly
```js
(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);
}
);
```
# --solutions--
```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.
*/
```

View File

@@ -0,0 +1,50 @@
---
id: 587d8249367417b2b2512c40
title: Configure Helmet Using the parent helmet() Middleware
challengeType: 2
forumTopicId: 301575
dashedName: configure-helmet-using-the-parent-helmet-middleware
---
# --description--
As a reminder, this project is being built upon the following starter project on [Repl.it](https://repl.it/github/freeCodeCamp/boilerplate-infosec), or cloned from [GitHub](https://github.com/freeCodeCamp/boilerplate-infosec/).
`app.use(helmet())` will automatically include all the middleware introduced above, except `noCache()`, and `contentSecurityPolicy()`, but these can be enabled if necessary. You can also disable or configure any other middleware individually, using a configuration object.
**Example:**
```js
app.use(helmet({
frameguard: { // configure
action: 'deny'
},
contentSecurityPolicy: { // enable and configure
directives: {
defaultSrc: ["self"],
styleSrc: ['style.com'],
}
},
dnsPrefetchControl: false // disable
}))
```
We introduced each middleware separately for teaching purposes and for ease of testing. Using the parent `helmet()` middleware is easy to implement in a real project.
# --hints--
no tests - it's a descriptive challenge
```js
assert(true);
```
# --solutions--
```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.
*/
```

View File

@@ -0,0 +1,47 @@
---
id: 587d8249367417b2b2512c3e
title: Disable Client-Side Caching with helmet.noCache()
challengeType: 2
forumTopicId: 301576
dashedName: disable-client-side-caching-with-helmet-nocache
---
# --description--
As a reminder, this project is being built upon the following starter project on [Repl.it](https://repl.it/github/freeCodeCamp/boilerplate-infosec), or cloned from [GitHub](https://github.com/freeCodeCamp/boilerplate-infosec/).
If you are releasing an update for your website, and you want the users to always download the newer version, you can (try to) disable caching on clients browser. It can be useful in development too. Caching has performance benefits, which you will lose, so only use this option when there is a real need.
# --instructions--
Use the `helmet.noCache()` method on your server.
# --hints--
helmet.noCache() middleware should be mounted correctly
```js
(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);
}
);
```
# --solutions--
```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.
*/
```

View File

@@ -0,0 +1,44 @@
---
id: 587d8248367417b2b2512c3d
title: Disable DNS Prefetching with helmet.dnsPrefetchControl()
challengeType: 2
forumTopicId: 301577
dashedName: disable-dns-prefetching-with-helmet-dnsprefetchcontrol
---
# --description--
As a reminder, this project is being built upon the following starter project on [Repl.it](https://repl.it/github/freeCodeCamp/boilerplate-infosec), or cloned from [GitHub](https://github.com/freeCodeCamp/boilerplate-infosec/).
To improve performance, most browsers prefetch DNS records for the links in a page. In that way the destination ip is already known when the user clicks on a link. This may lead to over-use of the DNS service (if you own a big website, visited by millions people…), privacy issues (one eavesdropper could infer that you are on a certain page), or page statistics alteration (some links may appear visited even if they are not). If you have high security needs you can disable DNS prefetching, at the cost of a performance penalty.
# --instructions--
Use the `helmet.dnsPrefetchControl()` method on your server.
# --hints--
helmet.dnsPrefetchControl() middleware should be mounted correctly
```js
(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);
}
);
```
# --solutions--
```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.
*/
```

View File

@@ -0,0 +1,81 @@
---
id: 58a25bcff9fc0f352b528e7d
title: Hash and Compare Passwords Asynchronously
challengeType: 2
forumTopicId: 301578
dashedName: hash-and-compare-passwords-asynchronously
---
# --description--
As a reminder, this project is being built upon the following starter project on [Repl.it](https://repl.it/github/freeCodeCamp/boilerplate-bcrypt), or cloned from [GitHub](https://github.com/freeCodeCamp/boilerplate-bcrypt/).
As hashing is designed to be computationally intensive, it is recommended to do so asynchronously on your server as to avoid blocking incoming connections while you hash. All you have to do to hash a password asynchronous is call
```js
bcrypt.hash(myPlaintextPassword, saltRounds, (err, hash) => {
/*Store hash in your db*/
});
```
# --instructions--
Add this hashing function to your server(we've already defined the variables used in the function for you to use) and log it to the console for you to see! At this point you would normally save the hash to your database.
Now when you need to figure out if a new input is the same data as the hash you would just use the compare function.
```js
bcrypt.compare(myPlaintextPassword, hash, (err, res) => {
/*res == true or false*/
});
```
Add this into your existing hash function(since you need to wait for the hash to complete before calling the compare function) after you log the completed hash and log 'res' to the console within the compare. You should see in the console a hash then 'true' is printed! If you change 'myPlaintextPassword' in the compare function to 'someOtherPlaintextPassword' then it should say 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
});
});
```
Submit your page when you think you've got it right.
# --hints--
Async hash should be generated and correctly compared.
```js
(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);
}
);
```
# --solutions--
```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.
*/
```

View File

@@ -0,0 +1,66 @@
---
id: 58a25bcff9fc0f352b528e7e
title: Hash and Compare Passwords Synchronously
challengeType: 2
forumTopicId: 301579
dashedName: hash-and-compare-passwords-synchronously
---
# --description--
As a reminder, this project is being built upon the following starter project on [Repl.it](https://repl.it/github/freeCodeCamp/boilerplate-bcrypt), or cloned from [GitHub](https://github.com/freeCodeCamp/boilerplate-bcrypt/).
Hashing synchronously is just as easy to do but can cause lag if using it server side with a high cost or with hashing done very often. Hashing with this method is as easy as calling
```js
var hash = bcrypt.hashSync(myPlaintextPassword, saltRounds);
```
Add this method of hashing to your code and then log the result to the console. Again, the variables used are already defined in the server so you won't need to adjust them. You may notice even though you are hashing the same password as in the async function, the result in the console is different- this is due to the salt being randomly generated each time as seen by the first 22 characters in the third string of the hash. Now to compare a password input with the new sync hash, you would use the compareSync method:
```js
var result = bcrypt.compareSync(myPlaintextPassword, hash);
```
with the result being a boolean true or false.
# --instructions--
Add the function in and log the result to the console to see it working.
Submit your page when you think you've got it right.
# --hints--
Sync hash should be generated and correctly compared.
```js
(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);
}
);
```
# --solutions--
```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.
*/
```

View File

@@ -0,0 +1,40 @@
---
id: 587d8247367417b2b2512c37
title: Hide Potentially Dangerous Information Using helmet.hidePoweredBy()
challengeType: 2
forumTopicId: 301580
dashedName: hide-potentially-dangerous-information-using-helmet-hidepoweredby
---
# --description--
As a reminder, this project is being built upon the following starter project on [Repl.it](https://repl.it/github/freeCodeCamp/boilerplate-infosec), or cloned from [GitHub](https://github.com/freeCodeCamp/boilerplate-infosec/).
Hackers can exploit known vulnerabilities in Express/Node if they see that your site is powered by Express. X-Powered-By: Express is sent in every request coming from Express by default. The `helmet.hidePoweredBy()` middleware will remove the X-Powered-By header. You can also explicitly set the header to something else, to throw people off. e.g. `app.use(helmet.hidePoweredBy({ setTo: 'PHP 4.2.0' }))`
# --hints--
helmet.hidePoweredBy() middleware should be mounted correctly
```js
(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);
}
);
```
# --solutions--
```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.
*/
```

View File

@@ -0,0 +1,46 @@
---
id: 587d8247367417b2b2512c36
title: Install and Require Helmet
challengeType: 2
forumTopicId: 301581
dashedName: install-and-require-helmet
---
# --description--
As a reminder, this project is being built upon the following starter project on [Repl.it](https://repl.it/github/freeCodeCamp/boilerplate-infosec), or cloned from [GitHub](https://github.com/freeCodeCamp/boilerplate-infosec/).
Helmet helps you secure your Express apps by setting various HTTP headers.
# --instructions--
All your code for these lessons goes in the `myApp.js` file between the lines of code we have started you off with. Do not change or delete the code we have added for you.
Install Helmet version `3.21.3`, then require it.
# --hints--
`helmet` version `3.21.3` should be in `package.json`
```js
(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);
}
);
```
# --solutions--
```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.
*/
```

View File

@@ -0,0 +1,64 @@
---
id: 587d8247367417b2b2512c38
title: Mitigate the Risk of Clickjacking with helmet.frameguard()
challengeType: 2
forumTopicId: 301582
dashedName: mitigate-the-risk-of-clickjacking-with-helmet-frameguard
---
# --description--
As a reminder, this project is being built upon the following starter project on [Repl.it](https://repl.it/github/freeCodeCamp/boilerplate-infosec), or cloned from [GitHub](https://github.com/freeCodeCamp/boilerplate-infosec/).
Your page could be put in a `<frame>` or `<iframe>` without your consent. This can result in clickjacking attacks, among other things. Clickjacking is a technique of tricking a user into interacting with a page different from what the user thinks it is. This can be obtained executing your page in a malicious context, by mean of iframing. In that context a hacker can put a hidden layer over your page. Hidden buttons can be used to run bad scripts. This middleware sets the X-Frame-Options header. It restricts who can put your site in a frame. It has three modes: DENY, SAMEORIGIN, and ALLOW-FROM.
We dont need our app to be framed.
# --instructions--
Use `helmet.frameguard()` passing with the configuration object `{action: 'deny'}`.
# --hints--
helmet.frameguard() middleware should be mounted correctly
```js
(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);
}
);
```
helmet.frameguard() 'action' should be set to 'DENY'
```js
(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);
}
);
```
# --solutions--
```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.
*/
```

View File

@@ -0,0 +1,51 @@
---
id: 587d8247367417b2b2512c39
title: >-
Mitigate the Risk of Cross Site Scripting (XSS) Attacks with helmet.xssFilter()
challengeType: 2
forumTopicId: 301583
dashedName: mitigate-the-risk-of-cross-site-scripting-xss-attacks-with-helmet-xssfilter
---
# --description--
As a reminder, this project is being built upon the following starter project on [Repl.it](https://repl.it/github/freeCodeCamp/boilerplate-infosec), or cloned from [GitHub](https://github.com/freeCodeCamp/boilerplate-infosec/).
Cross-site scripting (XSS) is a frequent type of attack where malicious scripts are injected into vulnerable pages, with the purpose of stealing sensitive data like session cookies, or passwords.
The basic rule to lower the risk of an XSS attack is simple: “Never trust users input”. As a developer you should always sanitize all the input coming from the outside. This includes data coming from forms, GET query urls, and even from POST bodies. Sanitizing means that you should find and encode the characters that may be dangerous e.g. &lt;, >.
Modern browsers can help mitigating the risk by adopting better software strategies. Often these are configurable via http headers.
The X-XSS-Protection HTTP header is a basic protection. The browser detects a potential injected script using a heuristic filter. If the header is enabled, the browser changes the script code, neutralizing it. It still has limited support.
# --instructions--
Use `helmet.xssFilter()` to sanitize input sent to your server.
# --hints--
helmet.xssFilter() middleware should be mounted correctly
```js
(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);
}
);
```
# --solutions--
```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.
*/
```

View File

@@ -0,0 +1,44 @@
---
id: 587d8248367417b2b2512c3b
title: Prevent IE from Opening Untrusted HTML with helmet.ieNoOpen()
challengeType: 2
forumTopicId: 301584
dashedName: prevent-ie-from-opening-untrusted-html-with-helmet-ienoopen
---
# --description--
As a reminder, this project is being built upon the following starter project on [Repl.it](https://repl.it/github/freeCodeCamp/boilerplate-infosec), or cloned from [GitHub](https://github.com/freeCodeCamp/boilerplate-infosec/).
Some web applications will serve untrusted HTML for download. Some versions of Internet Explorer by default open those HTML files in the context of your site. This means that an untrusted HTML page could start doing bad things in the context of your pages. This middleware sets the X-Download-Options header to noopen. This will prevent IE users from executing downloads in the trusted sites context.
# --instructions--
Use the `helmet.ieNoOpen()` method on your server.
# --hints--
helmet.ieNoOpen() middleware should be mounted correctly
```js
(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);
}
);
```
# --solutions--
```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.
*/
```

View File

@@ -0,0 +1,71 @@
---
id: 587d8249367417b2b2512c3f
title: Set a Content Security Policy with helmet.contentSecurityPolicy()
challengeType: 2
forumTopicId: 301585
dashedName: set-a-content-security-policy-with-helmet-contentsecuritypolicy
---
# --description--
As a reminder, this project is being built upon the following starter project on [Repl.it](https://repl.it/github/freeCodeCamp/boilerplate-infosec), or cloned from [GitHub](https://github.com/freeCodeCamp/boilerplate-infosec/).
This challenge highlights one promising new defense that can significantly reduce the risk and impact of many type of attacks in modern browsers. By setting and configuring a Content Security Policy you can prevent the injection of anything unintended into your page. This will protect your app from XSS vulnerabilities, undesired tracking, malicious frames, and much more. CSP works by defining an allowed list of content sources which are trusted. You can configure them for each kind of resource a web page may need (scripts, stylesheets, fonts, frames, media, and so on…). There are multiple directives available, so a website owner can have a granular control. See HTML 5 Rocks, KeyCDN for more details. Unfortunately CSP is unsupported by older browser.
By default, directives are wide open, so its important to set the defaultSrc directive as a fallback. Helmet supports both defaultSrc and default-src naming styles. The fallback applies for most of the unspecified directives.
# --instructions--
In this exercise, use `helmet.contentSecurityPolicy()`, and configure it setting the `defaultSrc directive` to `["self"]` (the list of allowed sources must be in an array), in order to trust only your website address by default. Set also the `scriptSrc` directive so that you will allow scripts to be downloaded from your website, and from the domain 'trusted-cdn.com'.
Hint: in the `self` keyword, the single quotes are part of the keyword itself, so it needs to be enclosed in double quotes to be working.
# --hints--
helmet.csp() middleware should be mounted correctly
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/app-info').then(
(data) => {
assert.include(data.appStack, 'csp');
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
Your csp config is not correct. defaultSrc should be ["'self'"] and scriptSrc should be ["'self'", 'trusted-cdn.com']
```js
(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);
}
);
```
# --solutions--
```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.
*/
```

View File

@@ -0,0 +1,72 @@
---
id: 58a25bcef9fc0f352b528e7c
title: Understand BCrypt Hashes
challengeType: 2
forumTopicId: 301586
dashedName: understand-bcrypt-hashes
---
# --description--
For the following challenges, you will be working with a new starter project that is different from the previous one. You can find the new starter project on [Repl.it](https://repl.it/github/freeCodeCamp/boilerplate-bcrypt), or clone it from [GitHub](https://github.com/freeCodeCamp/boilerplate-bcrypt/).
BCrypt hashes are very secure. A hash is basically a fingerprint of the original data- always unique. This is accomplished by feeding the original data into an algorithm and returning a fixed length result. To further complicate this process and make it more secure, you can also *salt* your hash. Salting your hash involves adding random data to the original data before the hashing process which makes it even harder to crack the hash.
BCrypt hashes will always looks like `$2a$13$ZyprE5MRw2Q3WpNOGZWGbeG7ADUre1Q8QO.uUUtcbqloU0yvzavOm` which does have a structure. The first small bit of data `$2a` is defining what kind of hash algorithm was used. The next portion `$13` defines the *cost*. Cost is about how much power it takes to compute the hash. It is on a logarithmic scale of 2^cost and determines how many times the data is put through the hashing algorithm. For example, at a cost of 10 you are able to hash 10 passwords a second on an average computer, however at a cost of 15 it takes 3 seconds per hash... and to take it further, at a cost of 31 it would takes multiple days to complete a hash. A cost of 12 is considered very secure at this time. The last portion of your hash `$ZyprE5MRw2Q3WpNOGZWGbeG7ADUre1Q8QO.uUUtcbqloU0yvzavOm`, looks like one large string of numbers, periods, and letters but it is actually two separate pieces of information. The first 22 characters is the salt in plain text, and the rest is the hashed password!
# --instructions--
To begin using BCrypt, add it as a dependency in your project and require it as 'bcrypt' in your server.
Add all your code for these lessons in the `server.js` file between the code we have started you off with. Do not change or delete the code we have added for you.
Submit your page when you think you've got it right.
# --hints--
BCrypt should be a dependency.
```js
(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);
}
);
```
BCrypt should be properly required.
```js
(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);
}
);
```
# --solutions--
```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.
*/
```

View File

@@ -0,0 +1,30 @@
---
id: 5ea9997bbec2e9bc47e94db0
title: Creating a TCP Client
challengeType: 11
videoId: ugYfJNTawks
dashedName: creating-a-tcp-client
---
# --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)`
## --video-solution--
1

View File

@@ -0,0 +1,43 @@
---
id: 5ea9997bbec2e9bc47e94db3
title: Developing a Banner Grabber
challengeType: 11
videoId: CeGW761BIsA
dashedName: developing-a-banner-grabber
---
# --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)`
## --video-solution--
3

View File

@@ -0,0 +1,30 @@
---
id: 5ea9997bbec2e9bc47e94db4
title: Developing a Port Scanner
challengeType: 11
videoId: z_qkqZS7KZ4
dashedName: developing-a-port-scanner
---
# --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.
## --video-solution--
3

View File

@@ -0,0 +1,30 @@
---
id: 5ea9997bbec2e9bc47e94db1
title: Developing an Nmap Scanner part 1
challengeType: 11
videoId: jYk9XaGoAnk
dashedName: developing-an-nmap-scanner-part-1
---
# --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`
## --video-solution--
3

View File

@@ -0,0 +1,30 @@
---
id: 5ea9997bbec2e9bc47e94db2
title: Developing an Nmap Scanner part 2
challengeType: 11
videoId: a98PscnUsTg
dashedName: developing-an-nmap-scanner-part-2
---
# --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')`
## --video-solution--
1

View File

@@ -0,0 +1,30 @@
---
id: 5ea9997bbec2e9bc47e94dae
title: Introduction and Setup
challengeType: 11
videoId: XeQ7ZKtb998
dashedName: introduction-and-setup
---
# --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.
## --video-solution--
2

View File

@@ -0,0 +1,30 @@
---
id: 5ea9997bbec2e9bc47e94daf
title: Understanding Sockets and Creating a TCP Server
challengeType: 11
videoId: F1QI9tNuDQg
dashedName: understanding-sockets-and-creating-a-tcp-server
---
# --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)`
## --video-solution--
3