Implementing Security Headers has become extremely important as the number of breaches and data thefts are increasing rapidly every day. Security Headers offer an easy-to-implement part of the solution: Simply pass specific HTTP Headers to protect your website from common attacks like XSS, code injection, clickjacking, etc.
What are Security Headers?
Web applications can send special commands to the browser to protect websites from breaches or client-side vulnerabilities, known as Security Headers.
When a user visits a website in their browser, the server responds with HTTP Response Headers. These headers, composed of metadata, share information with the client and server. This shared information defines how the browsers should interact with the website. Security headers provide powerful protection from various web app vulnerabilities and threats.
This blog will break down the following important security headers:
- Content Security Policy (CSP)
- X-Content-Type-Options
- X-Frame-Options
- Cross-Origin Resource Policy (CORP)
- Cross-Origin Embedder Policy (COEP)
- Cross-Origin Opener Policy (COOP)
- Referrer-Policy
- Permissions-Policy
- HTTP Strict Transport Security (HSTS)
Importance of Security Headers
HTTP security headers are a fundamental part of website security; however, only 1.6% of the top one million websites have implemented Content Security Policy (CSP) and only a mere .2% of sites implement CSP-Report-Only.
Shocking, right?! The lack of CSP HTTP Header takes down the defense mechanisms against Cross-Site Scripting (XSS) and other client-side injection attacks. British Airways data breach is one of the incidents which illustrates how due to a lack of client-side security, the names, street addresses, email addresses, credit card numbers, expiration dates and Card security codes of 380,000 customers were exposed, which remained undetected for 15 days.
Adding Security with Layer0’s EdgeJS
With Layer0’s deployment platform, things like TLS are automatically configured for each deploy link, so developers can ship securely by default. In this blog, we closely look at important security headers and an example to show how quickly you can secure a website with routes config on Layer0.
Getting Started with Security Headers with Edgio
Content Security Policy (CSP)
How CSP Prevents Loading Resources From Not-Allowed Origins
Content-Security-Policy provides an added layer to prevent Cross-Site Scripting (XSS) attacks by restricting scripts, styles, images, fonts and media from being loaded (and executed) from specific allowed origins. Regardless of how secure your backend is, if bad actors can attack the code that runs in the browser instead of on the server, user session data is compromised and confidential information is exposed. One of the many examples (such as the British Airways Data Breach) is the MageCart attack on Ticketmaster’s payment module. The Ticketmaster breach resulted in 40,000 victims of credit card theft and remained active for 5 months before being caught! All just by injecting a form skimming script inside the browser.
const { Router } = require(‘@layer0/core/router’) const ContentSecurityPolicy = `default-src ‘self’; script-src ‘self”unsafe-eval”unsafe-inline’ *.layer0.co; style-src ‘self”unsafe-inline’ *.googleapis.com; img-src * blob: data:; media-src ‘none’; connect-src *; font-src ‘self’ *.gstatic.com; `; new Router() .get(“/:route”, ({ setResponseHeader }) => { setResponseHeader(“Content-Security-Policy”, ContentSecurityPolicy.replace(/\n/g, “”)) })
Content-Security-Policy gives you the ability to:
- Overcome XSS (Cross Site Scripting) attacks
- Prevent Clickjacking
- Report violation(s) to the CSP rules
X-Content-Type-Options
How Configuring X-Content-Type-Options prevents MIME-Type Sniffing
The X-Content-Type-Options Header indicates that MIME (Multipurpose Internet Mail Extensions, an identifier for file formats) Types specified in the Content-Type headers shall be strictly followed. With MIME Type Sniffing, operations such as image upload can run executables that could be malicious, where the X-Content-Type-Options header comes into play.
const { Router } = require(‘@layer0/core/router’) new Router() .get(“/:route”, ({ setResponseHeader }) => { setResponseHeader(“X-Content-Type-Options”, “nosniff”) })
X-Frame-Options
X-Frame-Options Header
The X-Frame-Options header indicates whether a browser should be allowed to render a page in a frame, iframe, embed or object tag(s) to avoid click-jacking attacks. Whether set to DENY or SAMEORIGIN ensures that their content is not embedded into other sites or only embedded into sites with the same origin, respectively.
const { Router } = require(‘@layer0/core/router’) new Router() .get(“/:route”, ({ setResponseHeader }) => { setResponseHeader(“X-Frame-Options”, “SAMEORIGIN”) })
X-Frame-Options gives you the ability to:
- Prevent Clickjacking attacks
- Indicate whether or not a browser should be allowed to render a page in a <frame>, <iframe>, <embed> or <object>
Cross-Origin Resource Policy (CORP)
CORP allows servers to protect against certain cross-origin or cross-site embedding of the requested resource (for e.g. API responses). It also prevents speculative side-channel attacks like Spectre.
const { Router } = require(‘@layer0/core/router’) new Router() .get(“/:route”, ({ setResponseHeader }) => { setResponseHeader(“Cross-Origin-Resource-Policy”, “same-origin”) })
Cross-Origin Resource Policy is an opt-in response header which can protect any resource; there is no need for browsers to sniff MIME types. — MDN Docs
Cross-Origin Embedder Policy (COEP)
COEP header prevents loading of cross-origin resources that have not been granted permission for (via CORS or CORP). Use ‘require-corp’ to enforce the header, while ‘unsafe-none’ to allow fetching cross-origin documents.
const { Router } = require(‘@layer0/core/router’) new Router() .get(“/:route”, ({ setResponseHeader }) => { setResponseHeader(“Cross-Origin-Embedder-Policy”, “require-corp”) })
Cross-Origin Opener Policy (COOP)
Enforcing COOP header ensures that a top-level document’s browsing context group is not shared between cross-origin documents. While ‘same-origin’ breaks the integrations that require cross-origin window interactions such as OAuth and Payment, ‘same-origin-allow-popups’ aims to share the context with only the popups from the SAMEORIGIN.
const { Router } = require(‘@layer0/core/router’) new Router() .get(“/:route”, ({ setResponseHeader }) => { setResponseHeader(“Cross-Origin-Opener-Policy”, “same-origin-allow-popups”) })
Referrer Policy
When a user navigates (clicking on a link) from one site (the origin) to another (the destination), the latter receives information about the origin the user came from. The Referrer-Policy header controls how much of this information shall be available to the destination. For all the directives of Referrer-Policy, refer to Referrer-Policy — HTTP | MDN (mozilla.org).
const { Router } = require(“@layer0/core/router”) module.exports= new Router() .get(“/”, ({ setResponseHeader }) => { setResponseHeader(“Referrer-Policy”, “origin-when-cross-origin”) })
Permissions Policy
An experimental HTTP Header that provides the ability to allow/deny browser features in its own frames, and in any iframe in the document. For all the directives of Referrer-Policy, refer to Feature-Policy — HTTP | MDN (mozilla.org)
const { Router } = require(“@layer0/core/router”) module.exports= new Router() .get(“/”, ({ setResponseHeader }) => { setResponseHeader( “Permissions-Policy”, “camera=(), microphone=(), geolocation=()” ); })
HTTP Strict Transport Security (HSTS)
HSTS Strict Transport Security Header
HTTP Strict-Transport-Security (HSTS) informs the browsers to load the web site only using HTTPS, instead of using the HTTP Protocol.
const { Router } = require(‘@layer0/core/router’) new Router() .get(“/:route”, ({ setResponseHeader }) => { setResponseHeader(“Strict-Transport-Security”, “max-age=31536000; includeSubDomains”) })
HSTS gives you the ability to:
- Protect against HTTP downgrade attacks (SSL stripping attacks)
- Mixed content defense switches to HTTPS by default
An Example
With Layer0, it’s easier than ever to implement Security Headers. By using Layer0’s EdgeJS, you can add security headers to any website, independent of the framework being used. The following seeks to implement the relevant security headers in a website built with Sapper via Layer0.
Example: https://rishi-raj-jain-security-headers-example-default.layer0-limelight.link
GitHub: rishi-raj-jain/security-headers-example
Report: Security Headers Report Link
Discussion
Go ahead and add relevant security headers to secure your web application! With Layer0 you can do even more than this, secrets, cache poisoning and enabling basic authentication at Edgio Documentation — Security.