🎉 Introducing Edgio v6 which supports Node.js v16. Learn how to upgrade. 🎉
Edgio
Edgio

Website Security through EdgeJS

Use CDN-as-code (EdgeJS) to apply basic security to your website.

Content Security Policy (CSP)

Content Security Policy (CSP) is an added layer of security that helps to detect and mitigate certain types of attacks, including Cross Site Scripting (XSS) and data injection attacks. These attacks are used for everything from data theft to site defacement to distribution of malware.

You can easily add CSP headers to your site via a catch-all route near the top of your router.

To enforce a content security policy:

JavaScript
1new Router().match('/:path*', ({ setResponseHeader }) => {
2 setResponseHeader(
3 'Content-Security-Policy',
4 "default-src 'self'; report-uri http://reportcollector.example.com/collector.cgi",
5 )
6})
7// The rest of your router...

To enable a content security policy in report-only mode:

JavaScript
1new Router().match('/:path*', ({ setResponseHeader }) => {
2 setResponseHeader('Content-Security-Policy-Report-Only', "default-src 'self'")
3})
4// The rest of your router...

Basic Authentication

You can add basic authentication to your site using the requireBasicAuth router method. For example, add the following to the top of your router:

JavaScript
1router.requireBasicAuth({
2 username: process.env.BASIC_AUTH_USERNAME,
3 password: process.env.BASIC_AUTH_PASSWORD,
4})

Then, add BASIC_AUTH_USERNAME and BASIC_AUTH_PASSWORD environment variables to each environment that should enforce basic authentication. Any environment without those environment variables will not enforce basic authentication.

Once deployed, the router will return 403 Forbidden for requests that have the incorrect basic authentication token, and 401 Unauthorized for requests that have no basic authentication token.

SSL

By default Edgio only serves traffic over the https protocol. It automatically redirects http requests to the same URL, including any query strings, on https.

We strongly discourage the use of http protocol, but if you must enable it, then you can do so by adding protocol: 'http' to your route criteria. For example:

JavaScript
1// routes.js
2
3// Respond to Let's Encrypt HTTP-01 challenge.
4router.match(
5 {
6 protocol: 'http',
7 path: '/.well-known/acme-challenge/<your token>',
8 },
9 ({ send }) => {
10 send('<token value>')
11 },
12)

If you want the route to match both http and https protocols you can match on protocol: /^https?$/. If no route is matched on http protocol then Edgio will fallback on its default behavior of automatically redirecting the request to https.

Additionally:

  • A request’s protocol can be determined by reading the x-0-protocol request header or the request.secure property.
  • During local development all requests will appear secure by default. To test your router for http protocol matching you must either set the local_edgio_emulate_http_protocol cookie to true (if using a browser) or send an x-0-protocol request header set to http.

What is the minimum level of encryption?

Edgio enforces a minimum version of TLS 1.2 or higher.

HTTP/1/2 Version

The incoming HTTP version is independent of the upstream HTTP version. We support HTTP/1 or HTTP/2 on ingress requests. We prioritize HTTP/2 to origin servers. If the origin server does not support the incoming HTTP version (say version HTTP/2 came in but origin only supports HTTP/1), we will downgrade to successfully complete the request, but the outgoing response will return to HTTP/2.

Secrets

Rather than putting secret values such as API keys in your code and checking them into source control, you can securely store them in environment variables, then access them in your code from process.env. To configure environment variables, navigate to your environment, click EDIT, then under Environment Variables, click ADD VARIABLE.

networking

As of Edgio CLI version 2.19.0, when you deploy to an environment using a deploy token, for example by running edg deploy my-team --environment=production --token=(my token) option, all environment variables are pulled down from the Edgio Developer console and applied to process.env so they can be accessed at build time. This allows you to store all of your build and runtime secrets in a single place, Edgio Developer console, rather than storing some in your CI system’s secret manager.

Cache Poisoning

Cache poisoning attack is described by OWASP® as:

The impact of a maliciously constructed response can be magnified if it is cached either by a web cache used by multiple users or even the browser cache of a single user. If a response is cached in a shared web cache, such as those commonly found in proxy servers, then all users of that cache will continue to receive the malicious content until the cache entry is purged.

To guard against this attack you must ensure that all the request parameters that influence the rendering of the content are part of your custom cache key. Edgio will automatically include the host header and URL. Including other request headers and cookies are your responsibility.

For example, if you are rendering content based on a custom language cookie, then you must include it in your custom cache key:

JavaScript
1import { CustomCacheKey } from '@edgio/core/router'
2
3router.get('/some/path/depending/on/language/cookie', ({ cache }) => {
4 cache({
5 key: new CustomCacheKey().addCookie('language'),
6 // Other options...
7 })
8})

Bot Detection

Edgio examines the user-agent header in an incoming request to determine if it includes a string that indicates if it is a bot, and if so, injects 1 in the x-0-device-is-bot request header, which will be visible to your server code. If the user-agent header does not include any of the strings indicating a bot, a 0 value is injected.

User Agents and Bots

The following table list the user agents that Edgio examines and describes the corresponding bots.

User AgentBot Description
embedlyEmbed.ly web crawler bot that performs HTTP requests most often in automatic mode.
facebookexternalhitFacebook bot that crawls the HTML of social plugins, apps, and websites shared on Facebook. The bot gathers and caches data (title, description, thumbnail image) about the shared content and presents the data as a preview.
flipboardFlipboard Proxy Service bot that runs in response to a user request for the service to scan a social media feed such as Twitter, and construct a processed feed of items to deliver in real time.
googlepagesspeedGoogle bot that assists in ranking search results based on page load speed.
Google web/snippetGoogle+ Enterprise bot that extracts high-level data from a URL posted on Google+ Enterprise and presents the data as a snippet of the URL.
headlessBots, usually scripts, that run on a scheduled basis or are triggered from an external system. Headless bots usually perform activities like sending alerts or daily digest messages. The scripts usually run for a short time, then terminate.
ia_archiverAmazon Alexa bot that crawls web sites for issues related to Amazon’s Site Audit service.
outbrainOutbrain Recommendation Platform chat bot.
pinterestAutomated Pinterest bot that creates boards and schedules pins to post to customer accounts.
prerenderPrerender.io hosted service bot that produces an easily crawled version of dynamically rendered pages, allowing indexing by search engines.
previewYahoo bot that extracts data (title, description, thumbnail images) from a URL embedded in an email and presents the data as a preview of the URL
qwantifyWeb crawler bot that indexes content for the Qwant search engine.
scannerBots that analyze how well your website and its security measures respond to various bot threats.
slurpYahoo Search bot for crawling and indexing web page information.
spiderGeneral purpose automated bots that crawl the web to index web page information.
tumblrTumblr bot that performs automated HTTP requests as a web crawler.
vkshareVK social network bot that performs automated HTTP requests usually as a web crawler.
w3c_validatorW3C bot that checks Web documents in formats like HTML and XHTML for conformance to W3C Recommendations and other standards.
whatsappWhatsapp platform chat bot.
xing-contenttabreceiverXing social network crawler bot that indexes content for the Xing social network.
yahooAnother Yahoo Search robot for crawling and indexing web page information.

If the set of bots detected by Edgio is not sufficient for your needs, you can easily add your own bot detection through EdgeJS and its match and setRequestHeader APIs:

JavaScript
1router.match(
2 {
3 headers: {
4 'user-agent': /^regex-for-your-bot-detection$/i,
5 },
6 },
7 ({ setRequestHeader }) => {
8 setRequestHeader('my-bot-detection-is-bot', '1')
9 },
10)
11// ... all your other routes go here and they can match on `my-bot-detection-is-bot: 1`

The above code will match all the routes that even have a user-agent header and then inject the my-bot-detection-is-bot when the value of the user agent header matches the given regex. Once the header has been injected, the later routes can test for it and implement bot handling. Or, you could just let the header be sent upstream for your backend to handle it.