Skip to content

Commit

Permalink
fix: remove authorization header from core.windows.net requests for A…
Browse files Browse the repository at this point in the history
…zure docker registries
  • Loading branch information
etiennetremel committed Jul 1, 2020
1 parent d70b8c1 commit a5d4ad6
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 19 deletions.
82 changes: 81 additions & 1 deletion lib/util/http/index.spec.ts
Expand Up @@ -2,7 +2,7 @@ import nock from 'nock';
import { getName } from '../../../test/util';
import { EXTERNAL_HOST_ERROR } from '../../constants/error-messages';
import * as hostRules from '../host-rules';
import { Http } from '.';
import { Http, removeAuthorizationHeaders } from '.';

const baseUrl = 'http://renovate.com';

Expand Down Expand Up @@ -106,4 +106,84 @@ describe(getName(__filename), () => {
expect(data).toBe('{}');
expect(nock.isDone()).toBe(true);
});

it('removeAuthorizationHeaders Amazon', async () => {
expect(
await removeAuthorizationHeaders({
auth: 'auth',
headers: {
authorization: 'auth',
},
hostname: 'amazon.com',
href: 'https://amazon.com',
search: 'something X-Amz-Algorithm something',
})
).toEqual({
headers: {},
hostname: 'amazon.com',
href: 'https://amazon.com',
search: 'something X-Amz-Algorithm something',
});
});

it('removeAuthorizationHeaders Amazon ports', async () => {
expect(
await removeAuthorizationHeaders({
auth: 'auth',
headers: {
authorization: 'auth',
},
hostname: 'amazon.com',
href: 'https://amazon.com',
port: 3000,
search: 'something X-Amz-Algorithm something',
})
).toEqual({
headers: {},
hostname: 'amazon.com',
href: 'https://amazon.com',
search: 'something X-Amz-Algorithm something',
});
});

it('removeAuthorizationHeaders Azure blob', async () => {
expect(
await removeAuthorizationHeaders({
auth: 'auth',
headers: {
authorization: 'auth',
},
hostname: 'store123.blob.core.windows.net',
href:
'https://<store>.blob.core.windows.net/<some id>//docker/registry/v2/blobs',
})
).toEqual({
headers: {},
hostname: 'store123.blob.core.windows.net',
href:
'https://<store>.blob.core.windows.net/<some id>//docker/registry/v2/blobs',
});
});

it('removeAuthorizationHeaders keep auth', async () => {
expect(
await removeAuthorizationHeaders({
auth: 'auth',
headers: {
authorization: 'auth',
},
hostname: 'renovate.com',
href: 'https://renovate.com',
search: 'something',
})
).toEqual({
auth: 'auth',
headers: {
authorization: 'auth',
},
hostname: 'renovate.com',
href: 'https://renovate.com',
search: 'something',
});
});
});
53 changes: 35 additions & 18 deletions lib/util/http/index.ts
Expand Up @@ -57,6 +57,40 @@ async function resolveResponse<T>(
}
}

// isAmazon return true if request options contains Amazon related headers
function isAmazon(opts: any): boolean {
return opts.search?.includes('X-Amz-Algorithm');
}

// isAzureBlob return true if request options contains Azure container registry related data
function isAzureBlob(opts: any): boolean {
return (
opts.hostname?.endsWith('blob.core.windows.net') && // lgtm [js/incomplete-url-substring-sanitization]
opts.href?.includes('/docker/registry')
);
}

// removeAuthorizationHeaders from the redirect options
export function removeAuthorizationHeaders(opts: any): any {
// Check if request has been redirected to Amazon or an Azure blob (ACR)
if (isAmazon(opts) || isAzureBlob(opts)) {
// if there is no port in the redirect URL string, then delete it from the redirect options.
// This can be evaluated for removal after upgrading to Got v10
const portInUrl = opts.href.split('/')[2].split(':')[1];
if (!portInUrl) {
// eslint-disable-next-line no-param-reassign
delete opts.port; // Redirect will instead use 80 or 443 for HTTP or HTTPS respectively
}

// registry is hosted on Amazon or Azure blob, redirect url includes
// authentication which is not required and should be removed
delete opts.headers.authorization; // eslint-disable-line no-param-reassign
delete opts.auth; // eslint-disable-line no-param-reassign
}

return opts;
}

export class Http<GetOptions = HttpOptions, PostOptions = HttpPostOptions> {
constructor(private hostType: string, private options?: HttpOptions) {}

Expand All @@ -79,24 +113,7 @@ export class Http<GetOptions = HttpOptions, PostOptions = HttpPostOptions> {
options.retry = 0;
}
options.hooks = {
beforeRedirect: [
(opts: any): void => {
// Check if request has been redirected to Amazon
if (opts.search?.includes('X-Amz-Algorithm')) {
// if there is no port in the redirect URL string, then delete it from the redirect options.
// This can be evaluated for removal after upgrading to Got v10
const portInUrl = opts.href.split('/')[2].split(':')[1];
if (!portInUrl) {
// eslint-disable-next-line no-param-reassign
delete opts.port; // Redirect will instead use 80 or 443 for HTTP or HTTPS respectively
}

// registry is hosted on amazon, redirect url includes authentication.
delete opts.headers.authorization; // eslint-disable-line no-param-reassign
delete opts.auth; // eslint-disable-line no-param-reassign
}
},
],
beforeRedirect: [removeAuthorizationHeaders],
};
options.headers = {
...options.headers,
Expand Down

0 comments on commit a5d4ad6

Please sign in to comment.