chore: manual translations (#42811)

This commit is contained in:
Nicholas Carrigan (he/him)
2021-07-09 21:23:54 -07:00
committed by GitHub
parent a3395269a0
commit c4fd49e5b7
806 changed files with 8935 additions and 4378 deletions

View File

@@ -13,7 +13,7 @@ Build a full stack JavaScript app that is functionally similar to this: <https:/
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 [our Replit starter project](https://replit.com/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.
@@ -33,8 +33,8 @@ Write the following tests in `tests/2_functional-tests.js`:
- 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`
- Deleting a reply with the incorrect password: DELETE request to `/api/replies/{board}` with an invalid `delete_password`
- Deleting a reply with the correct password: DELETE request to `/api/replies/{board}` with a valid `delete_password`
- Reporting a reply: PUT request to `/api/replies/{board}`
# --hints--
@@ -84,7 +84,33 @@ async (getUserInput) => {
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
async (getUserInput) => {
const date = new Date();
const text = `fcc_test_${date}`;
const deletePassword = 'delete_me';
const data = { text, delete_password: deletePassword };
const url = getUserInput('url');
const res = await fetch(url + '/api/threads/fcc_test', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (res.ok) {
const checkData = await fetch(url + '/api/threads/fcc_test');
const parsed = await checkData.json();
try {
assert.equal(parsed[0].text, text);
assert.isNotNull(parsed[0]._id);
assert.equal(new Date(parsed[0].created_on).toDateString(), date.toDateString());
assert.equal(parsed[0].bumped_on, parsed[0].created_on);
assert.isArray(parsed[0].replies);
} catch (err) {
throw new Error(err.responseText || err.message);
}
} else {
throw new Error(`${res.status} ${res.statusText}`);
}
};
```
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`.

View File

@@ -2,6 +2,7 @@
id: 5e46f979ac417301a38fb932
title: Port Scanner
challengeType: 10
forumTopicId: 462372
helpCategory: Python
dashedName: port-scanner
---
@@ -10,7 +11,7 @@ dashedName: port-scanner
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).
You can access [the full project description and starter code on Replit](https://replit.com/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.

View File

@@ -2,6 +2,7 @@
id: 5e601c775ac9d0ecd8b94aff
title: Secure Real Time Multiplayer Game
challengeType: 4
forumTopicId: 462375
dashedName: secure-real-time-multiplayer-game
---
@@ -10,11 +11,15 @@ dashedName: secure-real-time-multiplayer-game
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 [our Replit starter project](https://replit.com/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.
# --instructions--
**Note**: `helmet@^3.21.3` is needed for the user stories. This means you will need to use the previous version of Helmet's docs, for information on how to achieve the user stories.
# --hints--
You can provide your own project, not the example URL.
@@ -116,25 +121,47 @@ Players can disconnect from the game at any time.
Prevent the client from trying to guess / sniff the MIME type.
```js
async (getUserInput) => {
const data = await fetch(getUserInput('url') + '/_api/app-info');
const parsed = await data.json();
assert.equal(parsed.headers['x-content-type-options'], 'nosniff');
};
```
Prevent cross-site scripting (XSS) attacks.
```js
async (getUserInput) => {
const data = await fetch(getUserInput('url') + '/_api/app-info');
const parsed = await data.json();
assert.equal(parsed.headers['x-xss-protection'], '1; mode=block');
};
```
Nothing from the website is cached in the client.
```js
async (getUserInput) => {
const data = await fetch(getUserInput('url') + '/_api/app-info');
const parsed = await data.json();
assert.equal(parsed.headers['surrogate-control'], 'no-store');
assert.equal(
parsed.headers['cache-control'],
'no-store, no-cache, must-revalidate, proxy-revalidate'
);
assert.equal(parsed.headers['pragma'], 'no-cache');
assert.equal(parsed.headers['expires'], '0');
};
```
The headers say that the site is powered by "PHP 7.4.3" even though it isn't (as a security measure).
```js
async (getUserInput) => {
const data = await fetch(getUserInput('url') + '/_api/app-info');
const parsed = await data.json();
assert.equal(parsed.headers['x-powered-by'], 'PHP 7.4.3');
};
```
# --solutions--

View File

@@ -2,6 +2,7 @@
id: 5e46f983ac417301a38fb933
title: SHA-1 Password Cracker
challengeType: 10
forumTopicId: 462374
helpCategory: Python
dashedName: sha-1-password-cracker
---
@@ -10,7 +11,7 @@ dashedName: sha-1-password-cracker
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).
You can access [the full project description and starter code on Replit](https://replit.com/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.

View File

@@ -15,7 +15,7 @@ Since all reliable stock price APIs require an API key, we've built a workaround
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 [our Replit starter project](https://replit.com/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.
@@ -62,7 +62,7 @@ async (getUserInput) => {
};
```
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`.
You can send a `GET` request to `/api/stock-prices`, passing a NASDAQ stock symbol to a `stock` query parameter. The returned object will contain a property named `stockData`.
```js
async (getUserInput) => {
@@ -74,7 +74,7 @@ async (getUserInput) => {
};
```
The `stockData` property includes the `stock` ticker as a string, the `price` as a number, and `likes` as a number.
The `stockData` property includes the `stock` symbol as a string, the `price` as a number, and `likes` as a number.
```js
async (getUserInput) => {

View File

@@ -8,13 +8,13 @@ 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/).
As a reminder, this project is being built upon the following starter project on [Replit](https://replit.com/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.
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`. Replit 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 Replit header, after inspecting it for testing.
Note: Configuring HTTPS on a custom website requires the acquisition of a domain, and a SSL/TLS Certificate.

View File

@@ -8,7 +8,7 @@ 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`.
As a reminder, this project is being built upon the following starter project on [Replit](https://replit.com/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--

View File

@@ -8,7 +8,7 @@ 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/).
As a reminder, this project is being built upon the following starter project on [Replit](https://replit.com/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.
@@ -21,7 +21,7 @@ app.use(helmet({
},
contentSecurityPolicy: { // enable and configure
directives: {
defaultSrc: ["self"],
defaultSrc: ["'self'"],
styleSrc: ['style.com'],
}
},

View File

@@ -8,7 +8,7 @@ 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/).
As a reminder, this project is being built upon the following starter project on [Replit](https://replit.com/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.

View File

@@ -8,7 +8,7 @@ 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/).
As a reminder, this project is being built upon the following starter project on [Replit](https://replit.com/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.

View File

@@ -8,7 +8,7 @@ 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 a reminder, this project is being built upon the following starter project on [Replit](https://replit.com/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

View File

@@ -8,7 +8,7 @@ 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/).
As a reminder, this project is being built upon the following starter project on [Replit](https://replit.com/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

View File

@@ -8,9 +8,9 @@ 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/).
As a reminder, this project is being built upon the following starter project on [Replit](https://replit.com/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' }))`
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. Use the `helmet.hidePoweredBy()` middleware to remove the X-Powered-By header.
# --hints--

View File

@@ -8,7 +8,13 @@ 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/).
Working on these challenges will involve you writing your code using one of the following methods:
- Clone [this GitHub repo](https://github.com/freeCodeCamp/boilerplate-infosec/) and complete these challenges locally.
- Use [our Replit starter project](https://replit.com/github/freeCodeCamp/boilerplate-infosec) to complete these challenges.
- 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.
Helmet helps you secure your Express apps by setting various HTTP headers.
@@ -16,7 +22,7 @@ Helmet helps you secure your Express apps by setting various HTTP headers.
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.
Install Helmet version `3.21.3`, then require it. You can install a specific version of a package with `npm install --save-exact package@version`, or by adding it to your `package.json` directly.
# --hints--
@@ -26,8 +32,9 @@ Install Helmet version `3.21.3`, then require it.
(getUserInput) =>
$.get(getUserInput('url') + '/_api/package.json').then(
(data) => {
var packJson = JSON.parse(data);
assert(packJson.dependencies.helmet === '3.21.3');
const packJson = JSON.parse(data);
const helmet = packJson.dependencies.helmet;
assert(helmet === '3.21.3' || helmet === '^3.21.3');
},
(xhr) => {
throw new Error(xhr.responseText);

View File

@@ -8,7 +8,7 @@ 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/).
As a reminder, this project is being built upon the following starter project on [Replit](https://replit.com/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.

View File

@@ -9,7 +9,7 @@ dashedName: mitigate-the-risk-of-cross-site-scripting-xss-attacks-with-helmet-xs
# --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/).
As a reminder, this project is being built upon the following starter project on [Replit](https://replit.com/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.

View File

@@ -8,7 +8,7 @@ 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/).
As a reminder, this project is being built upon the following starter project on [Replit](https://replit.com/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.

View File

@@ -8,7 +8,7 @@ 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/).
As a reminder, this project is being built upon the following starter project on [Replit](https://replit.com/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.
@@ -16,13 +16,13 @@ By default, directives are wide open, so its important to set the defaultSrc
# --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'.
In this exercise, use `helmet.contentSecurityPolicy()`. Configure it by adding a `directives` object. In the object, set the `defaultSrc` to `["'self'"]` (the list of allowed sources must be in an array), in order to trust only your website address by default. Also set the `scriptSrc` directive so that you only allow scripts to be downloaded from your website (`'self'`), 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.
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
helmet.contentSecurityPolicy() middleware should be mounted correctly
```js
(getUserInput) =>

View File

@@ -8,7 +8,7 @@ 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/).
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 [Replit](https://replit.com/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.