Add a default-src CSP Header in Express to Enforce an Allowlist and Mitigate XSS

Mike Sherov
InstructorMike Sherov
Share this video with your friends

Social Share Links

Send Tweet
Published 4 years ago
Updated 3 years ago

In this lesson, we'll learn how to disable all external content srcs other than the specific types of external resources we need. For the types of external resources we need, we'll limit those resources to only nonce-matching resources. This will effectively mitigate all forms of XSS, using the principle of least power to only enable needed capabilities, and drastically reducing the surface area of possible attacks on our website.

Instructor: [0:00] Now, having learned that even though we blocked JavaScript we're still vulnerable to iFrame injection attacks, we need to take a step back and examine the problem.

[0:08] The truth is the browser gives too much privilege by default. Any iFrame, script, image, font, stylesheet, video, audio, or other content from any source is allowed by default. This violates security best practice known as the principle of least privilege, which says that every program must be able to access only the information and resources that are necessary for its legitimate purpose.

[0:32] Fortunately, CSP allows us to allow this principle to our application. CSP has a source called default-src, which is the source that only applied if a more specific source is not specified for the type of resource you're trying to load.

[0:52] We'll specify that our default-src is none, and because we don't have an iFrame source specified here, now no iframes are allowed to be loaded. We could take our script source and abstract it and create a variable called constSelfNonSource.

[1:19] We'll use that for our script-src, and because we may want to allow images, we'll also add image-src. Because we want to add style sheets, we'll have style-src, and because we want to allow fetch and XHR to work, we'll add connect-src and hit Save. What this says is that we'll allow scripts from ourselves, images, XHR, and styles from ourselves but nothing else. If a new attack was discovered in font assets tomorrow, we'd be safe.

[1:55] If we log back into our site and paste in our pay load, you see that no hijack was successful. We've successfully blocked inline scripts, remote scripts, and iframes and, in fact, anything else an attacker may throw at us in the future.

~ 4 years ago

Hi! Thanks for the great course! The question is why not just take care of preventing code injection with validation/sanitization of user input for XSS?

Mike Sherov
Mike Sherovinstructor
~ 4 years ago

Hi Nat! You should definitely do both validation/sanitization AND use CSP. In earlier lessons, I explain that you should always use a "defense in depth" approach to security. That is, if there are two ways to protect, do both in case one of the fails. In this case, input sanitization should always be done but it's important to recognize that it's also error prone and difficult to always do it successfully. With CSP, you get an extra layer of protection :-)

For example, see this article that describes an XSS vuln that was found in Gmail's AMP implementation but wasn't exploitable because of gmails CSP policy:

~ 4 years ago

Thanks, Mike! You've been very helpful

Markdown supported.
Become a member to join the discussionEnroll Today