Preventing Cross-Site Scripting (XSS) and how to make your site more secure

Cross-Site Scripting or XSS as it's known is using and abusing external content through embedding or loading content that should not be allowed on a webpage.

Cross-Site Scripting (XSS) attacks are a type of injection, in which malicious scripts are injected into otherwise benign and trusted web sites. XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end user.

How do you prevent Cross-Site Scripting attacks?

It's easy to prevent if built into your site from the start, the best ways will be listed below. But always remember to only embed TRUSTED content into your website.

Content-Security-Policy (what content can be loaded)

A Content-Security-Policy is a header you send with your requests telling browsers what domains the content on your site content is allowed to be loaded from. But by adding this header no external loaded content will be allowed without listing it in the header, this includes things like scripts, images etc. Here is a simple .htaccess example that will add the header Content-Security-Policy to only load content from your domain. Just place the line in your main site folders .htaccess file, and if you don't have one you can create a new blank file for it and just add the rule.

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

This line will configure your website to only load scripts, images etc. from the same domain the request is made from, but if you are wanting to allow content from other trusted domains you can use the example below.

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

There are rules with this header and we have used a few, this lists where images, scripts or other media is allowed to load from, but you can use any number of header rules to tweak it.

  • default-src: Define loading policy for all resources type in case of a resource type dedicated directive is not defined (fallback)
  • script-src: Define which scripts the protected resource can execute
  • object-src: Define from where the protected resource can load plugins
  • style-src: Define which styles (CSS) the user applies to the protected resource
  • img-src: Define from where the protected resource can load images
  • media-src: Define from where the protected resource can load video and audio
  • frame-src: Define from where the protected resource can embed frames
  • font-src: Define from where the protected resource can load fonts
  • connect-src: Define which URIs the protected resource can load using script interfaces
  • report-uri: Specifies a URI to which the user agent sends reports about policy violation
  • sandbox: Specifies an HTML sandbox policy that the user agent applies to the protected resource

As you can also see after each rule we have domains set, this is called directives, but this header supports more then just 'self' and a list of domains.

Each directive accepts domains seperated by space, and domains can contain both protocol and ports if you want to be specific. Here is a list of other directives you can use.

  • 'none': Nothing is allowed.
  • 'self': Allow resources to load from the websites own (origin) domain.
  • 'unsafe-inline': Allows inline <script> and <style> elements. This can be further secured by specifying a hash of the code.
  • 'unsafe-eval': Allows use of eval() in scripts. Needed for Angular.
  • https: Forces all resources to be loaded over HTTPS.
  • data: Allows resources to be inlined with base64.

Strict-Transport-Security (force site to be loaded over HTTPS)

This header is a great thing to add to your .htaccess file as it forces browsers to only load content on your site over HTTPS (SSL).

Header set Strict-Transport-Security "max-age=631138519; includeSubDomains"

X-Frame-Options (iframe rules)

Disallow your page to be embedded within iframes. Just like the other headers just add this to your main site folders .htaccess file.

Header set X-Frame-Options DENY

Can NodeHost do this for me?

This is not a host side problem this is a website code problem. If we enabled the rules any external images, scripts, or other content would not load by default, and in the process breaking many CMS systems.