0

I need to support an older website running on Asp.net, C# and .NET 4.6.1. Security Audit has informed us that we need to enforce Content Security Policy. I have searched google but found no concrete answers to if there is support for webforms (not MVC) in NWebSec. https://docs.nwebsec.com/en/latest/ does mention support for Asp.net 4 as follows:

NWebsec for ASP.NET 4
Historically, NWebsec has been targeting ASP.NET 4. The following packages target ASP.NET 4:

NWebsec
NWebsec.Mvc
NWebsec.Owin

To test the NWebSec support for asp.net webforms, I followed these steps:

  1. Created a new Asp.net webforms project in VS 2017 using .net 4.6.1. Tested it as working.

  2. Added a NuGet package as specified here - https://www.nuget.org/packages/NWebsec/: Install-Package NWebsec -Version 6.0.0

  3. Changed the Web.config file to include the following:

<nwebsec> 
<httpHeaderSecurityModule xmlns="http://nwebsec.com/HttpHeaderSecurityModuleConfig.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="NWebsecConfig/HttpHeaderSecurityModuleConfig.xsd"> 
<securityHttpHeaders> 
<content-Security-Policy enabled="true"> 
<default-src self="true"/> 
<script-src self="true" enabled="true"> 
<add source="maxcdn.bootstrapcdn.com" /> 
<add source="code.jquery.com" /> 
<add source="ajax.googleapis.com" /> 
<!--<add source ="localhost:60252"/>--> 
</script-src> 
<style-src self="true" /> 
<report-uri enableBuiltinHandler="true"/> 
</content-Security-Policy> 
</securityHttpHeaders> 
</httpHeaderSecurityModule> 
</nwebsec>

4.Saved and Ran the project.

5.I got the following errors in Google Chrome Console

`modernizr-2.8.3.js:134 Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-CwE3Bg0VYQOIdNAkbB/Btdkhul49qZuwgNCMPgNY5zw='), or a nonce ('nonce-...') is required to enable inline execution.

localhost/:20 Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' maxcdn.bootstrapcdn.com code.jquery.com ajax.googleapis.com". Either the 'unsafe-inline' keyword, a hash ('sha256-uYoAmCrBFM4tx/Ww+6eFuIJxuwZ3YFRT7fWUTlgnPuE='), or a nonce ('nonce-...') is required to enable inline execution.

localhost/:39 Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' maxcdn.bootstrapcdn.com code.jquery.com ajax.googleapis.com". Either the 'unsafe-inline' keyword, a hash ('sha256-2vr5KMButMK7a+bOf/ned/cPnF2yNooMulXA8E65wGw='), or a nonce ('nonce-...') is required to enable inline execution.

localhost/:52 Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' maxcdn.bootstrapcdn.com code.jquery.com ajax.googleapis.com". Either the 'unsafe-inline' keyword, a hash ('sha256-AJipRK0+ga273yKzZZX3BqTHwvwc1v3R9erdu31Wh6I='), or a nonce ('nonce-...') is required to enable inline execution.`

Clicking on the error in bold in the Chrome Console for example leads to the following block of JavaScript which is being injected into the aspx page by the Asp.net framework


<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['ctl01'];
if (!theForm) {
    theForm = document.ctl01;
}
function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    }
}
//]]>
</script>

I would like to see these Google console errors go away, however, I do not want to allow the 'unsafe-inline' keyword or use the hash ('sha256-uYoAmCrBFM4tx/Ww+6eFuIJxuwZ3YFRT7fWUTlgnPuE='), or a nonce ('nonce-...'). Any help/pointers/support is appreciated.

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
bxsingh1
  • 1
  • 1
  • I do not understand your question's title. The configuration seems to work just fine, emitting the directives you have set in web.config to a CSP-header. – R. Schreurs Nov 17 '22 at 10:15

1 Answers1

0

The <script type="text/javascript"> ... </script> is an inline script therefore you have a few opts to allow it in CSP:

  1. add 'unsafe-inline' token into script-src:
    <add source="'unsafe-inline'" />
    Yes, it's unsafe and reduces the effectiveness of CSP

  2. add three 'hash-sources' into script-src because you have 3 inline scripts (this works for <script> inline blocks but failed in case of <tag onclick='...' or <a href='javascript:...' inline scripts):
    <add source="'sha256-AJipRK0+ga273yKzZZX3BqTHwvwc1v3R9erdu31Wh6I=' />
    <add source="'sha256-2vr5KMButMK7a+bOf/ned/cPnF2yNooMulXA8E65wGw=' />
    <add source="'sha256-uYoAmCrBFM4tx/Ww+6eFuIJxuwZ3YFRT7fWUTlgnPuE=' />

  3. use 'nonce-value' (it's not suitable for Client-Rendering Apps like SPA because you can't generate a new nonce on each page loads):
    <script type="text/javascript" nonce="server_generated_base64_value"> ... /script>

  4. move content of inline <script> to external file and allow it with 'self'.
    Instead of inline <tag onclick='..'> you can use addEventListener().
    Instead of inline <a href='javascript:...'> you can use <a href='#'>.

Also you have the same as above but with inline <style> or <tag style='...': modernizr-2.8.3.js:134 Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self'"
Therefore you have the same opts as above, but for the style-src directive:
<add source="'sha256-CwE3Bg0VYQOIdNAkbB/Btdkhul49qZuwgNCMPgNY5zw=' />
this works in case of inline <style> but fails with <tag style='...'.

PS: As you can see, there is a 3 kinds of 'inline scripts' and 2 kinds of 'inline styles'. And you need to know which of these are used before modify CSP rules. And JS call setAttribute('style', ...) is counted as an inline style too and will be blocked by CSP.

granty
  • 7,234
  • 1
  • 14
  • 21
  • I specifically do not want to use options 1,2 and 3 as I mentioned in my post. 'unsafe-inline' would make the code insecure. Hash sources and nonces are not practical. Hash of a webforms embedded script is unpredictable and might change with deployment environment. There is currently no way to pass a nonce to a dynamically embedded script in webforms. I cannot do option 4 as the block of JS is being injected dynamically by webforms. There is no JS script at compile time for me to separate out into it's own file. Thanks. – bxsingh1 Jan 07 '21 at 12:17
  • 1
    Pls have a look at [Customize web form script generation](https://stackoverflow.com/questions/62722871/customize-web-form-script-generation) there contains a trick with override `__DoPostBack` or override `CreateHtmlTextWriter`. The last one allows to insert a `nonce=` attribute into scripts – granty Jan 21 '21 at 22:06