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 (#6641)


Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
  • Loading branch information
etiennetremel and viceice committed Jul 1, 2020
1 parent c450621 commit 45d7d40
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 19 deletions.
108 changes: 108 additions & 0 deletions lib/util/http/auth.spec.ts
@@ -0,0 +1,108 @@
import { getName } from '../../../test/util';
import { removeAuthorization } from './auth';

describe(getName(__filename), () => {
it('removeAuthorization no authorization', () => {
const opts = {
hostname: 'amazon.com',
href: 'https://amazon.com',
search: 'something X-Amz-Algorithm something',
};

removeAuthorization(opts);

expect(opts).toEqual({
hostname: 'amazon.com',
href: 'https://amazon.com',
search: 'something X-Amz-Algorithm something',
});
});

it('removeAuthorization Amazon', () => {
const opts = {
auth: 'auth',
headers: {
authorization: 'auth',
},
hostname: 'amazon.com',
href: 'https://amazon.com',
search: 'something X-Amz-Algorithm something',
};

removeAuthorization(opts);

expect(opts).toEqual({
headers: {},
hostname: 'amazon.com',
href: 'https://amazon.com',
search: 'something X-Amz-Algorithm something',
});
});

it('removeAuthorization Amazon ports', () => {
const opts = {
auth: 'auth',
headers: {
authorization: 'auth',
},
hostname: 'amazon.com',
href: 'https://amazon.com',
port: 3000,
search: 'something X-Amz-Algorithm something',
};

removeAuthorization(opts);

expect(opts).toEqual({
headers: {},
hostname: 'amazon.com',
href: 'https://amazon.com',
search: 'something X-Amz-Algorithm something',
});
});

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

removeAuthorization(opts);

expect(opts).toEqual({
headers: {},
hostname: 'store123.blob.core.windows.net',
href:
'https://<store>.blob.core.windows.net/<some id>//docker/registry/v2/blobs',
});
});

it('removeAuthorization keep auth', () => {
const opts = {
auth: 'auth',
headers: {
authorization: 'auth',
},
hostname: 'renovate.com',
href: 'https://renovate.com',
search: 'something',
};

removeAuthorization(opts);

expect(opts).toEqual({
auth: 'auth',
headers: {
authorization: 'auth',
},
hostname: 'renovate.com',
href: 'https://renovate.com',
search: 'something',
});
});
});
36 changes: 36 additions & 0 deletions lib/util/http/auth.ts
Expand Up @@ -24,3 +24,39 @@ export function applyAuthorization(inOptions: any): any {
}
return options;
}

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

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

// removeAuthorization from the redirect options
export function removeAuthorization(options: any): void {
if (!options.auth && !options.headers?.authorization) {
return;
}

// Check if request has been redirected to Amazon or an Azure blob (ACR)
if (isAmazon(options) || isAzureBlob(options)) {
// 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 = options.href.split('/')[2].split(':')[1];
if (!portInUrl) {
// eslint-disable-next-line no-param-reassign
delete options.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 options.headers.authorization; // eslint-disable-line no-param-reassign
delete options.auth; // eslint-disable-line no-param-reassign
}
}
21 changes: 2 additions & 19 deletions lib/util/http/index.ts
Expand Up @@ -4,7 +4,7 @@ import got from 'got';
import { ExternalHostError } from '../../types/errors/external-host-error';
import * as memCache from '../cache/memory';
import { clone } from '../clone';
import { applyAuthorization } from './auth';
import { applyAuthorization, removeAuthorization } from './auth';
import { applyHostRules } from './host-rules';

interface OutgoingHttpHeaders {
Expand Down Expand Up @@ -79,24 +79,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: [removeAuthorization],
};
options.headers = {
...options.headers,
Expand Down

0 comments on commit 45d7d40

Please sign in to comment.