As a developer, I often have a need to tinker around in Chrome against production websites. For example, I might need to set-up a demo, bug fix an issue, or even try to mock something up for development purposes. More often than not nowadays, when I try to inject a script, call an API, insert an image, or even test if a site will work within an AB testing tool, the browser will throw some type of error that prevents me from performing my local development task in peace

When you bump into a restriction, its because a web security policy has been applied to the site. For security purposes these rules need to be in place, however, before you can move forward making your development changes, you will need to figure out what rule you are violating and also figure out which policy you need to either add, remove, or edit.

Debugging the root cause of a restriction and then figuring out where you need to apply a change can be easier said than done. What's harder is some of the rules can seem very similar in nature, and often the error message thrown in the browser is not as clear and obvious as you'd want it to.

When you need to work with scripts, APIs, images, iFrames, CSS files the blocking policies that you will encounter will be CORS (Cross-Origin Resource Sharing) related, or down to a CSP (Content Security Policy).

Both of these policies play a vital role in web security, however, for developers new to these policies it is very easy to get the two confused. A CSP policy can be used to lock down around 10 different types of calls on a page, one of which relates to API access. CORs on the other hand can be used to bypass API access issues, so its very easy to get the two confused at times and this is where this article will help 💥

If you are unclear about why your getting a resource restriction error in your browser, or you are unsure about the differences between CORS and CSP this is the article for you. In this article, I will explain why these things exist, the error message you can use to help identify the rule you are violating, as well as show you some tools and the hacks that you can use that will help you bypass some of the restrictions for local development purposes🔥🔥🔥

Content Security Policies

A Content Security Policy (CSP) is a security standard implemented within a web browser to mitigate cross-site scripting (XSS) and data injection attacks. These types of attacks can be made by injecting false images, loading unwanted scripts from third-parties, or even calling APIs from untrusted third-parties. You can tell when you bump into a CSP policy error by looking in the console on a page. Within the logs you will see an error that looks something like this: CSP Error

This error is an example of a iFrame violation and granted the issue above is easy to track down, however, depending on what resource is in violation, sometimes its less obvious. For example, if you asked ChatGPT about this error:

The response will be on the lines of 'this error occurs due to the browser's enforcement of the Same-Origin Policy, which prevents scripts from accessing resources (such as frames or iFrames) from different origins unless explicitly allowed through mechanisms like Cross-Origin Resource Sharing (CORS) or appropriate Content-Security-Policy (CSP) directives'

How you add and implement these two directives within your architecture is very different, so understanding the root cause is important. Without that understanding you'll be left to blindly hack away at your security policies until somethign works. In terms of good practice, hacking and security are definitely two words that should never be in the same sentence :P

As a web page can load many different types of resources, similarly we have lots of corresponding CSP polices to lock each resource type down. To see a full list of all the CSP policies you can head over to this page at the MDM Web Docs, however, for now lets focus on the main ones:

Script Execution: This policy is set using the script-src directive. When applied, this policy restricts what domains script tags can be loaded from on the page. When this rule is violated, expect to see an error like this:

In terms of JavaScript, think calls like this:

Style Execution: This policy is set using the style-src directive. When applied, this policy restricts what domains/origins that a stylesheet (CSS) can be loaded from. When this rule is violated, expect to see an error in the console like this:

Fetch Request:: This directive is set using the connect-src prop and is used to restrict the URLs that can be used within a script interfaces, e.g. a fetch, web sockets request:

Out of all the CSP policies, this directive is the one that can most easily be confused by CORs. Both rules are in the ballpark of API access, however, just to be clear the connect-src directive does not interfere with CORS headers!

Image Execution: This directive is set using the img-src prop and is used to define the domains/origins that images can be loaded from. When this rule is violated, expect to see an error in the console like this:

iFrame Execution: This directive is set using the frame-src prop and can restrict what domains can be loaded within an iFrame. When this rule is violated, expect to see an error in the console like this:

iFrame Origin Execution: This policy is set using the 'frame-ancestors' directive and is used to restrict what origin domains can commute via an iFrame. This directive helps prevent clickjacking attacks by restricting which origins can embed content within their frames.

As this is a lesser known policy, I have personally found it pretty easy to find iFrame origin execution errors to feel like a CORS error because when violated, you will encounter cross-origin warnings. Typically, when you encounter this error you will see this within the console:

With the policies covered, the next thing you need to know is how to implement each one and define their behaviours! For each policy you define, you can configure each directive using the below values:

  • *: The * denotes the wildcard operator. When applied to a directive it means any domain/origin can be used to access a resource except files. This a is good for testing purposes but bad for security!
  • none: None prevents any domain from any source from being use to load that resource
  • self: When applied self means that only the origin of the current document can make requests to the selected resource type.
  • data: Allows loading resources via the data scheme

Now you know the values, the easy rule to follow is that unless you need to explicitly whitelist something, self and none should be your go to policy types.

Next, you might be wondering where you need to apply these CSP rules. The answer to this will depend on the websites tech stack. You need to apply these rules at the server level, not within the client. If you use .NET for example, you would add these rules within Program.cs like this:

If you use a CDN like Cloudflare, you could alternatively add your policies within that layer of your architecture instead. For Cloudflare, you can create a police shield policy and within the text box, add something like this:

How Do You Hack A CSP Policy For Local Development?: For obvious security reasons there is no way for you to update policies globally within the client, however, you can force remove CSP policy headers for local development using a proxy tool if you want.

My browser of preference is Chrome and the proxy extension I use within Chrome is called Requestly.

Once installed, Requestly will allow you to build custom rules which will modify the headers for any network request made pages loaded within your browser. To get rid of a CSP policy locally, you can create a rule within Requestly to remove certain headers for all requests. Applying a rule like this can often unblock you and allow you to debug and build apps locally within your local browser. The rule to remove a CSP policy within Requisitely would look like this:

CSP Policies Vs CORS Hacking Masterclass In 10 Minutes 3

That covers most of the things you need to know in order to debug and work with CSP policies, the next policy to look at is CORS!

What is Cross-Origin Resource Sharing (CORS) ?

CORS allows a web server to specify which origins are permitted to access its resources. CORS helps prevent certain types of attacks, such as cross-origin requests initiated by malicious scripts, while still allowing legitimate cross-origin requests. You normally encounter CORS errors when you try to call an API from a domain that has not been locked down and not whitelisted. For reference, the type of error you will receive will be a Same-Origin Policy (SOP) error

Origin/domain errors being thrown by attempted API access, sounds very similar to an error thrown by a CSP script execution directive, however, the intentions are different. The error message thrown by a CORs violation is different to the CSP error:

As web development loves to be confusing, this is not the only type of CORs error message that you can encounter. There are several subtly different CORS errors that can be thrown. For example, this pre-flight error is definitely a little less obvious that it is down to CORS:

The reason you can get a pre-flight error is because the CORS check made by the browser failed. Whenever a request is attempted within your browser to a CORs restricted resource, within your network tab you will first see a pre-flight request being made. The pre-flight check is part of the CORs protocol and its used by the browser to check if a cross-origin request is safe to return or not.

As part of the CORs pre-flight, an OPTIONS request is made to the server to determine the server's CORs rules. In response to the pre-flight request, the server responds with the CORs headers indicating whether the request is allowed. If the origin is no allowed, you will see the errors above.

You can define your sites CORs policy at an application level, or on your end-point definition server-side. For example within .NET, you can add the rules within 'Program.cs' like this:

Alternatively, if you wanted to define the policy within a node API you could like this:

As you can hopefully tell by this code, CORS is implemented as HTTP headers exchanged between web browser and server. By adding headers such as Access-Control-Allow-Origin and Access-Control-Allow-Methods you can limit and whitelist different domains. CLS policies on the other hand are implemented at runtime.

In terms of debugging and hacking, there is no way to get around a CORS error without updating the CORS rules on the server itself.


Happy Coding 🤘