CSP Bypass: Turning a Security Header Against Itself

CSP Bypass: Turning a Security Header Against Itself

Introduction

The Content Security Policy (CSP) is a special HTTP response header designed to mitigate certain classes of client-side attacks, most notably Cross-Site Scripting (XSS). Some engineers view the CSP as a “magic bullet” against XSS. However, if the CSP is set up improperly, these misconfigurations can be exploited by attackers to completely bypass the policy and execute malicious code.


Content Security Policy (CSP) Basics

The CSP header is straightforward and is composed of directives separated by a semicolon (;). These directives act as specific security policies applied to a website.

Key CSP Directives

These directives define what types of resources are allowed and how they can be used:

  • default-src: Acts as a catchall for any resource type not explicitly listed below.
  • script-src: Describes the allowed sources for loading JavaScript files.
  • style-src: Describes the allowed sources for loading stylesheets.
  • img-src: Describes the allowed sources for loading images.
  • connect-src: Applies to AJAX requests and WebSockets.
  • font-src: Describes the allowed sources for loading fonts.
  • object-src: Describes the allowed sources for loading objects, such as the tag.
  • media-src: Describes the allowed sources for loading audio and video files.
  • frame-ancestors: Describes which sites are permitted to load this site in an iframe (mitigates clickjacking).

Key Source List Values

These values define which resources can be loaded and from where:

Source List ValueDescriptionImplication
*Wildcard: Load resources from anywhere.Dangerous: Negates protection.
'none'Block All: Blocks all resources of this type.Highly restrictive.
'self'Same Origin: Can only load resources from the same origin (protocol, domain, and port).Standard and safe default.
data:Data Scheme: Can only load resources from the data: schema (e.g., Base64 encoded resources).Useful but can be abused.
https:HTTPS Only: Can only load resources over HTTPS.Good security practice.
'unsafe-inline'Inline Elements: Allows inline elements (e.g., onclick handlers, tags, javascript: URLs).Dangerous: Re-introduces XSS risk.
'unsafe-eval'Dynamic Code: Allows dynamic code evaluation (e.g., the eval() function).Dangerous: Re-introduces XSS risk.
'sha256-...'Hash Match: Can only load resources if the content matches the specified cryptographic hash.Highly secure for specific inline scripts.
'nonce-...'Nonce Match: Allows an inline script or CSS to execute if the tag contains a nonce attribute matching the nonce specified in the CSP header.Highly secure for specific inline scripts.

Example CSP Header Breakdown

A CSP is typically returned in the HTTP response header.

Example: default-src 'none'; frame-ancestors 'none'; script-src github.githubassets.com; style-src 'unsafe-inline' github.githubassets.com

Let’s look at what some of these policies are doing:

  • default-src 'none';: This establishes a baseline policy to block everything unless explicitly told otherwise.
  • frame-ancestors 'none';: This policy blocks other sites from loading this site in an iframe, effectively killing the clickjacking vulnerability.
  • script-src github.githubassets.com;: This policy restricts the site to only load JavaScript files from the github.githubassets.com domain, essentially killing traditional XSS unless a bypass can be found on that specific whitelisted domain.
  • style-src 'unsafe-inline' github.githubassets.com: This policy allows stylesheets from one source and also permits inline CSS (which can sometimes be abused, though less so than inline scripts).

Basic CSP Bypass Due to Misconfiguration

One of the easiest ways to mess up a CSP implementation is to use dangerous source list values when setting policies.

1. Wildcard Permissions (*)

Always look out for wildcard permissions.

  • Vulnerable CSP: default-src 'self' *

Since default-src acts as a catchall and * acts as a wildcard, this policy essentially says allow any resources to be loaded from anywhere. This is the same thing as not having a CSP header at all.

2. Unsafe Inline and Eval

The use of 'unsafe-inline' and 'unsafe-eval' is always a critical danger when applied to the script-src policy.

  • Vulnerable CSP Snippet: script-src 'unsafe-inline' 'unsafe-eval' ...

If 'unsafe-inline' is present, XSS payloads that are normally blocked will execute:

  • (or similar inline injection)

If data: is present, it allows resources to be loaded via the data URI scheme:

Previous Post
Client-Side Template Injection (CSTI): Exploiting Modern Frontend Frameworks

Client-Side Template Injection (CSTI): Exploiting Modern Frontend Frameworks

Next Post
Relative Path Overwrite (RPO) Exploiting Path Confusion for Defacement

Relative Path Overwrite (RPO): Exploiting Path Confusion for Defacement

Related Posts