serverless-nextjs / serverless-next.js

⚡ Deploy your Next.js apps on AWS Lambda@Edge via Serverless Components
MIT License
4.47k stars 457 forks source link

Question: How to use helmet with nextjs #433

Open Arditc opened 4 years ago

Arditc commented 4 years ago

Hi, I'm trying to figure out how to use helmetHelmet with nextjs serverless component, however I couldn't find any docs relating to this. Any support or advice?

The reason for wanting to use it is because when running webpageTest I get a very low score with security (no HSTS for example) and I believe using helmet will help reduce the security issues.

Many thanks!

Arditc commented 4 years ago

Hi, Thanks for the link, however when reading about react helmet seems to be something completely different and not linked to security headers 😔

danielcondemarin commented 4 years ago

@Arditc It is not currently supported however I'd love to add support for it. In theory it shouldn't be too difficult assuming we can get Helmet working with plain Node req: http.IncomingMessage and res: http.ServerResponse.

Support for this would need to be added somewhere here after we map the CloudFront event to a node req and res.

Would look something like:

const page = require(`./${pagePath}`);
const { req, res, responsePromise } = lambdaAtEdgeCompat(event.Records[0].cf);

helmet(res) // this wouldn't actually work but the point is helmet should add headers to res somehow

There is a related AWS article about adding security headers to Lambda@Edge https://aws.amazon.com/blogs/networking-and-content-delivery/adding-http-security-headers-using-lambdaedge-and-amazon-cloudfront/.

The API could be a new input in serverless.yml:

component: serverless-next.js
input:
  securityHeaders:
    contentSecurityPolicy: true
    hsts: true
    ...
ARTushar commented 3 years ago

@Arditc I guess you can use the helmet middleware using next-connect. Something like below

import helmet from 'helmet'
import nc from 'next-connect';

const handler = nc();
nc.use(helmet())
\\ ......
\\ ....
export default handler;
nagaozen commented 3 years ago

I can confirm it works by using next-connect. helmet is connect style middleware.

afiiif commented 2 years ago

You might not need helmet for this. You can easily add security headers in next.config.js

// next.config.js

const securityHeaders = [
  {
    key: 'X-XSS-Protection',
    value: '1; mode=block',
  },
  {
    key: 'X-Frame-Options',
    value: 'SAMEORIGIN',
  },
  {
    key: 'X-Content-Type-Options',
    value: 'nosniff',
  },
  // ...
]

module.exports = {
  async headers() {
    return [
      {
        // Apply these headers to all routes in your application.
        source: '/:path*',
        headers: securityHeaders,
      },
    ]
  },
}

Read more on the official docs here:

germansokolov13 commented 2 years ago

Helmet installs dozens of headers automatically. Doing it yourself is of course possible but rather hard. And requires advanced knowledge. Also, using Helmet allows easier updating those headers.

tamon-persol commented 2 years ago

We can use it with next-connect.

 .use(async (req, res, next) => {
    const addHeaders = helmet();
    await addHeaders(req, res, next);
    next();
  })