0

I am using Content Security Policy (CSP) rules in my code to defend against XSS attacks. Here are the CSP rules I have implemented using Helmet:

.use(
helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: [
  "'self'",
  "use.fontawesome.com",
  "ajax.googleapis.com",
  "cdnjs.cloudflare.com",
   ],
 },
})
)

Despite these measures, suppose an attacker is faced with an input field in the application. The CSP rules prevent simple script injections like:

<script>alert(1)</script>

Given therestrictions, how could an attacker potentially bypass the given CSP rules and still execute a script? What specific approach or technique might they use to exploit vulnerabilities in this setup?

(Assume that any script inputted by the user could potentially execute. However, due to the Content Security Policy (CSP), such scripts are blocked. For instance, when the user inputs HTML, it is displayed literally because there is no mechanism in place to block HTML content. Similarly, JavaScript is also inputted by the user, but unlike HTML, it cannot execute because the CSP effectively blocks it)

1 Answer 1

0

There are two potential attacks in this scenario.

First, you don't specify a scheme in your script-src URLs. This means plaintext HTTP is permitted. An attacker could try to inject a script element like <script src="http://use.fontawesome.com/foo.js"></script>, which does not violate the CSP policy. The browser will then try to load the script via plaintext HTTP. If the attacker is in a man-in-the-middle position, they can inject an arbitrary script by responding to the HTTP request. To fix this, you should only allow HTTPS by specifying the URLs https://use.fontawesome.com etc.

Using 'self' on a site which serves dynamic content is also problematic. If your application supports file uploads, or if there's some server-script which prints the content of URL parameters (note this has nothing to do with reflected XSS), then an attacker may be able to inject scripts through script elements like <script src="/path/to/uploaded/script"></script> or <script src="/some/path?insert=javascript-code"></script>. To fix this, avoid 'self' and instead serve JavaScript files from a separate, complete static (sub-) domain like static.yourdomain.com.

9
  • I understand the concept, but I'm unsure about the implementation. For example, in the first approach, how would I integrate foo.js into fontawesome.com? In the second approach, when I attempted to include malicious code by simply using the src attribute to the specified path, I encountered the following error: 'Refused to execute script from THE CODE PATH because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled. @Ja1024
    – EPiez
    Commented Apr 25 at 21:35
  • @EPiez In the first attack, the path is irrelevant. The attacker doesn't need to actually place a file on use.fontawesome.com. By injecting a script element with the http scheme and some dummy path on use.fontawesome.com, they make the browser try to load JavaScript code using HTTP. If the attacker is in a man-in-the-middle position, they can intercept the request and respond with the JavaScript code they want to be executed. The path can be something like /this-does-not-exist, because the request never actually reaches the use.fontawesome.com server.
    – Ja1024
    Commented Apr 25 at 21:55
  • @EPiez In modern browsers, script elements only execute code which has been served as text/javascript. Your server has chosen text/html instead. If you use an uploaded file, try a .js extension; this may trigger the text/javascript media type. If you inject code through a URL, getting the right media type will be trickier. Either use an old browser without this protection (like Firefox before version 50). Or try to exploit MIME sniffing. By default, the browser will choose the content type by analyzing parts of the content and looking for typical patterns.
    – Ja1024
    Commented Apr 25 at 22:09
  • tried older versions but did not work. I have never used: <script src="/some/path?insert=javascript-code"> how would I insert a simpel "alert(1)" maybe this will solve the issue?
    – EPiez
    Commented Apr 25 at 23:37
  • You have to prepare a script in your application which takes a path parameter and shows its content. For a quick demonstration of the attack, make the script only print the parameter and nothing else. Also ensure the page is served as text/javascript. Alternatively, you can set up a more realistic scenario (a non-JavaScript media type, other content is displayed), but then you have to be ready to spend a lot of time on research and experimentation to come up with a working attack. It depends on what exactly you want to achieve.
    – Ja1024
    Commented Apr 26 at 4:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .