Prevent XSS attack on Sitecore: Use of in-built .NET validation
/Out of the box, when you test your Sitecore CMS website for XSS - Cross Scripting attack you will notice that nothing will happen on your browser, the webpage will open as usual.
For instance, your-host.com?<script>alert('attack');</script>
will simply render your webpage with no validation.
Reason:
Sitecore CMS comes with the below default configuration
<configuration>
<system.web>
<pages validateRequest="false" controlRenderingCompatibilityVersion="4.0">
<controls>
<add tagPrefix="sc" namespace="Sitecore.Web.UI.WebControls" assembly="Sitecore.Kernel" />
<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add tagPrefix="sc" namespace="Sitecore.Web.UI.WebControls" assembly="Sitecore.Analytics" />
</controls>
</pages>
</system.web>
</configuration>
You will notice that validateRequest="false"
. The reason behind this default value is that Sitecore uses some URL format for its back-office (save and other available options)
In order to use .NET's in-built request handler you will need to follow below steps:
1. ADD BELOW LINES TO THE WEB.CONFIG FILE.
-Set validateRequest to true
.
<configuration>
<system.web>
<pages validateRequest="true" controlRenderingCompatibilityVersion="4.0">
<controls>
<add tagPrefix="sc" namespace="Sitecore.Web.UI.WebControls" assembly="Sitecore.Kernel" />
<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add tagPrefix="sc" namespace="Sitecore.Web.UI.WebControls" assembly="Sitecore.Analytics" />
</controls>
</pages>
</system.web>
</configuration>
-Add RequestValidationMode="2.0"
to HttpRuntime
.
<configuration>
<system.web>
<httpRuntime maxRequestLength="512000" executionTimeout="600" enableKernelOutputCache="false" requestValidationMode="2.0" />
</system.web>
</configuration>
Notice: At this point, when you will open your back-office, you will notice that save and some other functionalities will throw below error
A potentially dangerous Request.QueryString value was detected from the client
2. OVERRIDING SITECORE'S PREPROCESSOR WITH OUR CUSTOM CODE
To overcome this, we will need to override Sitecore's default SuppressFormValidation from its preprocessor by creating our own which will instruct Sitecore to ignore this PreProcessor if the actual site is the shell, admin etc
a) Add sites we want to ignore in our web.config file using a patch.
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<settings>
<!-- Sites to ignore by custom processors -->
<setting name="SitesToIgnoreByCustomProcessors" value="shell,login,admin,service,scheduler,system,publisher,modules_shell,modules_website"/>
</settings>
</sitecore>
</configuration>
b) Create our custom class
namespace Sitecore.Loic.Blog.Extensibility.Processors
{
public class SuppressFormValidation : Sitecore.Pipelines.PreprocessRequest.SuppressFormValidation
{
private static readonly List<stringsitesToIgnoreByCustomProcessors = Settings.GetSetting("SitesToIgnoreByCustomProcessors", string.Empty).ToLowerInvariant().Split(new char[1]
{
','
}, StringSplitOptions.RemoveEmptyEntries).ToList();
public override void Process(PreprocessRequestArgs args)
{
var sitecoreContext =
SiteContextFactory.GetSiteContext(args.Context.Request.Url.Host, args.Context.Request.Url.PathAndQuery);
if (!sitecoreContext.HasValue())
{
return;
}
if (sitesToIgnoreByCustomProcessors.Contains(sitecoreContext.Name.ToLowerInvariant()))
{
return;
}
base.Process(args);
}
}
}
c) Create a patch to override Sitecore's SuppressFormValidation in the config file.
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
preprocessRequest>
<processor type="Sitecore.Pipelines.PreprocessRequest.SuppressFormValidation, Sitecore.Kernel">
<patch:attribute name="type">Sitecore.Loic.Blog.Extensibility.Processors.SuppressFormValidation, Sitecore.Loic.Blog</patch:attribute>
</processor>
</preprocessRequest>
</pipelines>
</sitecore>
</configuration>
This post describe one of multiples barriers to keep our application safe from hackers but yet not enough to garantee a full secure application. Other features will involve application's infrastructure and design. If you want to build an application which complies with the common security features, I would advise you to follow OWASP top 10 https://www.owasp.org/index.php/Top_10_2013-Top_10