This is a premium alert message you can set from Layout! Get Now!

Using Next.js security headers to strengthen app security

0

Security breaches in websites are often facilitated by poorly or inadequately configured vital security features. Any undetected security vulnerability leaves your site at risk of being hacked by malicious users. This could lead to disastrous consequences like data theft and unauthorized operations.

As a website administrator, you must therefore take the necessary steps to secure your website or application. Using security headers with the right directives is a highly effective way to secure websites from common security threats such as cross-site scripting (XSS) and clickjacking.

In this article, we’ll learn about security headers, their roles in website security, and how to add them to a Next.js application. We will cover:

What are HTTP security headers?

Every time a browser communicates with a web server, several other pieces of information are sent along with the actual payload using HTTP headers.

When a browser requests a resource from a web server, it includes additional information about the request in the HTTP request headers. The server then responds with the requested content along with HTTP response headers. Take a look at the graphic below to see how this works:

Graphic Showing Browser At Left And Server At Right With HTTP Request Headers In A Box With Arrow Pointing Right And HTTP Response Headers In A Box With Arrow Pointing Left

While there are many different header fields for conveying different kinds of information in HTTP requests and responses, our focus is on security headers.

Security headers are a unique set of header fields used by web applications to specify directives that web browsers must adhere to or enforce. The purpose of these headers is to implement a set of protective rules to ensure secure communication between the user and the website.

For this demonstration, I have created a new Next.js app, which uses the default setup configurations. I have also started the Next app at http://localhost:3000 by running npm run dev on my terminal.

Upon inspecting the HTTP response headers in the network tab of the developer console, it’s obvious that the starter Next app does not have the security headers enabled by default. The image below shows the active HTTP response headers:

Network Tab Of Developer Console Shown With Active Response Headers Displayed

As expected, there is neither Content-Security-Policy, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, nor any other security header present in the response header. Without these policies, the app will be left vulnerable to several security threats, including cross-site scripting (XSS) and clickjacking.

Before learning how to add these security headers to a Next.js app, let’s first understand how each of these headers works. Feel free to skip to the last section of this article if you’re already familiar with security headers.

Examples of security headers

In the following sections, we will go over six different HTTP security headers that you should be aware of. We recommend implementing these security headers in your Next.js project if possible to strengthen app security.

X-Content-Type-Options header

The X-Content-Type-Options header is designed to disable MIME type sniffing, a technique used by browsers to determine the Multipurpose Internet Mail Extensions (MIME) type of a resource based on the response content instead of what is specified in the Content-Type header.

Though MIME sniffing is a helpful method for determining the content type, it’s also possible for an attacker to manipulate the MIME sniffing algorithm. By doing so, they can confuse the browser into interpreting data in a way that allows the attacker to carry out malicious operations like cross-site scripting.

To counter this security vulnerability, the X-Content-Type-Option header supports the nosniff directive, which forces the browser to adhere to the MIME types specified in Content-Type:

X-Content-Type-Options: nosniff

Content-Security-Policy (CSP) header

Oftentimes, your app might need to execute scripts coming from origins other than its own. This will leave the app vulnerable to cross-site scripting (XSS) attacks, a client-side code injection attack characterized by the injection of malicious code by an attacker into a legitimate web page or web application.

With the use of the Content-Security-Policy header, we can specify the exact domains we want to allow content from — in other words, which domains should be considered as safe, and which domains shouldn’t.

Below, you can see the general syntax:

Content-Security-Policy: default-src <trusted-domains>

<trusted-domains> can be any of the following:

  • * to allow content from all domains
  • 'self' to appoint your own domain as the only trusted domain
  • The URL of an external domain you want to allow content from, such as 'https://logrocket.com'

The Content-Security-Policy header also allows us to set custom security policies for various resources, including images and other media, fonts, styles, scripts, and more, all using their respective directives.

Take the following, for example:

Content-Security-Policy: default-src 'self' 'http://blog.logrocket.com'; image-src 'https://unsplash.com'; script-src 'self' https://www.google-analytics.com; font-src 'self' 'https://fonts.googleapis.com'; 

In the above policy, we specified that only content originating from our site and blog.logrocket.com is allowed. These two domains will be used as sources for all our resources unless otherwise specified.

We also only allowed scripts from the current domain — defined as self — as well as google-analytics.com.

For fonts, we allowed both the current domain and fonts.googleapis.com to be sources, while images are only trusted from unsplash.com.

X-Frame-Options header

The X-Frame-Options header is designed to thwart clickjacking attempts on a website by ensuring that the site’s content is not embedded in other websites.

By setting the DENY directive for this header, we prohibited browsers from loading a page in an <iframe>, <frame>, <object>, or <embed> element, regardless of which site is loading the page:

X-Frame-Options: DENY

Another more lenient option is to only allow the page to be displayed in an iframe existing on the same origin as the page itself. This is achieved by setting the directive for X-Frame-Options as SAMEORIGIN, like so:

X-Frame-Options: SAMEORIGIN

HTTP Strict Transport Security (HSTS) header

The Strict-Transport-Security header instructs web browsers to connect with web servers only via HTTPS, thus ensuring that every HTTP connection is encrypted and secure from infiltration by third parties.

The directives for this header are max-age, SubDomains, and preload. Here’s an example of what this looks like:

Strict-Transport-Security: max-age=3571000; includeSubDomains; preload

max-age is the only required directive; the rest are optional. max-age specifies how long the browser should remember that a site is only to be accessed using HTTPS.

Permissions-Policy header

The Permissions-Policy header, formerly known as Feature-Policy, allows you to specify the Web APIs that the web browser is permitted to use.

This means that you can opt not to use external devices — such as the camera, microphone, and geolocation — if your site doesn’t need them. This helps to lower the risk of attackers exploiting such channels.

Here’s an example of what the header looks like:

Permissions-Policy: camera=(); battery=(self); geolocation=(); microphone=('https://a-domain.com')

The empty brackets for both camera and geolocation signify to the browser that we’re denying the use of both APIs. In addition, we specified that the battery status API should only be allowed for the current domain, while the microphone should only be allowed in the specified domain.

Referrer-Policy header

When you click on a link to go from one domain to another domain — say, from DomainA to DomainB — then DomainA is said to be the referrer in this case, and certain information about the referrer is sent to DomainB in the HTTP request’s referrer header.

The Referrer-Policy header allows you to specify how much information about the referrer is sent with the referrer header in each HTTP request when navigating from one domain to another.

There are many directives that you can use with the Referrer-Policy header. This example below uses origin-when-cross-origin to send the path, origin, and query string when performing a same-origin request between equal protocol levels — for example, between HTTPS and HTTPS.

Referrer-Policy: origin-when-cross-origin

Take a look at the MDN docs to learn more about the other directives you can use with the Referrer-Policy header.

How to add security headers in a Next.js app

Now that we know the different security headers and each of their roles in securing a website, let’s see how to add them to a Next.js application.

Next allows you to set security headers from the next.config.js file situated in the main folder of your project — you might need to create this file if it is not already present. Here, you must add an asynchronous headers function to the object.

The headers function must return an array containing a single object. The object will contain the source to which you want to apply the headers, as well as the actual directives themselves.

const nextConfig = {
  reactStrictMode: true,
  swcMinify: true,  
  // Adding policies:
  async headers() {
    return [
        {
          source: '/(.*)',
          headers: [
            {
              key: 'X-Frame-Options',
              value: 'DENY',
            },
            {
              key: 'Content-Security-Policy',
              value:
                "default-src 'self' 'http://blog.logrocket.com'; image-src 'https://unsplash.com'; script-src 'self' https://www.google-analytics.com; font-src 'self' 'https://fonts.googleapis.com'",
            },
            {
              key: 'X-Content-Type-Options',
              value: 'nosniff',
            },
            {
              key: 'Permissions-Policy',
              value: "camera=(); battery=(self); geolocation=(); microphone=('https://a-domain.com')",
            },
            {
              key: 'Referrer-Policy',
              value: 'origin-when-cross-origin',
            },
          ],
        },
      ];
  },   
}

module.exports = nextConfig

The above example sets security headers for all routes on the site, as specified by the source /(.*). There might be instances where you just want a set of headers set for a given page. You could do that as well, as shown below:

const nextConfig = {
  reactStrictMode: true,
  swcMinify: true,  
  // Adding policies:
  async headers() {
    return [
      {
          source: '/user',
          headers: [
            {
              key: 'Content-Security-Policy',
              value:
                "default-src 'self' 'http://blog.logrocket.com'; image-src 'https://unsplash.com'; script-src 'self' https://www.google-analytics.com; font-src 'self' 'https://fonts.googleapis.com'",
            }
          ]
        },
       {
          source: '/posts',
          headers: [
            {
              key: 'Content-Security-Policy',
              value:
                "default-src 'self'",
            }
          ]
        },
      ];
  },

}

module.exports = nextConfig

With this, you’re all set!

To test your project, simply start your Next.js development server by running npm run dev on your terminal. Then, in your browser, navigate to the website address on your local server — it should be at http://localhost:3000. You should be able to see the headers you set in the network tab of the developer console, like so:

Network Tab Of Developer Console Showing Active Security Headers Set And Underlined In Red

Wrapping up

In this article, we looked at security headers and how they can be implemented in a Next.js application. For information about HTTP Headers, check out the MDN documentation.

See you all next time!

The post Using Next.js security headers to strengthen app security appeared first on LogRocket Blog.



from LogRocket Blog https://ift.tt/3cFpAdY
Gain $200 in a week
via Read more

Post a Comment

0 Comments
* Please Don't Spam Here. All the Comments are Reviewed by Admin.
Post a Comment

Search This Blog

To Top