How do I allow `javascript:void(0)` for use in HTML element attributes through Content-Security-Policy?

Viewed 4048

I want to be able to do

<form action="javascript:void(0)">

or

<a href="javascript:void(0)">

to make sure nothing happens even if the handler fails to prevent the default action. How should I declare this to be allowed using the Content-Security-Policy HTTP response header without resorting to unsafe-eval?

5 Answers

I've recently applied CSP policy to a huge VUE project, by adding meta headers to index.html.

Google Chrome would print a warning about javascript: links, but nothing else happens apart from that.

What I did is simply remove the href="javascript: attribute, and added a style to maintain the cursor style:

a:hover {
    cursor: pointer;
}

And it worked great for me.

P.S I also replaced several <a> with <button> tag, and <button> does not require a href attribute.

I believe in your question you contradict yourself.

How do I allow javascript:void(0) for use in HTML element attributes through Content-Security-Policy?

On one hand, you set a Content Security Policy (CSP) header to which you specify a rule which I'm guessing is script-src. A directive used to prevent inline scripts from running.

On the other hand, you want to bypass it and execute inline javascript.

Isn't the header working just as expected?

Adding 'unsafe-inline' will bypass it, but negates the idea of disallowing inline styles and inline scripts (one of the biggest security wins CSP provides).

You can use a nonce-source to only allow specific inline script blocks.

Example:

Content-Security-Policy: script-src 'nonce-2726c7f26c'

Note, you will have to set the same nonce on the element as well.

<script nonce="2726c7f26c">
  var inline = 1;
</script>

For your case using forms, the header would be:

Content-Security-Policy: form-action 'nonce-<value>'

Alternatively, you can create hashes from your inline scripts. CSP supports sha256, sha384 and sha512.

Example:

Content-Security-Policy: script-src 'sha256-076c8f1ca6979ef156b510a121b69b6265011597557ca2971db5ad5a2743545f'

Note, that when generating the hash, don't include the tags and note that capitalization and whitespace matter, including leading or trailing whitespace.

<script>var inline = 1;</script>

I ran into (and reported) this Firefox bug when trying to do exactly that. I wanted to guarantee that data in my <form> wouldn’t traverse the network even if some freak JavaScript error prevents the submit event from being cancelled. But Firefox will incorrectly trigger a CSP error based on the action of a submitted <form> even when the submit event is cancelled by return false or event.preventDefault().

The workaround I came up with is to use an invalid blob: URL!

<form action="blob:">

Attempts to submit a <form> to blob: seem to be silently ignored. There’s no navigation, nothing sent over the network, and no CSP error, whether the submit event is cancelled or not. (You probably still want to make every effort to cancel it, of course.)

It seems to work for links too, although Chrome shows an error in the console here:

<a href="blob:">

If you come up with something less horrendous, please share!

As <a href="javascript:void(0);"> violates the Content Security Policy the best thing you can do is not use it and change it by:

 <a href="#" onClick="return false;">

These do the same work without problem.

Related