I’ve just run a couple of our mojoPortal web sites through the test on https://asafaweb.com and thought I’d write up some notes on how to get the best possible test results (and therefore presumably the most secure sites!). We are starting from a point where all the basic security measures are in place – folder permissions, custom machine key, running the site under SSL.
The tests that did not immediately pass were:
Request validation: Fail
OK so we find <pages validateRequest="false" … in web.config.
But we are assured this is deliberate and acceptable in mojoPortal because, as Joe Audette explained,
validateRequest is false because we do our own validation of inputs and setting it to true causes problems/errors when posting back html content from a wysiwyg editor.
Excessive headers: Warning
So our IIS server and site are revealing several pieces of information about the technologies behind the site, and we are better concealing these http headers.
Specifically we have:
- Server which can be turned off with URLscan by setting RemoveServerHeader=1 in UrlScan.ini (there are other ways, but this is by far the simplest).
- X-Powered-By which can be turned off in IIS Manager: select the web site, then open HTTP Response Headers and remove this one.
- X-AspNet-Version which can be suppressed by adding this attribute to the httpRuntime setting in web.config: <httpRuntime … enableVersionHeader="false" />
Secure cookies: Fail
In line with the mojoPortal documentation on SSL we already had the attribute in bold:
<forms name=".mojochangeme" protection="All" timeout="50000000" path="/" cookieless="UseCookies" requireSSL="true" />
but we were still failing the test until we also added this into the system.web section:
<httpCookies httpOnlyCookies="true" requireSSL="true" />
Joe Audette said:
Adding the <httpCookies element as you have just means that any other cookies issued for the web site would also be kept secure, but as far as I know any other cookies we are creating are only for cosmetic purposes such as the one to toggle the collapse state of the admin toolbar etc.
So I think we were secure anyway, but it’s nice to pass the test.
Clickjacking: Warning
This was easily blocked by preventing our site from being run in an iframe. This is achieved in IIS Manager: select the web site, then open HTTP Response Headers, and add a new one as follows:
If we are using an iframe within the site, for something like a keep-alive, another value for this setting is "SAMEORIGIN" - this allows iframes in the site to host content that is within the same domain. If we want our site to be displayed in an iframe within a known other site, we can use "ALLOW-FROM uri".
View state MAC: Not tested
Not tested apparently because the viewstate is encrypted in mojoPortal, but it turns out versions of mojoPortal before 2.4.0.2 had enableViewStateMac="false" which is not what we want. This has been removed, meaning it is set to true by default, in version 2.4.0.2, but if running an earlier version we should ensure this setting has only the following attributes:
<pages validateRequest="false" viewStateEncryptionMode="Auto" maxPageStateFieldLength="500" controlRenderingCompatibilityVersion="4.0" clientIDMode="AutoID">
So on sites running mojoPortal 2.4.0.2 or later, no change needed.
Summary
So we needed to make two changes in web.config, remove one http header and add another one. Plus install and configure URLscan if it's not already present. These are one-off changes for a server and/or site except the web.config settings. mojoPortal upgrades generally involve overwriting the web.config, so it’s important to keep separate notes about what default settings need to be changed again after an upgrade. We always keep these notes for each site in a UpgradeNotes.config file in the root folder of the site.
*** UPDATE ***
Further testing of some sites with ZAP and https://securityheaders.com identified two more http headers (in italics below) that should be set to improve security. Overall the header settings can be wrapped up by including this section in system.webServer:
<system.webServer>
...
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By" />
<add name="X-Frame-Options" value="SAMEORIGIN" />
<add name="X-XSS-Protection" value="1" />
<add name="X-Content-Type-Options" value="nosniff" />
<add name="Referrer-Policy" value="no-referrer-when-downgrade" />
<add name="strict-transport-security" value="max-age=31536000; includeSubDomains" />
</customHeaders>
</httpProtocol>
...
And it also pointed out that auto-complete was not disabled on the login screen (which leaves accounts vulnerable where more than one user may share a machine). This can be suppressed with the following in user.config:
<add key="DisableAutoCompleteOnLogin" value="true"/>