From e4e6c8dd3c58616147634aba69bde2c72e2335d7 Mon Sep 17 00:00:00 2001 From: gonzaloriestra <14979109+gonzaloriestra@users.noreply.github.com> Date: Thu, 18 Jun 2026 00:17:56 +0000 Subject: [PATCH 1/2] [Security] Redact SHOPIFY_API_SECRET from console output --- knip_output.txt | 3 +++ .../app/src/cli/services/app/env/pull.test.ts | 8 ++++---- packages/app/src/cli/services/app/env/pull.ts | 15 ++++++++++++--- .../app/src/cli/services/app/env/show.test.ts | 2 +- packages/app/src/cli/services/app/env/show.ts | 5 +++-- 5 files changed, 23 insertions(+), 10 deletions(-) create mode 100644 knip_output.txt diff --git a/knip_output.txt b/knip_output.txt new file mode 100644 index 00000000000..e9d479a4c55 --- /dev/null +++ b/knip_output.txt @@ -0,0 +1,3 @@ + +> @0.0.0 knip /app +> knip --workspace \@shopify/app diff --git a/packages/app/src/cli/services/app/env/pull.test.ts b/packages/app/src/cli/services/app/env/pull.test.ts index c8fd46e2488..8058faa2944 100644 --- a/packages/app/src/cli/services/app/env/pull.test.ts +++ b/packages/app/src/cli/services/app/env/pull.test.ts @@ -40,7 +40,7 @@ describe('env pull', () => { "Created ${filePath}: SHOPIFY_API_KEY=api-key - SHOPIFY_API_SECRET=api-secret + SHOPIFY_API_SECRET=****** SCOPES=my-scope " `) @@ -66,15 +66,15 @@ describe('env pull', () => { "Updated ${filePath} to be: SHOPIFY_API_KEY=api-key - SHOPIFY_API_SECRET=api-secret + SHOPIFY_API_SECRET=****** SCOPES=my-scope Here's what changed: - SHOPIFY_API_KEY=ABC - - SHOPIFY_API_SECRET=XYZ + - SHOPIFY_API_SECRET=****** + SHOPIFY_API_KEY=api-key - + SHOPIFY_API_SECRET=api-secret + + SHOPIFY_API_SECRET=****** SCOPES=my-scope " `) diff --git a/packages/app/src/cli/services/app/env/pull.ts b/packages/app/src/cli/services/app/env/pull.ts index 422749dd02e..4aea8b3476d 100644 --- a/packages/app/src/cli/services/app/env/pull.ts +++ b/packages/app/src/cli/services/app/env/pull.ts @@ -34,13 +34,20 @@ export async function pullEnv({app, remoteApp, organization, envFile}: PullEnvOp await writeFile(envFile, updatedEnvFileContent) const diff = diffLines(envFileContent ?? '', updatedEnvFileContent) + const redactedDiff = diff.map((change) => ({ + ...change, + value: change.value.replace(/^(SHOPIFY_API_SECRET=)(.*)$/gm, '$1******'), + })) + + const redactedEnvFileContent = updatedEnvFileContent.replace(/^(SHOPIFY_API_SECRET=)(.*)$/gm, '$1******') + return outputContent`Updated ${outputToken.path(envFile)} to be: -${updatedEnvFileContent} +${redactedEnvFileContent} Here's what changed: -${outputToken.linesDiff(diff)} +${outputToken.linesDiff(redactedDiff)} ` } } else { @@ -48,9 +55,11 @@ ${outputToken.linesDiff(diff)} await writeFile(envFile, newEnvFileContent) + const redactedEnvFileContent = newEnvFileContent.replace(/^(SHOPIFY_API_SECRET=)(.*)$/gm, '$1******') + return outputContent`Created ${outputToken.path(envFile)}: -${newEnvFileContent} +${redactedEnvFileContent} ` } } diff --git a/packages/app/src/cli/services/app/env/show.test.ts b/packages/app/src/cli/services/app/env/show.test.ts index cd3e039e7c9..5fb54348c3f 100644 --- a/packages/app/src/cli/services/app/env/show.test.ts +++ b/packages/app/src/cli/services/app/env/show.test.ts @@ -38,7 +38,7 @@ describe('env show', () => { expect(unstyled(stringifyMessage(result))).toMatchInlineSnapshot(` " SHOPIFY_API_KEY=api-key - SHOPIFY_API_SECRET=api-secret + SHOPIFY_API_SECRET=****** SCOPES=my-scope " `) diff --git a/packages/app/src/cli/services/app/env/show.ts b/packages/app/src/cli/services/app/env/show.ts index a2dbab01a07..51bb478253f 100644 --- a/packages/app/src/cli/services/app/env/show.ts +++ b/packages/app/src/cli/services/app/env/show.ts @@ -21,16 +21,17 @@ export async function outputEnv( ): Promise { await logMetadataForLoadedContext(remoteApp, organization.source) + const redactedApiSecret = remoteApp.apiSecretKeys[0]?.secret ? '******' : '' if (format === 'json') { return outputContent`${outputToken.json({ SHOPIFY_API_KEY: remoteApp.apiKey, - SHOPIFY_API_SECRET: remoteApp.apiSecretKeys[0]?.secret, + SHOPIFY_API_SECRET: redactedApiSecret, SCOPES: getAppScopes(app.configuration), })}` } else { return outputContent` ${outputToken.green('SHOPIFY_API_KEY')}=${remoteApp.apiKey} - ${outputToken.green('SHOPIFY_API_SECRET')}=${remoteApp.apiSecretKeys[0]?.secret ?? ''} + ${outputToken.green('SHOPIFY_API_SECRET')}=${redactedApiSecret} ${outputToken.green('SCOPES')}=${getAppScopes(app.configuration)} ` } From 667ec15703856b9fb6cb42de7217f5090851e4a9 Mon Sep 17 00:00:00 2001 From: gonzaloriestra <14979109+gonzaloriestra@users.noreply.github.com> Date: Thu, 18 Jun 2026 00:29:52 +0000 Subject: [PATCH 2/2] [Security] Redact SHOPIFY_API_SECRET from console output --- packages/app/src/cli/services/info.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/app/src/cli/services/info.test.ts b/packages/app/src/cli/services/info.test.ts index 2b7acb04be0..9d89d8974e9 100644 --- a/packages/app/src/cli/services/info.test.ts +++ b/packages/app/src/cli/services/info.test.ts @@ -97,7 +97,7 @@ describe('info', () => { expect(unstyled(stringifyMessage(result))).toMatchInlineSnapshot(` " SHOPIFY_API_KEY=api-key - SHOPIFY_API_SECRET=api-secret + SHOPIFY_API_SECRET=****** SCOPES=my-scope " `) @@ -121,7 +121,7 @@ describe('info', () => { expect(unstyled(stringifyMessage(result))).toMatchInlineSnapshot(` "{ "SHOPIFY_API_KEY": "api-key", - "SHOPIFY_API_SECRET": "api-secret", + "SHOPIFY_API_SECRET": "******", "SCOPES": "my-scope" }" `)