From fcddd8192ea2d94015d83c22fc143b988cb3b255 Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Tue, 15 Sep 2026 10:43:12 -0500 Subject: [PATCH] Remove the dependency CVE audit check from app doctor Co-authored-by: AI (Pi/GPT-6 Astra) --- .changeset/remove-app-doctor-cve-audit.md | 4 + .../app/src/cli/commands/app/doctor.test.ts | 2 - packages/app/src/cli/commands/app/doctor.ts | 4 +- .../checks/KNOWN_CVE_IN_DEPENDENCY.md | 9 - .../app-doctor-engine/checks/embedded.ts | 1 - .../app-doctor-engine/rules/catalog.ts | 9 - .../rules/dependency-rules.ts | 822 ------------------ .../services/app-doctor-engine/rules/types.ts | 14 - .../app-doctor-engine/scanners/discover.ts | 16 +- .../app-doctor-engine/scanners/index.ts | 54 +- .../app-doctor-engine/scanners/types.ts | 2 - .../app-doctor-engine/tests/checks.test.ts | 6 +- .../tests/deterministic-rules.test.ts | 59 +- .../tests/discovery-safety.test.ts | 47 - .../fixtures/submission-forbidden-values.json | 2 +- .../tests/fixtures/submission-trace.ts | 22 +- .../tests/fixtures/submission.json | 18 +- .../tests/rule-analysis.test.ts | 497 +---------- .../tests/scan-contract.test.ts | 2 - .../tests/submission.test.ts | 8 +- .../services/app-doctor-engine/trace/index.ts | 3 +- .../cli/services/app-doctor-engine/types.ts | 3 +- packages/cli/oclif.manifest.json | 4 +- 23 files changed, 45 insertions(+), 1563 deletions(-) create mode 100644 .changeset/remove-app-doctor-cve-audit.md delete mode 100644 packages/app/src/cli/services/app-doctor-engine/checks/KNOWN_CVE_IN_DEPENDENCY.md delete mode 100644 packages/app/src/cli/services/app-doctor-engine/rules/dependency-rules.ts diff --git a/.changeset/remove-app-doctor-cve-audit.md b/.changeset/remove-app-doctor-cve-audit.md new file mode 100644 index 00000000000..47049e37158 --- /dev/null +++ b/.changeset/remove-app-doctor-cve-audit.md @@ -0,0 +1,4 @@ +--- +'@shopify/app': patch +--- +Remove the dependency CVE audit check from `shopify app doctor`. diff --git a/packages/app/src/cli/commands/app/doctor.test.ts b/packages/app/src/cli/commands/app/doctor.test.ts index d93320d911e..35edf81fdc3 100644 --- a/packages/app/src/cli/commands/app/doctor.test.ts +++ b/packages/app/src/cli/commands/app/doctor.test.ts @@ -62,8 +62,6 @@ describe('app doctor command', () => { expect(Doctor.descriptionWithMarkdown).toContain('copy the coding-agent instructions') expect(Doctor.descriptionWithMarkdown).toContain('copying is the default') expect(Doctor.descriptionWithMarkdown).toContain('shopify app doctor instructions') - expect(Doctor.descriptionWithMarkdown).toContain('npm audit') - expect(Doctor.descriptionWithMarkdown).toContain('https://registry.npmjs.org/') }) test('allows --yes in JSON mode while preserving non-interactive output behavior', async () => { diff --git a/packages/app/src/cli/commands/app/doctor.ts b/packages/app/src/cli/commands/app/doctor.ts index 8fa19782ed5..a4026ecb5a4 100644 --- a/packages/app/src/cli/commands/app/doctor.ts +++ b/packages/app/src/cli/commands/app/doctor.ts @@ -15,9 +15,7 @@ export default class Doctor extends BaseCommand { static descriptionWithMarkdown = `Runs Shopify App Doctor locally and creates its review pack and trace. -Pass \`--findings\` after completing the review pack to validate agent findings and compile them into the trace. In interactive terminals, the command offers to copy the coding-agent instructions, print them, or choose nothing; copying is the default. In CI and other non-interactive environments, instructions aren't offered unless you pass \`--yes\`, which prints them. JSON output never prompts or prints those instructions. You can also run \`shopify app doctor instructions\` to print, copy, or write them later. - -CVE detection runs \`npm audit\` (or the pnpm/yarn equivalent) in an isolated sandbox and sends package names and versions to the public npm registry at https://registry.npmjs.org/.` +Pass \`--findings\` after completing the review pack to validate agent findings and compile them into the trace. In interactive terminals, the command offers to copy the coding-agent instructions, print them, or choose nothing; copying is the default. In CI and other non-interactive environments, instructions aren't offered unless you pass \`--yes\`, which prints them. JSON output never prompts or prints those instructions. You can also run \`shopify app doctor instructions\` to print, copy, or write them later.` static description = this.descriptionWithoutMarkdown() diff --git a/packages/app/src/cli/services/app-doctor-engine/checks/KNOWN_CVE_IN_DEPENDENCY.md b/packages/app/src/cli/services/app-doctor-engine/checks/KNOWN_CVE_IN_DEPENDENCY.md deleted file mode 100644 index 38d7494daee..00000000000 --- a/packages/app/src/cli/services/app-doctor-engine/checks/KNOWN_CVE_IN_DEPENDENCY.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -id: KNOWN_CVE_IN_DEPENDENCY -version: 3 -severity: medium ---- - -# Known Cve In Dependency - -When deterministic package-manager audit is unavailable, inspect the JavaScript manifest and lockfile statically for known vulnerable dependency versions. Do not execute the repository's package manager, scripts, plugins, binaries, or configuration. Distinguish version exposure from reachable impact: when source evidence allows it, check whether the app actually uses the vulnerable API or helper and whether the relevant configuration is enabled, especially for Shopify SDK behavior that depends on how a helper is called. If static evidence cannot confirm either the vulnerable version or the vulnerable API/helper reachability, mark the check unresolved instead of running repository-controlled code. diff --git a/packages/app/src/cli/services/app-doctor-engine/checks/embedded.ts b/packages/app/src/cli/services/app-doctor-engine/checks/embedded.ts index 3b9dd05e602..e2ae6adcdb0 100644 --- a/packages/app/src/cli/services/app-doctor-engine/checks/embedded.ts +++ b/packages/app/src/cli/services/app-doctor-engine/checks/embedded.ts @@ -16,7 +16,6 @@ export const EMBEDDED_CHECK_SOURCES: ReadonlyArray = [ "---\nid: EOL_API_VERSION\nversion: 1\nseverity: low\n---\n\n# Eol Api Version\n\nInspect every unresolved `shopify.app*.toml` plus React Router `app/shopify.server.*` declarations. Shopify publishes quarterly versions in January, April, July, and October and supports each stable version for 12 months; App Doctor allows a documented 30-day extension grace period before reporting it as end-of-life. Cite the exact declaration. For malformed config, computed `ApiVersion` values, or a Shopify-announced exceptional extension, inspect the source and current lifecycle policy rather than inferring from unrelated constants.\n", "---\nid: EXPIRING_OFFLINE_TOKEN\nversion: 1\nseverity: medium\n---\n\n# Expiring Offline Token\n\nFor supported React Router apps, verify `expiringOfflineAccessTokens` is enabled and the selected session storage persists `expires`, `refreshToken`, and `refreshTokenExpires` metadata needed for refresh and rotation. `isOnline: false` selects an offline session; it does not disable token expiry and is not a finding. Report an explicit `expiringOfflineAccessTokens: false`. Treat absent or computed flags, custom storage, and ambiguous Prisma schemas as unresolved investigation: inspect storage adapters, migrations, and serialization before returning a clean result. Config-only and unsupported frameworks are handled by the runtime applicability boundary.\n", "---\nid: INSECURE_WEBHOOK_URL\nversion: 2\nseverity: high\n---\n\n# Insecure Configured Callback Url\n\nInspect webhook destinations and OAuth redirect URLs in every unresolved Shopify app configuration. Relative Shopify paths and valid pubsub/eventbridge webhook destinations are allowed. Report HTTP, malformed, credential-bearing, wildcard-host, wildcard-path, or otherwise unsafe configured callback URLs.\n", - "---\nid: KNOWN_CVE_IN_DEPENDENCY\nversion: 3\nseverity: medium\n---\n\n# Known Cve In Dependency\n\nWhen deterministic package-manager audit is unavailable, inspect the JavaScript manifest and lockfile statically for known vulnerable dependency versions. Do not execute the repository's package manager, scripts, plugins, binaries, or configuration. Distinguish version exposure from reachable impact: when source evidence allows it, check whether the app actually uses the vulnerable API or helper and whether the relevant configuration is enabled, especially for Shopify SDK behavior that depends on how a helper is called. If static evidence cannot confirm either the vulnerable version or the vulnerable API/helper reachability, mark the check unresolved instead of running repository-controlled code.\n", "---\nid: LIQUID_UNSAFE_RENDER\nversion: 1\nseverity: medium\n---\n\n# Liquid Unsafe Render\n\nInspect only theme-extension Liquid/HTML files the parser could not analyze. Liquid output is not automatically HTML-escaped. Check the destination: use `escape`/`escape_once` for HTML text and ordinary attributes, `json` when embedding a value as JavaScript data, and `metafield_tag` only for supported rich metafield rendering in HTML content. HTML escaping is not sufficient for event handlers, `srcdoc`, or a `