nestjs / swagger

OpenAPI (Swagger) module for Nest framework (node.js) :earth_americas:

Home Page:https://nestjs.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add integrity hash on swagger-ui inline scripts

tafaust opened this issue · comments

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

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

I enabled CSP in my apps and I have issues with the redirect from /oauth2-redirect.html within my OIDC flow in swagger-ui for my non-prod workflows. My current workaround looks like this:

  let helmetOptions: Readonly<HelmetOptions> = {
    contentSecurityPolicy: {
      directives: {
        ...helmet.contentSecurityPolicy.getDefaultDirectives(),
        'default-src': ["'self'", 'token issuer url'],
        'script-src': ["'self'"],
        'connect-src': ["'self'", 'token issuer url'],
      },
    },
  };
  if (config.getOrThrow<string>('NODE_ENV') !== 'production') {
    helmetOptions = {
      contentSecurityPolicy: {
        directives: {
          ...helmet.contentSecurityPolicy.getDefaultDirectives(),
          'default-src': ["'self'", 'token issuer url'],
          'script-src': ["'self'", "'unsafe-inline'"],
          'connect-src': ["'self'", 'token issuer url'],
        },
      },
      crossOriginOpenerPolicy: {
        policy: 'unsafe-none',
      },
    };
  }

  app.use(helmet(helmetOptions));

Describe the solution you'd like

I'd like to have the integrity attribute on the script tags as described in https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity.

<script src="<% baseUrl %>swagger-ui-bundle.js"> </script>
<script src="<% baseUrl %>swagger-ui-standalone-preset.js"> </script>
<script src="<% baseUrl %>swagger-ui-init.js"> </script>

Teachability, documentation, adoption, migration strategy

Users can use it as follows in their code when using CSP:

  let helmetOptions: Readonly<HelmetOptions> = {
    contentSecurityPolicy: {
      directives: {
        ...helmet.contentSecurityPolicy.getDefaultDirectives(),
        'default-src': ["'self'", 'token issuer url'],
        'script-src': ["'self'", "'shaXXX-XXXXXXXXXXXXXX...'"],
        'connect-src': ["'self'", 'token issuer url'],
      },
    },
    crossOriginOpenerPolicy: {
      policy: 'unsafe-none',
    },
  };
  app.use(helmet(helmetOptions));

where shaXXX-XXXXXXXXXXXXXX... resembles the integrity hash from the oauth2-redirect.html.

What is the motivation / use case for changing the behavior?

As mentioned above, I want to use CSP headers and the swagger-ui is giving me a hard time with the inline scripts without the integrity hash that could be whitelisted in CSP.

Would you like to create a PR for this issue?

@kamilmysliwiec Yeah, do you want me to hardcode (= kind of a burden when the https://github.com/nestjs/swagger/blob/master/package.json#L31 dependency is upgraded) or dynamically compute the integrity (adds a new dependency https://github.com/zkat/ssri#from-data)?

I'd rather steer clear of adding more external dependencies to this package

@kamilmysliwiec May I have some preliminary feedback on #2680 before writing tests?

I am particularly interested about your thoughts for this commit b29efb0 which breaks one of the E2E tests.

I also did not find the swagger-ui-init.js to compute the checksum
(checked this repo and https://github.com/swagger-api/swagger-ui/tree/master/dist).

Let's track this here #2680