Giter Club home page Giter Club logo

nuxt-security's Introduction

nuxt-security

npm version npm downloads Github Actions CI License Nuxt

Nuxt Security

Automatically configure your app to follow OWASP security patterns and principles by using HTTP Headers and Middleware.

This module works with Nuxt 3 only

Features

  • Security response headers (including CSP for SSG apps)
  • Request Size & Rate Limiters
  • Cross Site Scripting (XSS) Validation
  • Cross-Origin Resource Sharing (CORS) support
  • Hide X-Powered-By header and remove console loggers utils
  • [Optional] Allowed HTTP Methods, Basic Auth, CSRF

Usage

Install the module:

npx nuxi@latest module add security

And that's it! The module will now register route rules and server middlewares globally so that your application will be more secured.

Configuration

You can pass configuration to the module in the nuxt.config.ts like following:

export default defineNuxtConfig({
  modules: ["nuxt-security"],
  security: {
    // options
  }
})

For all available configuration options check out the docs.

Development

  • Run yarn dev:prepare to generate type stubs.
  • Use yarn dev to start playground in development mode.

License

MIT License

nuxt-security's People

Contributors

afganabbas avatar baroshem avatar boring-dragon avatar damianglowala avatar danielroe avatar dargmuesli avatar dominic-marcelino avatar droutin avatar espensgr avatar eyopa21 avatar fabriciooak avatar felix-dolderer avatar galactichypernova avatar huang-julien avatar insomnius avatar jesse1989pp avatar kouts avatar mohamed-kaizen avatar morgbn avatar mtdvlpr avatar mubaidr avatar pi0 avatar runyasak avatar scottix avatar snepsnepy avatar tmlmt avatar tresko avatar trijpstra-fourlights avatar tristan971 avatar vejja avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

nuxt-security's Issues

Potential issue with passing empty object as middleware config

    // TODO: fix the conditions here. What if user passes '{}'? It will result true here and later will break
    const requestSizeLimiterConfig = nuxt.options.security.requestSizeLimiter
    if(requestSizeLimiterConfig) {

Version

nuxt-security:
nuxt:

Reproduction Link

Steps to reproduce

What is Expected?

What is actually happening?

Some module improvements

Doing a quick review for nuxt/modules#473

Nitro provides a built-in storage useStorage (memory and redis)

Version

nuxt-security: last
nuxt: 3 last

Reproduction Link

Steps to reproduce

Example: Simple (in memory) operations

await useStorage().setItem('test:foo', { hello: 'world' })
await useStorage().getItem('test:foo')

Example: redis operations

await useStorage().setItem('redis:foo', { hello: 'world' })
await useStorage().getItem('redis:foo')

export default defineNitroConfig({
  // Production
  storage: {
    'db': {
      driver: 'redis',
      /* redis connector options */
    }
  }

What is Expected?

But you use package like memory-cache

What is actually happening?

Allow module options to be passed as ['nuxt-security', options]

Version

nuxt-security: 0.10.1
nuxt: 3.1.0

Steps to reproduce

In you Nuxt config, add the nuxt-security module as a [moduleName, moduleOptions] entry.

export default defineNuxtConfig({
  modules: [
    ["nuxt-security", {headers: {...}}]
  ]
})

What is Expected?

The passed configuration should be taken into account.

What is actually happening?

The module options are only handled if they are passed through the security configuration key in Nuxt config.

Possible fix

In the module definition, instead of using explicitly nuxt.options.security to retrieve passed options, you should use options directly :

{
    setup(options, nuxt) {
    // ...
    nuxt.options.security = defuReplaceArray(options, {
      ...defaultSecurityConfig
    });
}

Thanks for you module, it's a really huge and valuable work 🤗

Issue on Nuxt v3.1.1

Hello,

A little issue with Nuxt v3.1.1...

Version

nuxt-security: v0.10.1
nuxt: v3.1.1

Reproduction Link

Stackblitz

Steps to reproduce

Install the module and add it to nuxt.config.ts

What is Expected?

The module to works 😇

What is actually happening?

An error and blank page on Stackblitz.

On my local the error is:

[worker reload] [worker init] Cannot find package '@nozomuikuta/h3-cors' imported from /Users/lguegu50/projects/dkt/corength/platform/webapp/.nuxt/dev/index.mjs 17:20:58

at new NodeError (node:internal/errors:371:5)
at packageResolve (node:internal/modules/esm/resolve:932:9) 17:20:43
at moduleResolve (node:internal/modules/esm/resolve:978:18)
at defaultResolve (node:internal/modules/esm/resolve:1080:11)
at ESMLoader.resolve (node:internal/modules/esm/loader:530:30)
at ESMLoader.getModuleJob (node:internal/modules/esm/loader:251:18)
at ModuleWrap. (node:internal/modules/esm/module_job:79:40)
at link (node:internal/modules/esm/module_job:78:36)

Be the force be with you for that 💪.

Rate limit bypassable by explicitly setting the x-forwarded-for header

Version

nuxt-security: v0.10.0
nuxt: v2.13.0

Reproduction Link

https://github.com/jviide/nuxt-security-repro

Steps to reproduce

  • Clone the repository linked above.

  • In the repository directory, Install dependencies, build and start the server:

    npm i
    
    npm run build
    
    npm start
  • Let's simulate a situation where Nuxt server is running behind a typical load-balancer that appends the originating request IP to the x-forwarded-for header.

    While the server is running (assuming http://localhost:3000 in this example), request the root page twice with curl. Observe the 429 response on the second request due to the rate limit:

    curl -H 'x-forwarded-for: 192.168.0.2' http://localhost:3000
    
    curl -H 'x-forwarded-for: 192.168.0.2' http://localhost:3000
  • Now run the requests again, this time prefixing the x-forwarded-for header with some unique value for each request.

    This simulates the situation where the original requester sends requests where the x-forwarded-for header is manually set to unique values, and the load balancer just appends to the header. Observe how the rate limiting is not triggered:

    curl -H 'x-forwarded-for: 1.1.1.1, 192.168.0.2'  http://localhost:3000
    
    curl -H 'x-forwarded-for: 2.2.2.2, 192.168.0.2'  http://localhost:3000

What is Expected?

The rate limiter, set to 1 request per hour, could be expected to be triggered in both examples above.

What is actually happening?

In common proxy / load balancer scenarios the rate limit is not triggered if the requester manually adds unique values to the x-forwarded-for request chain.

Many load balancers and proxies just append to the x-forwarded-for headers, keeping such unique client-submitted values in the chain. This in turn can be used to trick nuxt-security's x-forwarded-for based rate limiting logic to consider each request to originate from a unique source. This could allow bypassing e.g. brute-forcing protections.

Other libraries, like Express and fastify-rate-limit, have had to deal with this problem too. For example Express exposes the "trust proxy" configuration value to define how many hops in the x-forwarded-for chain are considered valid.

adding custom configuration with array structure results in duplication of header values

When registering a custom configuration like for CSP headers with the array structure as instructed in the docs, user will get a duplicated headers values. This is caused by defu package that merges two objects and if they dont find exact match, it will merge two objects together.

I will instruct in the docs to not use this approach as it will cause bugs.

Version

nuxt-security:
nuxt:

Reproduction Link

Steps to reproduce

What is Expected?

What is actually happening?

Error: cannot set headers after they are sent to the client

Receiving a couple errors when using this module.
Any advice?

Versions

  "devDependencies": {
    "nuxt": "3.0.0-rc.11",
    "sass": "^1.55.0",
    "sass-loader": "^10.3.1"
  },
  "dependencies": {
    "nuxt-security": "^0.2.1"
  }

Error

 ERROR

 6: import _EyMD21 from 'D:\Devbox\Dare\ms-amlin\code\node_modules\nuxt-security\dist\runtime\server\middleware\headers\referrerPolicy';
 7: import _dVKsGV from 'D:\Devbox\Dare\ms-amlin\code\node_modules\nuxt-security\dist\runtime\server\middleware\headers\strictTransportSecurity';
 8: import _A7rfIb from 'D:\Devbox\Dare\ms-amlin\code\node_modules\nuxt-security\dist\runtime\server\middleware\headers\xContentTypeOptions';
                                                                                                                         ^
 9: import _6AG9Sx from 'D:\Devbox\Dare\ms-amlin\code\node_modules\nuxt-security\dist\runtime\server\middleware\headers\xDNSPrefetchControl';
10: import _aR9QUI from 'D:\Devbox\Dare\ms-amlin\code\node_modules\nuxt-security\dist\runtime\server\middleware\headers\xDownloadOptions';
 ERROR  [unhandledRejection] Cannot set headers after they are sent to the client

  at new NodeError (node:internal/errors:371:5)
  at ServerResponse.setHeader (node:_http_outgoing:576:11)
  at sendError (/D:/Devbox/Dare/ms-amlin/code/node_modules/h3/dist/index.mjs:72:13)
  at nodeHandler (/D:/Devbox/Dare/ms-amlin/code/node_modules/h3/dist/index.mjs:550:15)

Module problem on Windows

Is it possible to fix the absolute path problem on windows?

Build error: Only URLs with a scheme in: file, data are supported by the default ESM loader. On Windows, absolute paths must be valid file:// URLs. Received protocol 'c:'

Wrong paths on Windows

Hello, i was trying to import the module inside my project but after importing the module i always seem to be getting the following error.
image

This error happens in my own project but also when i setup a completely empty nuxt project with nothing in it.

// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
  modules: ["nuxt-security"],
});
{
  "private": true,
  "scripts": {
    "build": "nuxt build",
    "dev": "nuxt dev",
    "generate": "nuxt generate",
    "preview": "nuxt preview",
    "postinstall": "nuxt prepare"
  },
  "devDependencies": {
    "nuxt": "3.0.0-rc.12"
  },
  "dependencies": {
    "nuxt-security": "^0.5.0"
  }
}

Nuxt 3 error when adding module

Version

nuxt-security: 0.6.0
nuxt: 3.0.0-rc.13

Reproduction Link

Error [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only URLs with a scheme in: file, data are supported by the default ESM loader. On Windows, absolute paths must be valid file:// URLs. Received protocol 'd:'
at new NodeError (node:internal/errors:387:5)
at throwIfUnsupportedURLScheme (node:internal/modules/esm/resolve:1017:11)
at defaultResolve (node:internal/modules/esm/resolve:1097:3)
at nextResolve (node:internal/modules/esm/loader:163:28)
at ESMLoader.resolve (node:internal/modules/esm/loader:837:30)
at ESMLoader.getModuleJob (node:internal/modules/esm/loader:424:18)
at ModuleWrap. (node:internal/modules/esm/module_job:76:40)
at link (node:internal/modules/esm/module_job:75:36)

implement headers with `routeRules`

It feels like you could implement setting various headers with routeRules - e.g. a default value imposed via:

export default defineNuxtConfig({
  routeRules: {
    '/**': {
      // default headers
    }
  }
})

That way they could also be overridden with other route rules.

Moreover, it would be good to configure cors in the same way, and for the same reason. As a heads-up, likely future cors enhancements are anticipated directly within nitro.

use cache mechanism from `unstorage`

Nitro has native caching built-in. It implements this using unstorage. You could hook into unstorage also for caching instead of using memory-cache. It is as simple as calling useStorage() which is exposed by Nitro.

Unable to set CSP directive in options

Version

nuxt-security: 0.9.0
nuxt: 3.0.0

Steps to reproduce

Load an image from an external source, for example: <img src="https://images.mycdn.com/image.png" />

Set the nuxt-security options to allow the url:

export default defineNuxtConfig({
security: {
    contentSecurityPolicy: {
      value: {
        'base-uri': ["'self'"],
        'font-src': ["'self'", 'https:', 'data:'],
        'form-action': ["'self'"],
        'frame-ancestors': ["'self'"],
        'img-src': [
          "'self'",
          'data:',
          "https://images.mycdn.com",
        ],
        'object-src': ["'none'"],
        'script-src-attr': ["'none'"],
        'style-src': ["'self'", 'https:', "'unsafe-inline'"],
        'upgrade-insecure-requests': true,
      },
      route: '/**',
    },
  },
})

What is Expected?

The image should be allowed to load.

What is actually happening?

Chrome still gives an error:
Refused to load the image '<URL>' because it violates the following Content Security Policy directive: "img-src 'self' data:".

It seems the options are not applied and it's not possible to load images from a cdn.

Add option for except

Is your feature request related to a problem? Please describe.

When a configuration is set for '' or '/**' which in both cases means global middleware, it would be beneficial to set except property on that configuration object so that user could define routes where he does not want the middleware to work.

Describe the solution you'd like

Describe alternatives you've considered

Additional context

Customization on error response

How to properly handle response? I created an ~error.vue and it works for other error responses like 404 response but not on 429.

Version

nuxt-security: ^0.9.0
nuxt: 3.0.0

Reproduction Link

What is Expected?

I was expecting to customize the error response like redirecting to another page or customize the default response.

What is actually happening?

I am getting the default error response from nuxt
Screenshot 2022-12-16 at 2 45 58 AM

Thank you

Support Basic Auth

Is your feature request related to a problem? Please describe.

Describe the solution you'd like

Describe alternatives you've considered

Additional context

returns undefined error on request (req)

Version

nuxt-security: >= 0.8.0
nuxt: 3.0.0-rc.13

Reproduction Link

Steps to reproduce

What is Expected? page requested

What is actually happening? throws 500 error

[nuxt] [request error] [unhandled] [500] Cannot read properties of undefined (reading 'req')
at Object.handler (./.nuxt/dev/index.mjs:464:53)
at Object.handler (./node_modules/h3/dist/index.mjs:634:31)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Server.toNodeHandle (./node_modules/h3/dist/index.mjs:698:7)
[nuxt] [request error] [unhandled] [500] Cannot read properties of undefined (reading 'req')
at Object.handler (./.nuxt/dev/index.mjs:464:53)
at Object.handler (./node_modules/h3/dist/index.mjs:634:31)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async toNodeHandle (./node_modules/h3/dist/index.mjs:698:7)
at async Object.ufetch [as localFetch] (./node_modules/unenv/runtime/fetch/index.mjs:9:17)
at async Object.errorhandler [as onError] (./.nuxt/dev/index.mjs:436:30)
at async Server.toNodeHandle (./node_modules/h3/dist/index.mjs:705:9)
[nuxt] [request error] [unhandled] [500] Cannot read properties of undefined (reading 'req')
at Object.handler (./.nuxt/dev/index.mjs:464:53)
at Object.handler (./node_modules/h3/dist/index.mjs:634:31)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Server.toNodeHandle (./node_modules/h3/dist/index.mjs:698:7)
[nuxt] [request error] [unhandled] [500] Cannot read properties of undefined (reading 'req')
at Object.handler (./.nuxt/dev/index.mjs:464:53)
at Object.handler (./node_modules/h3/dist/index.mjs:634:31)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async toNodeHandle (./node_modules/h3/dist/index.mjs:698:7)
at async Object.ufetch [as localFetch] (./node_modules/unenv/runtime/fetch/index.mjs:9:17)
at async Object.errorhandler [as onError] (./.nuxt/dev/index.mjs:436:30)
at async Server.toNodeHandle (./node_modules/h3/dist/index.mjs:705:9)

basicAuth all routers

Can there be an auth structure that will pass completely to all applications and links?

Possible to define different policies for different routes?

Hello, I wasn't able to find anything in the documentation regarding this question, but I'm facing a problem where I'd like to relax the 'Cross-Origin-Embedder-Policy' header to 'unsafe-none' on a single route (to make a specific 3rd party module work), while keeping it strict on all others.

However in nuxt.config.ts, as far as I can tell, it is not possible to make such a distinction. Any help would be greatly appreciated!

Add a default `default-src` directive for Content Security Policy?

Is your feature request related to a problem? Please describe.

When the default-src directive isn't present and a directive isn't specified, everything is allowed (in some cases) for that unspecified directive (according to the answers here).

In the default values for the CSP header, there is for example no media-src directive and no default-src. It is my understanding that anything is allowed for media-src.

Describe the solution you'd like

Add a default value for the default-src directive. Something like:

'default-src': ["'self'"]

Describe alternatives you've considered

An alternative could be to add default values for all directives. But I still think it's good to have a default-src in case directives are added in the future.

Additional context

N/A.

npm page issues

image

There is no github repo.

Playground redirects to npm/playground which is not correct

Version

nuxt-security:
nuxt:

Reproduction Link

Steps to reproduce

What is Expected?

What is actually happening?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.