From 6d898f71ea9ba4ceeb9fed8b9101b80da9abf1a0 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 8 Feb 2024 12:19:53 +0100 Subject: [PATCH] integrations: trim secrets read from config Signed-off-by: Patrik Oldsberg --- .changeset/khaki-seahorses-joke.md | 6 ++++++ packages/integration-aws-node/src/config.ts | 4 ++-- .../src/awsS3/AwsS3Integration.test.ts | 2 +- packages/integration/src/awsS3/config.ts | 2 +- packages/integration/src/azure/config.test.ts | 4 ++-- packages/integration/src/azure/config.ts | 16 +++++++++------- .../integration/src/bitbucket/config.test.ts | 4 ++-- packages/integration/src/bitbucket/config.ts | 4 ++-- .../src/bitbucketCloud/config.test.ts | 2 +- .../integration/src/bitbucketCloud/config.ts | 2 +- .../src/bitbucketServer/config.test.ts | 2 +- .../integration/src/bitbucketServer/config.ts | 2 +- packages/integration/src/gerrit/config.test.ts | 2 +- packages/integration/src/gerrit/config.ts | 2 +- packages/integration/src/gitea/config.test.ts | 2 +- packages/integration/src/gitea/config.ts | 2 +- packages/integration/src/github/config.test.ts | 2 +- packages/integration/src/github/config.ts | 2 +- packages/integration/src/gitlab/config.test.ts | 2 +- packages/integration/src/gitlab/config.ts | 2 +- 20 files changed, 37 insertions(+), 29 deletions(-) create mode 100644 .changeset/khaki-seahorses-joke.md diff --git a/.changeset/khaki-seahorses-joke.md b/.changeset/khaki-seahorses-joke.md new file mode 100644 index 0000000000..9382d6f108 --- /dev/null +++ b/.changeset/khaki-seahorses-joke.md @@ -0,0 +1,6 @@ +--- +'@backstage/integration-aws-node': patch +'@backstage/integration': patch +--- + +All single-line secrets read from config will now have both leading and trailing whitespace trimmed. This is done to ensure that the secrets are always valid HTTP header values, since many fetch implementations will include the header value itself when an error is thrown due to invalid header values. diff --git a/packages/integration-aws-node/src/config.ts b/packages/integration-aws-node/src/config.ts index 0bc8c0ed06..5cf34e4dd3 100644 --- a/packages/integration-aws-node/src/config.ts +++ b/packages/integration-aws-node/src/config.ts @@ -152,7 +152,7 @@ function readAwsIntegrationAccountConfig( const accountConfig = { accountId: config.getString('accountId'), accessKeyId: config.getOptionalString('accessKeyId'), - secretAccessKey: config.getOptionalString('secretAccessKey'), + secretAccessKey: config.getOptionalString('secretAccessKey')?.trim(), profile: config.getOptionalString('profile'), roleName: config.getOptionalString('roleName'), region: config.getOptionalString('region'), @@ -216,7 +216,7 @@ function readMainAwsIntegrationAccountConfig( ): AwsIntegrationMainAccountConfig { const mainAccountConfig = { accessKeyId: config.getOptionalString('accessKeyId'), - secretAccessKey: config.getOptionalString('secretAccessKey'), + secretAccessKey: config.getOptionalString('secretAccessKey')?.trim(), profile: config.getOptionalString('profile'), region: config.getOptionalString('region'), }; diff --git a/packages/integration/src/awsS3/AwsS3Integration.test.ts b/packages/integration/src/awsS3/AwsS3Integration.test.ts index 2987f46a8a..6f3b603dc9 100644 --- a/packages/integration/src/awsS3/AwsS3Integration.test.ts +++ b/packages/integration/src/awsS3/AwsS3Integration.test.ts @@ -26,7 +26,7 @@ describe('AwsS3Integration', () => { { endpoint: 'https://a.com', accessKeyId: 'access key', - secretAccessKey: 'secret key', + secretAccessKey: ' secret key ', }, ], }, diff --git a/packages/integration/src/awsS3/config.ts b/packages/integration/src/awsS3/config.ts index 477741b839..83f0fb60d6 100644 --- a/packages/integration/src/awsS3/config.ts +++ b/packages/integration/src/awsS3/config.ts @@ -101,7 +101,7 @@ export function readAwsS3IntegrationConfig( } const accessKeyId = config.getOptionalString('accessKeyId'); - const secretAccessKey = config.getOptionalString('secretAccessKey'); + const secretAccessKey = config.getOptionalString('secretAccessKey')?.trim(); const roleArn = config.getOptionalString('roleArn'); const externalId = config.getOptionalString('externalId'); diff --git a/packages/integration/src/azure/config.test.ts b/packages/integration/src/azure/config.test.ts index eb36120c32..dc6781c45e 100644 --- a/packages/integration/src/azure/config.test.ts +++ b/packages/integration/src/azure/config.test.ts @@ -70,7 +70,7 @@ describe('readAzureIntegrationConfig', () => { credentials: [ { organizations: ['org1'], - personalAccessToken: 't', + personalAccessToken: 't ', }, ], }), @@ -119,7 +119,7 @@ describe('readAzureIntegrationConfig', () => { { organizations: ['org1', 'org2'], clientId: 'id', - clientSecret: 'secret', + clientSecret: 'secret\n\n\n', tenantId: 'tenant', }, ], diff --git a/packages/integration/src/azure/config.ts b/packages/integration/src/azure/config.ts index 5c16394484..5ed1914ea2 100644 --- a/packages/integration/src/azure/config.ts +++ b/packages/integration/src/azure/config.ts @@ -205,18 +205,18 @@ export function readAzureIntegrationConfig( ?.map(credential => { const result: Partial = { organizations: credential.getOptionalStringArray('organizations'), - personalAccessToken: credential.getOptionalString( - 'personalAccessToken', - ), + personalAccessToken: credential + .getOptionalString('personalAccessToken') + ?.trim(), tenantId: credential.getOptionalString('tenantId'), clientId: credential.getOptionalString('clientId'), - clientSecret: credential.getOptionalString('clientSecret'), + clientSecret: credential.getOptionalString('clientSecret')?.trim(), }; return result; }); - const token = config.getOptionalString('token'); + const token = config.getOptionalString('token')?.trim(); if ( config.getOptional('credential') !== undefined && @@ -247,10 +247,12 @@ export function readAzureIntegrationConfig( organizations: config.getOptionalStringArray( 'credential.organizations', ), - token: config.getOptionalString('credential.token'), + token: config.getOptionalString('credential.token')?.trim(), tenantId: config.getOptionalString('credential.tenantId'), clientId: config.getOptionalString('credential.clientId'), - clientSecret: config.getOptionalString('credential.clientSecret'), + clientSecret: config + .getOptionalString('credential.clientSecret') + ?.trim(), }, ]; credentialConfigs = credentialConfigs?.concat(mapped) ?? mapped; diff --git a/packages/integration/src/bitbucket/config.test.ts b/packages/integration/src/bitbucket/config.test.ts index 5440b174c8..8dd20cade7 100644 --- a/packages/integration/src/bitbucket/config.test.ts +++ b/packages/integration/src/bitbucket/config.test.ts @@ -58,9 +58,9 @@ describe('readBitbucketIntegrationConfig', () => { buildConfig({ host: 'a.com', apiBaseUrl: 'https://a.com/api', - token: 't', + token: 't\n\n\n', username: 'u', - appPassword: 'p', + appPassword: '\n\n\np', }), ); expect(output).toEqual({ diff --git a/packages/integration/src/bitbucket/config.ts b/packages/integration/src/bitbucket/config.ts index 11839094da..4b6296b0e9 100644 --- a/packages/integration/src/bitbucket/config.ts +++ b/packages/integration/src/bitbucket/config.ts @@ -76,9 +76,9 @@ export function readBitbucketIntegrationConfig( ): BitbucketIntegrationConfig { const host = config.getOptionalString('host') ?? BITBUCKET_HOST; let apiBaseUrl = config.getOptionalString('apiBaseUrl'); - const token = config.getOptionalString('token'); + const token = config.getOptionalString('token')?.trim(); const username = config.getOptionalString('username'); - const appPassword = config.getOptionalString('appPassword'); + const appPassword = config.getOptionalString('appPassword')?.trim(); if (!isValidHost(host)) { throw new Error( diff --git a/packages/integration/src/bitbucketCloud/config.test.ts b/packages/integration/src/bitbucketCloud/config.test.ts index 9f7a66e2bf..2c68059196 100644 --- a/packages/integration/src/bitbucketCloud/config.test.ts +++ b/packages/integration/src/bitbucketCloud/config.test.ts @@ -55,7 +55,7 @@ describe('readBitbucketCloudIntegrationConfig', () => { const output = readBitbucketCloudIntegrationConfig( buildConfig({ username: 'u', - appPassword: 'p', + appPassword: '\n\n\np', }), ); expect(output).toEqual({ diff --git a/packages/integration/src/bitbucketCloud/config.ts b/packages/integration/src/bitbucketCloud/config.ts index 710957900e..5ecabfedc4 100644 --- a/packages/integration/src/bitbucketCloud/config.ts +++ b/packages/integration/src/bitbucketCloud/config.ts @@ -62,7 +62,7 @@ export function readBitbucketCloudIntegrationConfig( // If config is provided, we assume authenticated access is desired // (as the anonymous one is provided by default). const username = config.getString('username'); - const appPassword = config.getString('appPassword'); + const appPassword = config.getString('appPassword')?.trim(); return { host, diff --git a/packages/integration/src/bitbucketServer/config.test.ts b/packages/integration/src/bitbucketServer/config.test.ts index 985165f23f..425ffc5ca4 100644 --- a/packages/integration/src/bitbucketServer/config.test.ts +++ b/packages/integration/src/bitbucketServer/config.test.ts @@ -60,7 +60,7 @@ describe('readBitbucketServerIntegrationConfig', () => { buildConfig({ host: 'a.com', apiBaseUrl: 'https://a.com/api', - token: 't', + token: '\tt\t', }), ); expect(output).toEqual({ diff --git a/packages/integration/src/bitbucketServer/config.ts b/packages/integration/src/bitbucketServer/config.ts index 2f93bdeb07..1412b7ab17 100644 --- a/packages/integration/src/bitbucketServer/config.ts +++ b/packages/integration/src/bitbucketServer/config.ts @@ -77,7 +77,7 @@ export function readBitbucketServerIntegrationConfig( ): BitbucketServerIntegrationConfig { const host = config.getString('host'); let apiBaseUrl = config.getOptionalString('apiBaseUrl'); - const token = config.getOptionalString('token'); + const token = config.getOptionalString('token')?.trim(); const username = config.getOptionalString('username'); const password = config.getOptionalString('password'); diff --git a/packages/integration/src/gerrit/config.test.ts b/packages/integration/src/gerrit/config.test.ts index f9287f6801..583687bd23 100644 --- a/packages/integration/src/gerrit/config.test.ts +++ b/packages/integration/src/gerrit/config.test.ts @@ -59,7 +59,7 @@ describe('readGerritIntegrationConfig', () => { cloneUrl: 'https:a.com/clone', gitilesBaseUrl: 'https://a.com/git', username: 'u', - password: 'p', + password: ' p ', }), ); expect(output).toEqual({ diff --git a/packages/integration/src/gerrit/config.ts b/packages/integration/src/gerrit/config.ts index 8558ff0c1b..c3ee3aaa24 100644 --- a/packages/integration/src/gerrit/config.ts +++ b/packages/integration/src/gerrit/config.ts @@ -78,7 +78,7 @@ export function readGerritIntegrationConfig( let cloneUrl = config.getOptionalString('cloneUrl'); let gitilesBaseUrl = config.getOptionalString('gitilesBaseUrl'); const username = config.getOptionalString('username'); - const password = config.getOptionalString('password'); + const password = config.getOptionalString('password')?.trim(); if (!isValidHost(host)) { throw new Error( diff --git a/packages/integration/src/gitea/config.test.ts b/packages/integration/src/gitea/config.test.ts index cdcc7e3f3e..5a85c12aab 100644 --- a/packages/integration/src/gitea/config.test.ts +++ b/packages/integration/src/gitea/config.test.ts @@ -53,7 +53,7 @@ describe('readGiteaConfig', () => { host: 'a.com', baseUrl: 'https://a.com/route/api', username: 'u', - password: 'p', + password: 'p ', }), ); expect(output).toEqual({ diff --git a/packages/integration/src/gitea/config.ts b/packages/integration/src/gitea/config.ts index 99c5b5c1f7..28070d570d 100644 --- a/packages/integration/src/gitea/config.ts +++ b/packages/integration/src/gitea/config.ts @@ -56,7 +56,7 @@ export function readGiteaConfig(config: Config): GiteaIntegrationConfig { const host = config.getString('host'); let baseUrl = config.getOptionalString('baseUrl'); const username = config.getOptionalString('username'); - const password = config.getOptionalString('password'); + const password = config.getOptionalString('password')?.trim(); if (!isValidHost(host)) { throw new Error( diff --git a/packages/integration/src/github/config.test.ts b/packages/integration/src/github/config.test.ts index c4d9eb1900..9eca82701f 100644 --- a/packages/integration/src/github/config.test.ts +++ b/packages/integration/src/github/config.test.ts @@ -57,7 +57,7 @@ describe('readGithubIntegrationConfig', () => { host: 'a.com', apiBaseUrl: 'https://a.com/api', rawBaseUrl: 'https://a.com/raw', - token: 't', + token: '\nt\t', }), ); expect(output).toEqual({ diff --git a/packages/integration/src/github/config.ts b/packages/integration/src/github/config.ts index cd76eba3d3..1ff4779be2 100644 --- a/packages/integration/src/github/config.ts +++ b/packages/integration/src/github/config.ts @@ -123,7 +123,7 @@ export function readGithubIntegrationConfig( const host = config.getOptionalString('host') ?? GITHUB_HOST; let apiBaseUrl = config.getOptionalString('apiBaseUrl'); let rawBaseUrl = config.getOptionalString('rawBaseUrl'); - const token = config.getOptionalString('token'); + const token = config.getOptionalString('token')?.trim(); const apps = config.getOptionalConfigArray('apps')?.map(c => ({ appId: c.getNumber('appId'), clientId: c.getString('clientId'), diff --git a/packages/integration/src/gitlab/config.test.ts b/packages/integration/src/gitlab/config.test.ts index db03285206..f1d17a6d7e 100644 --- a/packages/integration/src/gitlab/config.test.ts +++ b/packages/integration/src/gitlab/config.test.ts @@ -55,7 +55,7 @@ describe('readGitLabIntegrationConfig', () => { const output = readGitLabIntegrationConfig( buildConfig({ host: 'a.com', - token: 't', + token: ' t\n', apiBaseUrl: 'https://a.com', baseUrl: 'https://baseurl.for.me/gitlab', }), diff --git a/packages/integration/src/gitlab/config.ts b/packages/integration/src/gitlab/config.ts index 301fe46f90..79161561f3 100644 --- a/packages/integration/src/gitlab/config.ts +++ b/packages/integration/src/gitlab/config.ts @@ -67,7 +67,7 @@ export function readGitLabIntegrationConfig( ): GitLabIntegrationConfig { const host = config.getString('host'); let apiBaseUrl = config.getOptionalString('apiBaseUrl'); - const token = config.getOptionalString('token'); + const token = config.getOptionalString('token')?.trim(); let baseUrl = config.getOptionalString('baseUrl'); if (apiBaseUrl) { apiBaseUrl = trimEnd(apiBaseUrl, '/');