Intro to Website Security

Welcome to a brief introduction to Website Security – FOCUS ON: Content Security Policy (CSP).

Nowadays, it’s very easy and fast to create and deploy websites. Services like WIX, Squarespace, Webflow, Wordpress, and others make it so easy to create beautiful websites in a matter of hours. Almost anyone with a little bit of time at hand can do that.

However, not everyone thinks or even knows about how to properly secure their website, once it is deployed and public. Most services do offer some basics and take care of some features and configurations under the hood, such as HTTPS (SSL Certificate), but that is barely scratching the surface of website security. Especially, if you are actively being targeted by hackers or other threat actors. And even if you are not being targeted, it is good to at least understand that your and most other websites have a certain degree of security that will maintain you and your information safe, (or not).

Let’s dive right into it. Below a quick overview…

Table of Contents


The OWASP Top 10

Here you will find the top 10 web application security risks: Top 10 Web Application Security Risks – OWASP

In this blog post you’ll learn a little bit more about the X-XSS-Protection (Cross-Site Scripting (XSS)), specifically about the Content Security Policy (CSP).

Content Security Policy (CSP)

“The HTTP Content-Security-Policy response header allows web site administrators to control resources the user agent is allowed to load for a given page."

This is probably one of the most forgotten aspects in website security. CSP allows you to set certain parameters for your website in order to prevent specific attacks or unauthorized access or modifications from external resources.

Here a small example of a CSP in a website header block:

<meta http-equiv="Content-Security-Policy" content="default-src https://cdn.example.net; child-src 'none'; object-src 'none'">

“Fetch directives control the locations from which certain resource types may be loaded."

All fetch directives, such as default-src or child-src, have a specific meaning and purpose. Some good places to start learning more about CSP and the fetch directives are these websites:

Additionally, if you want to know what CSP a specific website has implemented, you can use these tools:

Implementation of a CSP

In order to implement CSP on your website, it depends on what your website is built on or what hosting provider you are using. Most often, you configure your CSP on server side configurations. But in some cases you might apply it on the website header as a meta tag (as shown in the first example above).

The most important part of implementation though is to know your own website: what external sources, links, external resources is your website using? Are they all really necessary? Do those resource locations change over time, or are they static? Depending on what you answer to each of these questions, you will have to change and adapt your CSP to your own needs – step by step.

An easy way to figure those out is to start with implementing the default CSP Content-Security-Policy: "default-src 'self';, and then when you inspect your website (Command + Shift + C on MacOs / Control + Shift + C on Windows) with Google Chrome, the console will display what resources and hashes need to be added to your CSP in most cases. Do it step by step, in order to be able to fix anything that you might accidentally break.

Don’t forget that CSP varies from website to website. It mostly depends on what resources you want your website to be able to load.

Below you will find a few general examples on how to implement CSP on different platforms:

Apache

In your httpd.conf main configuration file – usually located in /etc/httpd/conf or /etc/httpd/conf or /etc/apache2/ – add your CSP.

Here is a simple example:

Header set Content-Security-Policy "default-src 'self';"

If you are using Wordpress, you can either use a Wordpress plugin to add your CSP, or you can add your policy to the default .htaccess distributed configuration file.

Here is a simple example:

<IfModule mod_headers.c>
  Header set Content-Security-Policy "default-src 'self'; img-src 'self' http: https: *.gravatar.com;"
</IfModule>

Nginx

In your nginx.conf configuration file – usually located in the /etc/nginx or /usr/local/nginx/conf or /usr/local/etc/nginx directory –, add your CSP at the end of your server {} block.

Here is a simple example:

add_header Content-Security-Policy "default-src 'self';";

Netlify

Add a file named _headers to your website’s root directory.

Here an example of a _headers file:

/*
  Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
  Content-Security-Policy: default-src 'self' https:; img-src 'self'; script-src 'self'; style-src 'self'; font-src 'self' https://fonts.googleapis.com/ https://fonts.gstatic.com/; child-src 'none'; object-src 'none'; report-uri https://YOUR_DOMAIN.report-uri.com/r/d/csp/reportOnly
  X-Frame-Options: SAMEORIGIN
  X-XSS-Protection: 1; mode=block
  X-Content-Type-Options: nosniff
  Referrer-Policy: no-referrer
  Permissions-Policy: fullscreen=(self "https://www.YOUR_DOMAIN.com/"), geolocation=*
  Cache-Control: max-age=0
  Cache-Control: no-cache
  Cache-Control: no-store
  Cache-Control: must-revalidate

Source: Netlify Docs

Cloudflare

Visit the Workers tab within your Cloudflare account. Click the Manage Workers button and then click Create a Worker. Add the following code to the Worker, and add your security header parameters.

const securityHeaders = {
        "Content-Security-Policy": "upgrade-insecure-requests",
        "Strict-Transport-Security": "max-age=1000",
        "X-Xss-Protection": "1; mode=block",
        "X-Frame-Options": "DENY",
        "X-Content-Type-Options": "nosniff",
        "Referrer-Policy": "strict-origin-when-cross-origin"
    },
    sanitiseHeaders = {
        Server: ""
    },
    removeHeaders = [
        "Public-Key-Pins",
        "X-Powered-By",
        "X-AspNet-Version"
    ];

async function addHeaders(req) {
    const response = await fetch(req),
        newHeaders = new Headers(response.headers),
        setHeaders = Object.assign({}, securityHeaders, sanitiseHeaders);

    if (newHeaders.has("Content-Type") && !newHeaders.get("Content-Type").includes("text/html")) {
        return new Response(response.body, {
            status: response.status,
            statusText: response.statusText,
            headers: newHeaders
        });
    }

    Object.keys(setHeaders).forEach(name => newHeaders.set(name, setHeaders[name]));

    removeHeaders.forEach(name => newHeaders.delete(name));

    return new Response(response.body, {
        status: response.status,
        statusText: response.statusText,
        headers: newHeaders
    });
}

addEventListener("fetch", event => event.respondWith(addHeaders(event.request)));

Code source: GitHub

More info on Workers Docs

Note: Cloudflare will grant you 100,000 free worker requests per day on the FREE plan.

Back on the Workers dashboard click the Add Route button.

  • Configure your route using Cloudflare’s Matching Behavior syntax.
  • Select the Worker you just created.
  • Expand the “Request limit failure mode” accordion to configure Failure mode (select “Fail” open) so that users can continue to use your website if you run out of requests.
  • Add additional routes to prevent the CSP worker from processing requests for static assets (such as img, style, scripts, assets, etc.).

Source for Cloudflare: Thanks to maxchadwick

Alternatively, check out this article: GeekFlare

Report URI

“Report URI provides real-time security reporting for your site."

It is a useful feature built into content-security-policy that allows you to get insights on your policy. The probably most useful website for this is the one below:

Report URI allows you to easily display your CSP, as well as any errors that might occur over time. It has many more features, but it is definitely a good place to start learning about analytics.

Implementing HTTPS

Another important aspect of Website Security is HSTS and HTTPS. Normally, your hosting provider should allow you to activate HTTPS for your domain, providing you with SSL Certificates.

Now, we can submit our domain to be preloaded. Being added to the HTTP Strict Transport Security (HSTS) preload list, allows our website to be hardcoded into the browser, and your site should not be available in an insecure way anymore.

The following page allows us to submit our domain:

And then we can test our SSL and security level on the following page:

If you are using Cloudflare, then take a look at those amazing short YouTube tutorials:

Web Security Analysis Tools

There are also other several tools out there that can be helpful to do further security checks and analysis on websites. Check these out:

Other good places to start learning more are these articles (or just Google):

Server and Network Security

Let’s not forget websites are served by servers. Security actually starts right there (Security Misconfiguration). The level of your server security depends on who is your hosting provider, what are you web admin configurations, how’s your network firewall configured, and several other aspects.

There are many more aspects and more things to take into account when working on your website’s security. Google can be your best friend for that. Feel free to also contact your hosting provider to learn more about how to properly secure your website.

Disclaimer

This is a very general introduction to Website security, specifically to Content Security Policy (CSP). Educational purposes only. There are many more aspects to website security which are not covered here, and all implementations might differ from situation to situation, technology to technology. Remember, you are responsible for your own actions – this is merely an educational intro. Properly inform yourself, keep learning, keep testing, and feel free to share your learnings and experiences as I do. Hope it was helpful!

David J. K. Tofan
David J. K. Tofan
Digital Consultant

I am a self-proclaimed world-citizen with an entrepreneurial spirit.

Related