Secure Web App Using HTTP Security Headers: Next.js

security web app using http security headers
Table of Contents
Contributors
Picture of Vivasoft Team
Vivasoft Team
Tech Stack
0 +
Want to accelerate your software development your company?

It has become a prerequisite for companies to develop custom software products to stay competitive.

What are http Security Headers?

HTTP security headers are additional pieces of information sent by web servers along with regular HTTP responses to enhance the security of web applications.

These headers provide instructions to web browsers on how to handle various aspects of interaction with the website, mitigating risks associated with common web vulnerabilities such as cross-site scripting (XSS), clickjacking, and protocol downgrade attacks.

Security headers include directives like Content-Security-Policy (CSP), which defines a whitelist of trusted sources for content, X-Frame-Options to prevent clickjacking by controlling how pages can be embedded in iframes, and Strict-Transport-Security (HSTS) to enforce secure communication over HTTPS.

These headers serve as proactive measures to protect sensitive user data, maintain data integrity, and prevent unauthorized access, ultimately contributing to the overall security posture of web applications.

Consider the scenario of TechMart, an e-commerce platform susceptible to attacks due to vulnerabilities in its search functionality. Without proper security headers, an attacker could inject malicious scripts into the search query, potentially leading to cross-site scripting (XSS) attacks.

In this scenario, the risk factor involves compromising user data, such as login credentials or payment information, through the execution of unauthorized scripts. However, by implementing Content-Security-Policy (CSP) with strict content source directives, TechMart can prevent the execution of these malicious scripts, thereby mitigating the risk of XSS attacks.

Similarly, other security headers like X-Frame-Options protect against clickjacking attacks, ensuring the integrity and confidentiality of user data.

Thus, security headers play a pivotal role in safeguarding web applications against a plethora of cyber threats, preserving user trust, and maintaining the overall security of the platform.

Some common security headers are—

1. Content-Security-Policy (CSP)

Content-Security-Policy (CSP) is a security header that allows website administrators to define a whitelist of trusted sources for content, mitigating risks associated with cross-site scripting (XSS) attacks, data injection, and other types of code injection attacks.

CSP works by specifying which content sources are allowed to be loaded and executed on a web page, such as scripts, stylesheets, fonts, images, and more. The CSP header consists of one or more directives, each specifying a particular type of content and its allowed sources. Here are some common directives used in CSP:

  • default-src: Defines the default source for content types not explicitly specified by other directives.
  • script-src: Specifies the allowed sources for JavaScript.
  • style-src: Specifies the allowed sources for CSS stylesheets.
  • img-src: Specifies the allowed sources for images.
  • font-src: Specifies the allowed sources for fonts.
  • connect-src: Specifies the allowed sources for XMLHttpRequest, WebSocket, and EventSource connections.
  • frame-src: Specifies the allowed sources for framing content using <frame>, <iframe>, <object>, <embed>, or <applet> elements.
  • media-src: Specifies the allowed sources for media files (audio and video).
  • object-src: Specifies the allowed sources for <object>, <embed>, and <applet> elements.
  • worker-src: Specifies the allowed sources for web workers and nested browsing contexts.
  • base-uri: Specifies the allowed URIs that can be used in a document’s <base> tag.
  • form-action: Specifies the allowed URIs for form submissions.
  • frame-ancestors: Specifies the allowed sources that can embed the current page using <frame>, <iframe>, <object>, <embed>, or <applet> elements.
  • plugin-types: Specifies the allowed MIME types for plugins invoked via <object> or <embed> elements.

Here’s an example of the syntax for setting CSP directives in the CSP header:

				
					Content-Security-Policy: default-src 'self'; script-src 'self' https://example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' https://fonts.gstatic.com; connect-src 'self' https://api.example.com; frame-src 'self' https://www.youtube.com;
				
			

In this example:

By setting the Content-Security-Policy header with appropriate directives, web developers can control which content sources are allowed to be loaded and executed, thereby mitigating risks associated with XSS attacks and data injection.

It’s important to carefully configure CSP to balance security and functionality, ensuring that it doesn’t inadvertently block legitimate resources required by the web application.

2. X-DNS-Prefetch-Control

X-DNS-Prefetch-Control is an HTTP response header that controls the browser’s DNS prefetching behavior. DNS prefetching is a technique used by modern browsers to resolve domain names before a user navigates to them, aiming to improve page load times by reducing DNS lookup latency.

However, in some cases, DNS prefetching may lead to privacy concerns or unnecessary resource consumption.

The X-DNS-Prefetch-Control header allows web developers to control whether DNS prefetching is enabled or disabled for their website. It can have two directives:

  • on: Enables DNS prefetching. If this directive is set, the browser may perform DNS lookups for resources referenced in the page, even if they are not explicitly requested by the user.
  • off: Disables DNS prefetching. If this directive is set, the browser will not perform DNS lookups for resources unless explicitly requested by the user.

Here’s the syntax for setting the X-DNS-Prefetch-Control header:

				
					X-DNS-Prefetch-Control: on
OR
X-DNS-Prefetch-Control: off
				
			
In the example:
  • X-DNS-Prefetch-Control: on: Enables DNS prefetching for the website.
  • X-DNS-Prefetch-Control: off: Disables DNS prefetching for the website.
We can include this header in your HTTP response to control the browser’s DNS prefetching behavior based on your specific requirements and considerations for privacy and resource usage.

3. Strict-Transport-Security (HSTS)

Strict-Transport-Security (HSTS) is an HTTP response header that instructs web browsers to only communicate with the web server over HTTPS (HTTP Secure) for a specified duration.

This header helps protect against certain types of attacks, such as protocol downgrade attacks and man-in-the-middle (MitM) attacks, by ensuring that all communication between the client and server is encrypted and transmitted securely.

The HSTS header consists of one or more directives, specifying various parameters related to the enforcement of HTTPS. The most common directive is max-age, which sets the duration for which the browser should enforce HTTPS. Additional directives may include includeSubDomains and preload.

Here’s the syntax for setting the HSTS header:

				
					Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
				
			
In this example:
  • max-age=63072000: Specifies the duration, in seconds, for which the browser should enforce HTTPS. In this case, the duration is set to 2 years (63072000 seconds).
  • includeSubDomains: This optional directive indicates that the HSTS policy should also be applied to all subdomains of the website. When included, it ensures that HTTPS is enforced not only for the main domain but also for all its subdomains.
  • preload: This optional directive indicates that the website should be included in the HSTS preload list maintained by browsers. Being on this list ensures that browsers will always

Connect to the website over HTTPS, even for the first visit, which helps prevent initial insecure connections and potential attacks.

By setting the Strict-Transport-Security header with appropriate directives, you can mitigate several risks associated with insecure communication over HTTP, thereby enhancing the overall security of your website.

4. The X-Frame-Options Header

The X-Frame-Options header is a security feature that controls whether a web page can be displayed within an iframe or not. It helps mitigate clickjacking attacks by restricting how a web page can be embedded in frames or iframes on other domains. The X-Frame-Options header has three directives:
  • DENY: This directive instructs the browser to deny any framing of the web page, regardless of the origin.
  • SAMEORIGIN: This directive allows the web page to be framed only by pages from the same origin (i.e., the same domain).
  • ALLOW-FROM uri: This directive specifies a specific URI that is allowed to frame the web page. This URI can be an absolute URL or a wildcard (*). Here’s the syntax for setting the X-Frame-Options header:
				
					X-Frame-Options: DENY
or
X-Frame-Options: SAMEORIGIN
or
X-Frame-Options: ALLOW-FROM https://example.com
				
			
In these examples:
  • X-Frame-Options: DENY denies all framing of the web page.
  • X-Frame-Options: SAMEORIGIN allows framing only by pages from the same origin.
  • X-Frame-Options: ALLOW-FROM https://example.com allows framing only by the specified URI (example.com).
By setting the X-Frame-Options header with the appropriate directive, you can prevent clickjacking attacks and ensure the integrity and security of your web pages when embedded in frames or iframes on other domains.

5. The X-Content-Type-Options

The X-Content-Type-Options header is a security feature that controls how a web browser should interpret the content type of a response. It helps prevent MIME-sniffing attacks, where browsers may override the declared content type and attempt to guess the correct content type based on the content of the response.

The X-Content-Type-Options header has one directive:

  • nosniff: This directive instructs the browser not to perform MIME-sniffing and to strictly adhere to the declared content type of the response.

Here’s the syntax for setting the X-Content-Type-Options header:

				
					X-Content-Type-Options: nosniff
				
			

By including this header in the HTTP response, you explicitly instruct the browser not to sniff the content type and to rely only on the declared content type provided by the server.

This helps prevent potential security vulnerabilities associated with MIME-sniffing, ensuring that the browser interprets the content as intended by the server and mitigating risks related to content type confusion.

6. Permissions-Policy

Permissions-Policy is a security header that allows web developers to control and restrict browser features, APIs, and other browser functionalities used by the website.

It enables fine-grained control over which web platform features are available to the site, thereby mitigating potential security risks associated with certain browser capabilities.

The Permissions-Policy header has multiple directives, each specifying a particular browser feature or API and its allowed behavior. Some common directives include:

  • accelerometer: Controls access to the device’s accelerometer sensor.
  • camera: Controls access to the device’s camera.
  • geolocation: Controls access to the device’s geolocation.
  • microphone: Controls access to the device’s microphone.
  • usb: Controls access to USB devices.
  • autoplay: Controls whether media elements can autoplay without user interaction.
  • fullscreen: Controls whether elements can enter fullscreen mode.
  • payment: Controls access to the Payment Request API.
  • sync-xhr: Controls whether synchronous XHR requests are allowed.

Here’s an example syntax for setting the Permissions-Policy header.

				
					Permissions-Policy: accelerometer=(), camera=(), geolocation=(), microphone=()
				
			

In this example:

accelerometer=() specifies that access to the device’s accelerometer sensor is disallowed.

camera=() specifies that access to the device’s camera is disallowed.

geolocation=() specifies that access to the device’s geolocation is disallowed.

microphone=() specifies that access to the device’s microphone is disallowed.

By setting the Permissions-Policy header with appropriate directives, web developers can control the behavior of various browser features and APIs, reducing the attack surface and enhancing the security of their web applications.

7. The Referrer-Policy Header

The Referrer-Policy header is a security feature that controls how much information about the referring URL is included in the Referrer header when navigating from one page to another.

It helps mitigate the risk of information leakage and privacy concerns associated with the referrer header by allowing web developers to specify the policy for handling referrer information.

The Referrer-Policy header has several directives, each specifying a different policy for sending referrer information. Some common directives include:

  • no-referrer: Specifies that no referrer information should be sent in the Referrer header.
  • no-referrer-when-downgrade: Specifies that referrer information should be sent when navigating to a less secure destination (i.e., from HTTPS to HTTP), but not when navigating to a more secure destination.
  • origin: Specifies that only the origin of the referring URL (scheme, host, and port) should be sent in the Referrer header.
  • origin-when-cross-origin: Specifies that the full URL should be sent in the Referrer header when navigating within the same origin, but only the origin should be sent when navigating to a different origin.
  • same-origin: Specifies that the full URL should be sent in the Referrer header only when navigating within the same origin.
  • strict-origin: Specifies that only the origin of the referring URL should be sent in the Referrer header, regardless of the destination’s security level.
  • strict-origin-when-cross-origin: Specifies that the full URL should be sent in the Referrer header when navigating within the same origin, but only the origin should be sent when navigating to a different origin. Additionally, the referrer information should be sent in HTTPS-to-HTTPS navigations, but not in HTTPS-to-HTTP navigations.

Here’s an example syntax for setting the Referrer-Policy header:

				
					Referrer-Policy: strict-origin-when-cross-origin
				
			

In this example:

strict-origin-when-cross-origin specifies that the full URL should be sent in the Referrer header when navigating within the same origin, but only the origin should be sent when navigating to a different origin. Additionally, the referrer information should be sent in HTTPS-to-HTTPS navigations, but not in HTTPS-to-HTTP navigations.

By setting the Referrer-Policy header with appropriate directives, web developers can control the amount of referrer information sent in the Referrer header, thereby enhancing privacy and mitigating the risk of information leakage.

Some Common Security Headers and their Implementation in Next.js

Next.js allows us to set custom HTTP headers by using async headers inside the next.config.js. The headers is an async function that expects an array to be returned holding objects with source and headers properties—

Security Headers Implements

[NextJS requires ‘unsafe-eval’ in dev (faster source maps)]

As per the next.js doc headers properties are:

source is the incoming request path pattern. For a specific path source: ‘/name_of_pathor sets security headers for all routes source: ‘/(.*)’,

headers is an array of response header objects, with key and value properties.

basePath: false or undefined – if false the basePath won’t be included when matching, can be used for external rewrites only.

				
					const withPWA = require("next-pwa");
const production = process.env.NODE_ENV === "production";
const ApiHost = process.env.API_HOST;
/*
default-src 'none'; // none is default
NextJS requires 'unsafe-eval' in dev (faster source maps)
*/
const cspHeader = `
default-src 'self';
connect-src 'self' ${ApiHost} https://dc.services.visualstudio.com/v2/track data:;
frame-src 'self' blob:;
script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval' ${
production ? "" : "'unsafe-eval'"
};
style-src 'self' 'unsafe-inline';
img-src 'self' blob: data:;
font-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
block-all-mixed-content;
upgrade-insecure-requests;
`;
const securityHeaders = [
{
key: "Content-Security-Policy",
value: cspHeader.replace(/\n/g, "")
},
{
key: "X-DNS-Prefetch-Control",
value: "on"
},
{
key: "Strict-Transport-Security",
value: "max-age=63072000; includeSubDomains; preload"
},
{
key: "X-Frame-Options",
value: "SAMEORIGIN"
},
{
key: "X-Content-Type-Options",
value: "nosniff"
},
{
key: "Permissions-Policy",
value: "camera=(), microphone=(), geolocation=(), browsing-topics=()"
},
{
key: "Referrer-Policy",
value: "same-origin"
}
];
const nextConfig = {
async headers() {
return [
{
source: "/(.*)",
headers: securityHeaders
}
];
},
async redirects() {
return [
{
source: "/",
destination: "/dashboard",
permanent: false
}
];
},
webpack5: true,
webpack: (config) => {
config.resolve.fallback = { fs: false };
return config;
},
...withPWA({
dest: "public",
register: true,
skipWaiting: true,
disable: process.env.NODE_ENV === "development"
})
};
module.exports = nextConfig;
				
			

We can check our web app’s HTTP Security Headers status from site like— Mozilla Observatory, Analyse your HTTP response headers (securityheaders.com)

HTTP Security Headers status

Before HTTP Security Headers implementations—

Before HTTP Security Headers implementations

[Result from Mozila Observatory]

After HTTP Security Headers implementations—

Result from Mozila Observatory

[Result from Mozila Observatory]

Result from Mozila securityheaders

[Result from securityheaders.com]
Hope now we have some idea about the HTTP Security Headers, that may help to prevent malicious security attacks.

Final Words

In this article, we looked at security headers and how they can be implemented in a Next.js application.

Implementing HTTP security headers in Next.js web applications is crucial for enhancing overall security posture. By properly configuring these headers, developers can mitigate various common web vulnerabilities and protect sensitive user data from potential threats.

With the right measures in place, Next.js applications can ensure a safer and more secure browsing experience for users.

Tech Stack
0 +
Accelerate Your Software Development Potential with Us
With our innovative solutions and dedicated expertise, success is a guaranteed outcome. Let's accelerate together towards your goals and beyond.
Blogs You May Love

Don’t let understaffing hold you back. Maximize your team’s performance and reach your business goals with the best IT Staff Augmentation