Tips to make your website more secure

by Kristian Ranstrom
November 3, 2021
3 min read

There's actually a lot more to securing a website than just slapping on an SSL cert and delivering it over HTTPS.  While that's a great first step, with the use of certain meta tags, headers and approaches, you can actually secure your site against more diabolical threats.  I'm taking the following approaches using an asp.net standpoint, but the techniques are universal, just apply them in your own language.

Ensure HTTPS Delivery

This may be the most obvious, but allowing any traffic over http and not https is a no-no.  Adding rewrites should be a mandatory check on the to-do list:

<system.webServer>
    <rewrite>
      <rules>
        <rule name="Redirect to https" stopProcessing="true">
          <match url=".*" />
          <conditions>            
            <add input="{HTTPS}" pattern="off" ignoreCase="true" />
          </conditions>
          <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" appendQueryString="false" />
        </rule>
      </rules>
    </rewrite>
</system.webServer>

or with .net core, you can add the following to the Configure in the Startup

public void Configure(IApplicationBuilder app)
{
   var options = new RewriteOptions().AddRedirectToHttpsPermanent();
   app.UseRewriter(options);
}

More details can be found here on how to use rewrites.

Secure Your Cookies

By default, cookies are not delivered via SSL, even though the site is.  You can update this and make them secure by requiring SSL:

<system.web>
    <authentication mode="None">
      <forms name=".EPiServerLogin" loginUrl="Util/login.aspx" timeout="120" defaultUrl="~/" requireSSL="true" cookieless="UseCookies" />
    </authentication>
</system.web>

or with .net core, you can add the following to the Configure in the Startup

app.UseCookiePolicy(
new CookiePolicyOptions
{
 Secure = CookieSecurePolicy.Always
});  

Apply Security Headers

A lot of web server will add in a header that specifies which type of web server it is (IIS, nginx, apache).  This can tip-off hackers how your site is run.  They can probably figure it out without this header, by why give them any clues.  I always remove it.  There are several other security headers I use and you can see them below.  

<system.webServer>
    <httpProtocol>
      <customHeaders>
        <remove name="X-Powered-By" />
        <remove name="X-AspNet-Version" />
        <remove name="Server" />
        <add name="Strict-Transport-Security" value="max-age=63072000" />
        <add name="X-Content-Type-Options" value="nosniff" />
        <add name="X-Frame-Options" value="SAMEORIGIN" />
        <add name="Content-Security-Policy" value="default-src https: 'unsafe-eval' 'unsafe-inline'; img-src https: data:;" />
      </customHeaders>
    </httpProtocol>
</system.webServer>

Or in in the Startup of .net core:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
   if (env.IsDevelopment())
   {
       app.UseDeveloperExceptionPage();
   }

   // Add headers, add this towards the top of the function:
   app.Use((context, next) =>
   {
       context.Response.Headers["Strict-Transport-Security"] = "max-age=63072000";
       context.Response.Headers["X-Content-Type-Options"] = "nosniff";
       context.Response.Headers["X-Frame-Options"] = "SAMEORIGIN";
       context.Response.Headers["Content-Security-Policy"] = "default-src https: 'unsafe-eval' 'unsafe-inline'; img-src https: data:;";
       return next.Invoke();
   });

   // put this underneath
   app.UseMvc();
}

Strict-Transport-Security - This headers tells browsers to only allow access to the site via HTTPS, not HTTP.

X-Content-Type-Options - setting the value to "nosniff" will block requests to resources like css/js that don't match their specified mime types.  This setting tells browsers to not guess about the mime types that are downloading.

X-Frame-Options - Setting to SAMEORIGIN tells browsers that the page can only be iframed from a page with the same domain.  Using this can stop security risks via click-jacking by not allowing other sites to load this page into their website.  

Content-Security-Policy - This powerful header tells the browser about what is allowed for each type of entity, whether it be image, script, stylesheet, or any other type of file.  In the above, I'm setting a default policy to only allow HTTPS, but I do allow some lesser secure options like 'unsafe-eval' and 'unsafe-inline', which are necessities with some projects due to how a particular system needs to work.  Images also must be HTTPS but can also be data strings, which is less secure, but are sometimes necessary.

Version Header
Also, some sites automatically add in a Version Header, which again, is not really secure.  Removing it is as easy as updating the web.config:

<httpRuntime targetFramework="4.8" requestValidationMode="2.0" enableVersionHeader="false" />

Hopefully these tips will help make your site more secure.  Happy coding!