Monday 15 February 2021

Simple Ways to Improve Episerver Websites Security

In my previous post, Basic Episerver Coding Best Practices I briefly mentioned the website security.  I thought I could go a little bit in details about basic security measure you can take in your ASP.NET website or in particular Episerver website. 

Each project comes with its own set of security requirements but I usually start from the following list to cover the basics. Keep in mind the list below are just suggestions and you can always opt-out or include other measures to quench your thirst for your website security. 

Before we go into detail lets do a quick security check or your website. I usually use these tools (https://www.immuniweb.com/websec/ & https://securityheaders.com/)  but there are so many free tools available to quickly give you a sanity check of your website security. 

Episerver has a suggestive security checklist for the websites (https://world.episerver.com/documentation/developer-guides/CMS/learning-path/security-checklist/). Some of the suggestions in this post are taken from the checklist.

Use HTTPS

Implement Rewrite Rule to ensure always redirect HTTP to HTTPS

   <rule name="HTTPS rewrite" stopProcessing="true">
        <match url="^(.*)$" ignoreCase="false" />
        <conditions>
            <add input="{HTTP_X_FORWARDED_PROTO}" pattern="^http$" ignoreCase="false" />
        </conditions>
        <action type="Redirect" redirectType="Found" url="https://{SERVER_NAME}{URL}" />
    </rule>

Secure Cookies

<system.web>
    <httpCookies sameSite="Lax" httpOnlyCookies="true" requireSSL="true"/>
</system.web>

Using the Same-Site Cookie Attribute to Prevent CSRF Attacks

     <outboundRules>
        <clear />
        <rule name="Add SameSite" preCondition="No SameSite">
          <match serverVariable="RESPONSE_Set_Cookie" pattern=".*" negate="false" />
          <action type="Rewrite" value="{R:0}; SameSite=lax" />
        </rule>
        <preConditions>
          <preCondition name="No SameSite">
            <add input="{RESPONSE_Set_Cookie}" pattern="." />
            <add input="{RESPONSE_Set_Cookie}" pattern="; SameSite=lax" negate="true" />
          </preCondition>
        </preConditions>
      </outboundRules>

You can read more about SameSite cookies at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite

Session Cookie Expires Attribute

The session cookie will be stored on the user's hard drive. An attacker or local user who has access to this cookie may be able to log into the application by resubmitting the session cookie.

The "Expires" attribute should not be set. This will cause the cleanup management of the browser to be used for deleting the cookie once the browser is closed.


Turn off Detailed Errors and Set Compilation Mode to Release


<compilation debug="false" />
<episerver.framework>
    <clientResources debug="false"/>
  </episerver.framework>

JavaScript Code Obfuscation

The JavaScript code is human-readable. An attacker is therefore able to analyze the source code to find vulnerabilities. Confidential details can also be revealed through the source code (e.g., developer information or source code comments).

Make sure that JavaScript code should be automatically obfuscated on deployment.

For manual obfuscation take a look at this online tool https://obfuscator.io/

Implement Server-Side Input Validation

Input that is not correctly validated can trigger unexpected behaviour in the backend application, which might lead to security vulnerabilities.

Any input for the application should be checked to verify that it only contains valid data.

Improving Security Using Custom Headers

The following headers should be implemented to improve the security in Episerver project


X-Frame-Options

The X-Frame-Options header ensures that hackers don't iframe the site, in order to trick the user into clicking links which they never intended to. If we are using ASP.NET MVC 5 or newer, this header is added automatically. 

Adding the header in previous versions or other web frameworks is easy using web.config:

  
  <system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="X-Frame-Options" value="SAMEORIGIN"/>
      </customHeaders>
    </httpProtocol>
  </system.webServer>

If we are using iframes on the same domain, we can change the value to SAMEORIGIN.


X-Xss-ProtectionX-ASPNET-VERSION

The X-Xss-Protection is a feature implemented in a most modern browser, which will stop loading the page when a cross-site scripting attack is detected. 

Adding the header happens through web.config as well:

<system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="X-XSS-Protection" value="1; mode=block"/>
      </customHeaders>
    </httpProtocol>
  </system.webServer>

X-Content-Type-Options

To avoid MIME type sniffing, we can add the X-Content-Type-Options header. This makes it harder for hackers to guess the right mime type, by inspecting the content. Adding the header is easily done through web.config:

 
 <system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="X-Content-Type-Options" value="nosniff "/>
      </customHeaders>
    </httpProtocol>
  </system.webServer>

Referrer-Policy

Browsers automatically add the Referer header, when a user clicks a link on the site. This means that a linked website will be able to see where the users are coming from. While this is a great feature for Analytics, we may have sensitive information in the URLs, which we don't want to forward to other domains. 

To remove the referrer entirely, add the following header to web.config:

 
 <system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Referrer-Policy" value="strict-origin"/>
      </customHeaders>
    </httpProtocol>
  </system.webServer>

In real life, we may want another value for Referrer-Policy. Removing the referrer entirely makes it impossible to see the internal traffic flow on the website. Check out Referrer-Policy on mozilla.org for a list of possible values.


X-Permitted-Cross-Domain-Policies

To restrict Flash components to make cross-origin requests, we should disable it entirely (unless we are using Flash of course). 

To do so, add the X-Permitted-Cross-Domain-Policies to web.config:

<system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="X-Permitted-Cross-Domain-Policies" value="none"/>
      </customHeaders>
    </httpProtocol>
  </system.webServer>

Strict-Transport-Security

After implementing implemented HTTPS on the website, we can prevent any communication happening over HTTP using the Strict-Transport-Security header:

  
 <system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains"/>
      </customHeaders>
    </httpProtocol>
  </system.webServer>

The max-age value tells browsers to use this setting for the specified number of seconds. In this case a year. The includeSubDomains part can be excluded if we are hosting non-HTTPS websites on subdomains.


X-Powered-By

The X-Powered-By header is automatically added by ASP.NET. To make it less obvious which technology we are using to host our website, we should remove this header through web.config:

 
  <system.webServer>
    <httpProtocol>
      <customHeaders>
        <remove name="X-Powered-By"/>
      </customHeaders>
    </httpProtocol>
  </system.webServer>

X-AspNetMvc-Version

Much like X-Powered-By, X-AspNetMvc-Version is a header automatically added by the framework. To avoid telling hackers that we use MVC and which version, we should remove it. X-AspNetMvc-Version cannot be removed through web.config, but we can disable it from code. 

Add the following to the Global.asax.cs:

public class EPiServerApplication : EPiServer.Global
{
	protected void Application_Start()
	{
		 MvcHandler.DisableMvcResponseHeader = true;
	}
}

 
<system.web>
	 <httpRuntime enableVersionHeader="false" />
</system.web>

Server

ASP.NET also reveals the server hosting the application. If a hacker knows that we are using IIS, this narrows the number of weaknesses that he/she needs to try. 

To remove the Server header, remove it from code in either a filter or through Global.asax.cs:

public class EPiServerApplication : EPiServer.Global
{
   protected void Application_PreSendRequestHeaders()
   {
       if (HttpContext.Current != null)
       {
           HttpContext.Current.Response.Headers.Remove("Server");
       }
   }
}

Feature-Policy

The Feature-Policy header is a recent addition to the range of security-related headers. When specifying the header, we tell the browser which features our site uses or not. This is a great feature, especially if we embed other websites. 

To add the header, make the following change in web.config:

 
   <system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Feature-Policy" value="accelerometer 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; payment 'none'; usb 'none'"/>
      </customHeaders>
    </httpProtocol>
  </system.webServer>

Content-Security-Policy

Set basic Content-Security-Policy header values that enforce https:// for external styles and scripts and allows inline scripts in the website.

  
<system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Content-Security-Policy" value="default-src * data:; script-src https: 'unsafe-inline' 'unsafe-eval'; style-src https: 'unsafe-inline'"  />
      </customHeaders>
    </httpProtocol>
  </system.webServer>

Disable HTTP TRACE Method

The HTTP TRACE method is designed for diagnostic purposes. If enabled, the web server will respond to requests that use the TRACE method by echoing in its response the exact request that was received.

This behaviour is often harmless but occasionally leads to the disclosure of sensitive information such as internal authentication headers appended by reverse proxies. This functionality could historically be used to bypass the HttpOnly cookie flag on cookies, but this is no longer possible in modern web browsers.

  <system.webServer>
    <security>
      <requestFiltering>
        <verbs>
          <add verb="TRACE" allowed="false" />
        </verbs>
      </requestFiltering>
    </security>
  </system.webServer>

References:

About the Author

Adnan Zameer, Lead Developer at Optimizley UK, is a certified Microsoft professional, specializing in web app architecture. His expertise includes Optimizley CMS and Azure, showcasing proficiency in crafting robust and efficient solutions.

0 comments :

Post a Comment