Dynamic scripts with CSP (Content Security Policy)

An ASP.NET WebForms project adds several scripts to the page on the fly. Since these scripts don’t exist in the compile time, how to whitelist these dynamic scripts with CSP?

The title and the first paragraph may sound pretty abstract. Let’s look at the fundamentals first.

Are you receiving “Custom JavaScript is not allowed” error? Check this post out.

What is CSP (Content Security Policy)?

CSP is an HTTP header that we use to prevent cross site scripting (XSS) and packet sniffing attacks. Long story short: By using CSP header, we tell the browser which scripts or other resources we trust. The browser executes these resources and ignores the rest.

Here is an example CSP header:

object-src 'none';  script-src 'nonce-{random}' 'unsafe-inline'

As mentioned in this article, this header means:

object-src 'none' Prevents fetching and executing plugin resources embedded using <object>, <embed> or <applet> tags. The most common example is Flash.

script-src nonce-{random} 'unsafe-inline' The nonce directive means that <script> elements will be allowed to execute only if they contain a nonce attribute matching the randomly-generated value which appears in the policy.

Note: In the presence of a CSP nonce the unsafe-inline directive will be ignored by modern browsers. Older browsers, which don’t support nonces, will see unsafe-inline and allow inline scripts to execute.

For more information about CSP:

If the browser blocks a resource because it doesn’t comply with CSP, you will see this error in browser logs:

Refused to execute inline script because it violates the following Content Security Policy directive: “script-src ‘self'”. Either the ‘unsafe-inline’ keyword, a hash, or a nonce is required to enable inline execution.

Dynamic scripts with CSP

How to prevent executing dynamic scripts with CSP?

Using unsafe-inline removes the error above (“Refuse to execute inline script“). However, it is not a secure way of whitelisting dynamically created scripts.

script-src 'self' 'unsafe-inline'

Other than using unsafe-inline, it doesn’t seem like there is another way to whitelist dynamic scripts with CSP. There are a few open questions below if you want to keep posted about future updates on this topic.

PageMethods is not working (Solved)

PageMethods is a JavaScript class that you can use to call a server-side function. It’s basically an AJAX call which works asynchronously. In .NET world, you can use PageMethods to call a C# code-behind function. If you think that PageMethods is not working no matter what you do, keep reading.

For PageMethods to work, you need a JavaScript function on the client-side and a WebMethod function on the server-side.

Sample JavaScript code (Put it in asp:content section of Default.aspx):

<script type="text/jscript">

   function callCodeBehind() {
		PageMethods.GetMessage("test string", onSuccess, onFailure);
	}

   function onSuccess(result, usercontext, methodname) {
	   alert(result)
   }

   function onFailure(error, usercontext, methodname) { alert("failed: "+ error.get_message()); }

</script>

Sample C# code (code-behind file – Default.aspx.cs):

public partial class Welcome : System.Web.UI.Page
{
	protected void Page_Load(object sender, EventArgs e)
	{

	}

	[WebMethod]
	protected static void GetMessage(string val)
	{
		return "doingit";
	}
}

A button to call the JavaScript function (in Default.aspx)

<button onclick="callCodeBehind()">Click me</button> 

ScriptManager (in Site.Master – note that EnablePageMethods is set to True):

<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="True">
</asp:ScriptManager>

Having issues with your AJAX call as part of Google reCAPTCHA implementation? Check this post out.

What to do if PageMethods is not working

If you have the code above, your project should be working. In exceptional cases, you may not receive the return value. In my case, the issue was the post-back that was happening after clicking the button.

The reason behind the post-back was that friendy URL setting. As soon as I disabled it, my PageMethods function started working.

In order to disable friendly URL feature, remove or comment out the line below in your RouteConfig file.

routes.EnableFriendlyUrls(settings)
Solved PageMethods is not working issue
Successfully returned the value

Are you losing data after a post-back? Here is what to do.

References:

Secure cookie flag

I have noticed that there is a vulnerability which comes up in results of many penetration tests: “The application doesn’t user secure cookie flag”.

Penetration testers generally mark this vulnerability as “Severity Low” but it doesn’t mean that you should ignore it. It has an important role for protecting your data. The best part of it is that it is very easy to fix it!

First things first, what is secure cookie flag? 

What is secure cookie flag?

When cookies are sent in clear text as part of HTTP requests, unauthorized parties can access to their content by intercepting the request (also called as man-in-the-middle attack).

Accessing to a cookie’s content may result in unauthorized access to users’ personal information and other sensitive data such as authentication tokens that are used to login web applications.

Secure cookie flag is basically a parameter that forces applications to use secure cookies so that browser and web server transfer cookies only through secure (HTTPS) connection. Therefore, unauthorized parties cannot see the cookie content. Microsoft recommends configuring web applications to force using secure cookies.

Having a problem with ASP.NET session IDs? Check this post out.

How to fix it?

In order to force an ASP.NET application to enable using secure cookies, add the following line into the section of the web.config file:

<httpCookies requireSSL="true"/>

If you are using Forms Authentication, make sure to include “requireSSL” attribute in section. For example:

<system.web>
    <authentication mode="Forms">
        <forms requireSSL="true">
            <!-- forms content -->
        </forms>
    </authentication>
</system.web>

Confirm the fix

In order to confirm the secure flag in a cookie, use an intercepting proxy such as F12 Developer Tools in browser or a third-party tool such as Fiddler. Check the response headers to see if the “secure” word is there.

Secure cookie flag is displayed
Cookie is secured

As you see in the screenshot below, “test” cookie is “secure”. Therefore, it will show up only in HTTPS connections.

References