Why is HSTS header not set on _next/image calls?
Unanswered
Black carp posted this in #help-forum
Black carpOP
We've been notified from a security pass of our application that calls to our CDN via _next/image are not setting the HSTS header (Strict-Transport-Security). This is despite us setting the necessary headers in next.config.js and seeing those headers on all calls other than via _next/image.
I can see in the NextJS source code for the image optimizer that it sets specific headers only and makes no attempt to include the headers set in the next.config.js: https://github.com/vercel/next.js/blob/e9e666d50fe35157e02737d4a7003c24a269438b/packages/next/src/server/image-optimizer.ts#L707 (assuming I am looking in the right place!)
This means that even if we set the HSTS header for files issued from the CDN they are still effectively stripped.
One thing I attempted was detecting calls to _next/image in middleware.js and forcing the header in at that point:
import { NextResponse } from 'next/server'
export function middleware(request) {
const requestHeaders = new Headers(request.headers);
// delete range header because it seems to cause all sorts of issues when
// the file being requested can't satisfy the requested range
requestHeaders.delete('range');
const response = NextResponse.next({
request: {
headers: requestHeaders,
},
});
if (request.url.includes('/_next/image')) {
response.headers.set('Strict-Transport-Security', 'max-age=63072000; includeSubDomains; preload');
}
return response;
};
However this was thwarted due to this NextJS issue that has just made its way into canary: https://github.com/vercel/next.js/pull/68271
My question is, why should we have to handle _next/image headers in this way, shouldn't the code itself take into account the headers configured in next.config.js, or perhaps NextJS needs to add an additional header config block for _next/image where specific headers can be specified?
I can see in the NextJS source code for the image optimizer that it sets specific headers only and makes no attempt to include the headers set in the next.config.js: https://github.com/vercel/next.js/blob/e9e666d50fe35157e02737d4a7003c24a269438b/packages/next/src/server/image-optimizer.ts#L707 (assuming I am looking in the right place!)
This means that even if we set the HSTS header for files issued from the CDN they are still effectively stripped.
One thing I attempted was detecting calls to _next/image in middleware.js and forcing the header in at that point:
import { NextResponse } from 'next/server'
export function middleware(request) {
const requestHeaders = new Headers(request.headers);
// delete range header because it seems to cause all sorts of issues when
// the file being requested can't satisfy the requested range
requestHeaders.delete('range');
const response = NextResponse.next({
request: {
headers: requestHeaders,
},
});
if (request.url.includes('/_next/image')) {
response.headers.set('Strict-Transport-Security', 'max-age=63072000; includeSubDomains; preload');
}
return response;
};
However this was thwarted due to this NextJS issue that has just made its way into canary: https://github.com/vercel/next.js/pull/68271
My question is, why should we have to handle _next/image headers in this way, shouldn't the code itself take into account the headers configured in next.config.js, or perhaps NextJS needs to add an additional header config block for _next/image where specific headers can be specified?