Skip to content
Open
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions nodeJS/final_project/advanced_topics.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
### Introduction

As you work on more sophisticated web applications, there are some further concepts that might be good for you to be aware of, which we've left until now to avoid rabbit holes. In this lesson, we'll briefly talk about some of them along with possible ways to incorporate them into your Express applications.

### Lesson overview

This section contains a general overview of topics that you will learn in this lesson.

- Content Security Policy.
- Logging.
- Internationalisation.
- Cross-Origin Resource Sharing.
Comment thread
ZackHoang marked this conversation as resolved.
Resolved
- Rate limiting.
Comment thread
ZackHoang marked this conversation as resolved.
Resolved

### Content Security Policy

Depending on the app you are building, chances are you might want to limit what kind of resources are allowed on it. [Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) is a feature that allows you to restrict what resources are loaded on your pages. This is important because it can prevent a few common vulnerabilities:

- **Cross-site scripting (XSS)**: The most common reason why you would want to employ a CSP. By restricting how JavaScript could be loaded and/or injected into your app, you can protect your app and your clients.
- **Clickjacking**: Attackers could also embed certain HTML elements (such as an `<iframe>`), overlaying your UI and hiding what's really under it. A user clicks something, thinking it'll done one thing, but the real button underneath actually does something different instead, such as overlaying a fake "close" button over a "submit" button.

### Logging

Logging information in your app can help you identify what your app is doing at any given moment and display some errors internally that will be helpful for debugging and/or providing some useful data analytics, such your app's traffic distribution, how long do users tend to stay on certain endpoints, etc. The main point about leaving a series of ongoing record is that you could look back and see what went wrong or right, like leaving an entry in your diary!

Logging could be as simple as a few `console.log()`s in certain routes or you could introduce an entire library like [pino](https://github.com/pinojs/pino) or [winston](https://github.com/winstonjs/winston) into your workflow. These libraries are often optimized for performance and can give you back a lot of detail that'll prove useful.

### Cross-Site Request Forgery

Another very common exploit in the World Wide Web. Imagine you encountered a strange but very innocent looking website called `cutekittens.com`...until you inspect its HTML that looks like this.

```html
<form action="https://my-bank.example.org/transfer" method="POST">
<input type="hidden" name="recipient" value="attacker" />
<input type="hidden" name="amount" value="1000" />
</form>
```

Then, within that site, a small but very dangerous snippet of JavaScript is embedded and will be loaded if anyone clicked on it...

```javascript
const form = document.querySelector("form");
form.submit();
```

Assuming you are still logged in and your banking app's cookies still persist, disaster has already been struck! "Wait, I just want to see kittens! Why is my money gone?!" Yikes, you don't want that, right? [Cross-Site Request Forgery (CSRF) attacks](https://developer.mozilla.org/en-US/docs/Web/Security/Attacks/CSRF) are just that: tricking a user into performing a state-changing request to a certain target site from a malicious site. In this case, a form was automatically submit the moment you landed on `cutekittnes.com` and a banking transaction was silently performed.
Comment thread
ZackHoang marked this conversation as resolved.
Resolved

So what could you do about it? One of the most common methods is to use a CSRF token. Every time you prompt your user to perform some state-changing request in your application, check for a hidden, unpredictable key (this could be embedded inside a `<form>` or an HTTP request header). Then, in your app, carry out the request if and only if the token is valid.
Comment on lines +28 to +48

@mao-sz mao-sz Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I think makes this section incomplete is that it's not quite clear exactly where the learner stands in relation to all this.
e.g. from this section, I can absolutely see a learner going "how would I use a CSRF token here? I don't have anything to do with cutekittens.com nor my-bank.example.org!"
The example used here makes sense but it's the bank site's responsibility to implement anti-CSRF measures, not the user's responsibility.

This section needs to clearly frame things so that it's relevant to the learner and them building sites/servers. The problem is specifically that if they're building something, not using anti-CSRF techniques like CSRF tokens is what can allow a malicious site to make a malicious request. By using something like CSRF tokens, a malicious site can certainly try a CSRF attack on your site but since they won't have the correct token, the request will not succeed.

So this example can be kept but instead of saying "So what could you do about it?" (which makes it sound like the user is the one to protect the banking site), frame it as what the banking site could do to protect against CSRF.
Then expand by framing things for when the learner is making their own sites, and how they can use stuff like CSRF tokens to protect users of their sites from CSRF.

Comment on lines +28 to +48

@mao-sz mao-sz Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A separate thing I want to also point out about this section is that it probably won't be clear to learners exactly where the bank site URL comes from. The point is that whoever made the malicious site knows the URL (and params) that could get them what they want, and that's why they crafted the request URL in that way (see https://stackoverflow.com/a/33829607 for more context). It's not just any ol' URL/request to some random site.


### Internationalization

Eventually, you might want to adapt your app to a wider range of audiences around the world. [Internationalization (I18n)](https://learn.microsoft.com/en-us/globalization/methodology/software-internationalization) is a process of adapting your applications to different populations/languages. This could involve taking a look at a client's [Accept-Language header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Accept-Language) and serve the content in the language that they want to see.

MDN documentations also accommodate a wide range of languages! For example, <https://developer.mozilla.org/fr/> will display all your pages in MDN in French! C'est pratique, non?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. "documentation" is an uncountable noun (i.e. no plural)
  2. Rephrasing for better flow from the previous line. Starting straight with "MDN also accommodates..." reads to me a little like it's out of nowhere.
Suggested change
MDN documentations also accommodate a wide range of languages! For example, <https://developer.mozilla.org/fr/> will display all your pages in MDN in French! C'est pratique, non?
For example, MDN can accommodate a wide range of languages! For example, <https://developer.mozilla.org/fr/> will display all your pages in MDN in French! C'est pratique, non?

@mao-sz mao-sz Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about something like this:

Suggested change
MDN documentations also accommodate a wide range of languages! For example, <https://developer.mozilla.org/fr/> will display all your pages in MDN in French! C'est pratique, non?
For example, MDN can accommodate a wide range of languages! [MDN maintains a lot of translated content for various languages](https://github.com/mdn/translated-content), including [French](https://developer.mozilla.org/fr/ "MDN docs in French") and [German](https://developer.mozilla.org/de/ "MDN docs in German").

I think it's a good idea to make it clear that internationalisation is something that has to be manually implemented and not some automatic translation that can be done for any site by just adding headers. While the current text kinda hints at that, actually linking MDN's translated-content repo should make it much clearer that it's a pretty damn big job that has to be manually worked on (they only provide content for certain languages too, not just automatic translation for anything).

Also providing more than one language example feels nicer IMO (but that's just a nit; also using our style guide's aria-label/title links syntax for visually nicer links while still remaining sufficiently accessible.


### Rate limiting

Just like how your city has speed limit signs, [rate limiting](https://www.cloudflare.com/learning/bots/what-is-rate-limiting) is a technique that tracks a user's number of requests and puts a limit on how many times they can access a resource, such as how many requests they're allowed per day. This becomes especially important as your API grows, protecting you from [Denial of Service](https://www.cloudflare.com/learning/ddos/glossary/denial-of-service/) attacks.

This is commonly employed on sensitive endpoints, like ones involving authentication. You might've faced a similar problem where, after a number of unsuccessful attempts of logging into an application, it will temporarily lock you out and remind you to try again after half an hour or so. This is rate limiting coming into play because we want to protect users from brute-force login attacks. rate limiting can involve tracking both a user's IP address and their username and checking how many requests they have made before our application stops or slows them down before any more requests are made.
Comment thread
ZackHoang marked this conversation as resolved.
Resolved

### Conclusion

That was quite a lot that we covered. Hopefully by being aware of these concepts, you are now able to imagine what goes on under the hood of the software you are using in your everyday life.
Comment thread
ZackHoang marked this conversation as resolved.
Resolved

### Assignment

<div class="lesson-content__panel" markdown="1">

1. [ExpressJS' security best practices](https://expressjs.com/en/advanced/best-practice-security/) will help you well in securing your Express app. This guide also suggests a few libraries that could be helpful, should you want to tighten up your app's security without doing everything from scratch.
Comment thread
ZackHoang marked this conversation as resolved.
Resolved

</div>
Loading