Adding security to Nuxt 3

SnykSec - Jan 30 '23 - - Dev Community

What is Nuxt?

Nuxt is an Intuitive Web Framework that allows you to build your next Vue.js application with confidence. It’s an open source framework under MIT license that makes web development simple and powerful. I highly recommend you check out the official website if you want to get started with it.

About web security

Web applications are becoming more and more complex everyday. They can store confidential data or process user information on the fly. In order to handle this effectively, developers need to implement certain layers of security. This can be achieved with security controls such as rate limiters and using open source packages that help your application be more secure.

About the nuxt-security module

In this article, I would like to introduce you to the new Nuxt module that I recently created that should help you build more secure Nuxt applications — whether it’s a simple blog, or a complex e-commerce store. Just keep in mind that this module won’t solve all your security problems. Its main purpose is to help you build secure applications and provide an easy way to implement security layers in your project.

Before we get started, check out the GitHub module and documentation. The nuxt-security module is currently based on two main aspects — OWASP Top 10 for Node.js and Helmet.js.

With nuxt-security, you will have middleware functions that will set the same HTTP security headers as the ones used in HelmetJS, in addition to custom middleware functions based on recommendations from OWASP.

The following are examples of HTTP status codes returned for requests based on implementing security controls in a Nuxt application:

  • 429 too many requests – There will be too many requests from one IP Address (Protection against DOS – Denial of Service attacks)
  • 413 request entity too large – The request body (both normal and file) will be too large to handle — protection against attacks that are meant to exhaust the Server memory.
  • Hidden X-Powered-By header. It is usually considered a bad practice to show what technology the application is built with, so this module hides this header completely.
  • 400 bad request – XSS Validator for both GET and POST requests that will drop requests that contain dangerous code
  • CORS Handler similar to popular Express.js middleware
  • 405 method not allowed – Allowed HTTP Methods Restrictor that allows you to restrict what HTTP methods can be accepted.
  • A Basic Auth implementation so that you can secure your application against unauthorized access

Helmet.js security headers will have the following structure:

Content-Security-Policy: default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Resource-Policy: same-origin
Origin-Agent-Cluster: ?1
Referrer-Policy: no-referrer
Strict-Transport-Security: max-age=15552000; includeSubDomains
X-Content-Type-Options: nosniff
X-DNS-Prefetch-Control: off
X-Download-Options: noopen
X-Frame-Options: SAMEORIGIN
X-Permitted-Cross-Domain-Policies: none
X-XSS-Protection: 0
Enter fullscreen mode Exit fullscreen mode

I developed this module with extendability and customization in mind, meaning you can tailor the Nuxt security setup to your application’s needs, such as:

  • disabling unwanted headers or middlewares
  • configuring middlewares to work only on certain routes
  • changing middleware values

In the module documentation, you will also find good practice sections where you can read more about next steps you can take to make your application more secure.

Using the nuxt-security module

Adding nuxt-security to your Nuxt 3 app is relatively simple. The module does not require any configuration when used with the default and recommended values for middlewares, but feel free to experiment with the values to match your project requirements best.

In order to use nuxt-security in your app, we’ll first need to install it using a package manager of your choice:

# if you use yarn:
yarn add nuxt-security

# if you use npm:
npm i nuxt-security
Enter fullscreen mode Exit fullscreen mode

Next, let’s add it to modules array in nuxt.config.ts:

{
  modules: [
    "nuxt-security",
  ],
}
Enter fullscreen mode Exit fullscreen mode

And that’s it! Both Helmet’s HTTP security headers and middleware functions are now enabled and will help you make your application safer.

This module will register several security middlewares andrecommendations for you under the hood. If you would like to know more about these functions, check out the Request Size Limiter and other middlewares in this section.

However, if you are interested in customizing the default security functions, you can do so like this:

{
  modules: [
    "nuxt-security",
  ],
​​ security: {
    rateLimiter: {
      value: {
        tokensPerInterval: 2,
        interval: "day",
      },
      route: '/my-custom-route',
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

This will override the default configuration of the security middleware so that the rate limiter will ban certain IP Addresses after just 2 requests and reset after a day. However, this will only work for a certain route. If you want to make it global, just pass an empty string — which how Nuxt registers global middlewares.

If you are interested in more customization options, please go to the Configuration page.

Summary

Nicely done! You’ve successfully added security controls to your application that should help you make it a bit safer — just keep in mind that this is only the beginning of your security journey. To learn more, check out the Youtube video below.

Learn more:

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .