Skip to content

Commit

Permalink
fix(express): reading of case sensitive headers (#2675)
Browse files Browse the repository at this point in the history
  • Loading branch information
emmenko authored Jul 1, 2022
1 parent 21b8cc2 commit cb60852
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changeset/eight-horses-carry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@commercetools-backend/express': patch
---

Fix reading and validating case sensitive `X-MC-API-*` headers
12 changes: 7 additions & 5 deletions packages-backend/express/src/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
MC_API_URLS,
MC_API_PROXY_HEADERS,
} from './constants';
import { getFirstOrThrow } from './utils';
import { getFirstHeaderValueOrThrow } from './utils';

type TDecodedJWT = {
sub: string;
Expand Down Expand Up @@ -142,8 +142,9 @@ function createSessionAuthVerifier<Request extends TBaseRequest>(
// Returns an async HTTP handler.
return async (request: Request, response?: unknown) => {
// Get the cloud identifier header, forwarded by the `/proxy/forward-to` endpoint.
const cloudIdentifierHeader = getFirstOrThrow(
request.headers[MC_API_PROXY_HEADERS.CLOUD_IDENTIFIER],
const cloudIdentifierHeader = getFirstHeaderValueOrThrow(
request.headers,
MC_API_PROXY_HEADERS.CLOUD_IDENTIFIER,
`Missing "X-MC-API-Cloud-Identifier" header.`
);

Expand All @@ -155,8 +156,9 @@ function createSessionAuthVerifier<Request extends TBaseRequest>(

// Get the `Accept-version` header, forwarded by the `/proxy/forward-to` endpoint.
// The version should be sent by the client making the request, to use the features of v2.
const proxyForwardVersion = getFirstOrThrow(
request.headers[MC_API_PROXY_HEADERS.FORWARD_TO_VERSION],
const proxyForwardVersion = getFirstHeaderValueOrThrow(
request.headers,
MC_API_PROXY_HEADERS.FORWARD_TO_VERSION,
`Missing "X-MC-API-Forward-To-Version" header.`
);
if (proxyForwardVersion === 'v1') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,13 @@ describe.each`
issuer,
audience: 'http://test-server/foo/bar',
})}`,
'x-mc-api-cloud-identifier': cloudIdentifier,
// The following headers are validated as they are expected to be present
// in the incoming request.
// To ensure we can correctly read the header values no matter if the
// header key is lowercase or not, we test both headers variations:
// * one with upper/camel case key
// * one with lowercase key
'X-MC-API-Cloud-Identifier': cloudIdentifier,
'x-mc-api-forward-to-version': 'v2',
},
originalUrl: '/foo/bar',
Expand Down
28 changes: 22 additions & 6 deletions packages-backend/express/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
const getFirstOrThrow = (
value: string | string[] | undefined,
const getHeaderByCaseInsensitiveKey = (
headers: Record<string, string | string[] | undefined>,
headerKey: string
): string | undefined => {
const matchingHeader = Object.entries(headers).find(
([key]) => headerKey.toLowerCase() === key.toLowerCase()
);
if (matchingHeader && matchingHeader.length > 0) {
const [, headerValue] = matchingHeader;
return Array.isArray(headerValue) ? headerValue[0] : headerValue;
}
return undefined;
};

const getFirstHeaderValueOrThrow = (
headers: Record<string, string | string[] | undefined>,
headerKey: string,
errorMessage: string
) => {
if (!value) {
): string => {
const headerValue = getHeaderByCaseInsensitiveKey(headers, headerKey);
if (!headerValue) {
throw new Error(errorMessage);
}
return Array.isArray(value) ? value[0] : value;
return headerValue;
};

export { getFirstOrThrow };
export { getHeaderByCaseInsensitiveKey, getFirstHeaderValueOrThrow };

1 comment on commit cb60852

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deploy preview for merchant-center-application-kit ready!

✅ Preview
https://merchant-center-application-6w6kpxrbw-commercetools.vercel.app

Built with commit cb60852.
This pull request is being automatically deployed with vercel-action

Please sign in to comment.