Skip to content

[4.9] Only read from Git in app security check - #8842

Open
jek wants to merge 1 commit into
stable/4.9from
app-security/git-fsmonitor-4.9
Open

jek wants to merge 1 commit into
stable/4.9from
app-security/git-fsmonitor-4.9

Conversation

@jek

@jek jek commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

WHY are these changes introduced?

Back-port of #8841 to stable/4.9 for a patch release.

WHAT is this pull request doing?

Cherry-picks #8841's commit onto stable/4.9 without changes. Merge after #8841.

How to manually test your changes?

Follow the steps in #8841 on this branch.

app security check asks Git which files are tracked, which are ignored
and where a repository's top level is. Answering doesn't need Git to
run a program, start a background file-system monitor or fetch
anything, and the answers should come from the repository that
contains the app, not from repository files committed inside it. Git
takes the settings behind all of these from the repository being
scanned, so the check now overrides them.

Every Git command in the engine goes through one runGit helper that
applies four protections:

- `-c core.fsmonitor=` turns off the file-system monitor, which only
  speeds up reading the index.
- `-c safe.bareRepository=explicit` refuses a bare repository found in
  the working directory, such as one committed as ordinary files.
  Older Git versions ignore it; the other protections still apply.
- `GIT_NO_LAZY_FETCH=1` stops a partial clone from fetching a missing
  object, which would use the network and write to the repository.
- `GIT_ALLOW_PROTOCOL=` refuses every transport, which also covers Git
  versions without GIT_NO_LAZY_FETCH.

The tests build a repository for each case and show that plain Git
runs a program it names. They then show that each protection on its
own stops that program and that a scan runs nothing. A protection
added without a test fixture fails type-checking. The tests also run
on Windows.
@jek
jek requested a review from a team as a code owner October 8, 2026 19:35
@jek jek added Area: @shopify/cli @shopify/cli package issues Hackerone security labels Oct 8, 2026
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Differences in type declarations

We detected differences in the type declarations generated by Typescript for this branch compared to the baseline ('main' branch). Please, review them to ensure they are backward-compatible. Here are some important things to keep in mind:

  • Some seemingly private modules might be re-exported through public modules.
  • If the branch is behind main you might see odd diffs, rebase main into this branch.

New type declarations

We found no new type declarations in this PR

Existing type declarations

packages/cli-kit/dist/private/node/constants.d.ts
@@ -8,7 +8,6 @@ export declare const environmentVariables: {
     env: string;
     noAnalytics: string;
     optOutInstrumentation: string;
-    organizationAutomationToken: string;
     appAutomationToken: string;
     partnersToken: string;
     runAsUser: string;
packages/cli-kit/dist/public/node/environment.d.ts
@@ -10,13 +10,10 @@
  */
 export declare function getEnvironmentVariables(): NodeJS.ProcessEnv;
 /**
- * Returns the automation token the CLI authenticates with, from the first of these variables that is set:
- * SHOPIFY_ORGANIZATION_AUTOMATION_TOKEN, SHOPIFY_APP_AUTOMATION_TOKEN, or the deprecated SHOPIFY_CLI_PARTNERS_TOKEN.
+ * Returns the value of the SHOPIFY_APP_AUTOMATION_TOKEN environment variable,
+ * falling back to the deprecated SHOPIFY_CLI_PARTNERS_TOKEN.
  *
- * Returns undefined when the variables can't be used (an empty value, or the organization variable set alongside
- * another one). Callers then fall back to the login flow, which reports the problem instead of logging in.
- *
- * @returns The automation token, or undefined if there is no usable one.
+ * @returns The app automation token value, or undefined if neither env var is set.
  */
 export declare function getAppAutomationToken(): string | undefined;
 /**
packages/cli-kit/dist/public/node/session.d.ts
@@ -128,35 +128,14 @@ export declare function ensureAuthenticatedAdmin(store: string, scopes?: AdminAP
  * @returns The access token and store.
  */
 export declare function ensureAuthenticatedThemes(store: string, password: string | undefined, scopes?: AdminAPIScope[], options?: EnsureAuthenticatedAdditionalOptions): Promise<AdminSession>;
-/**
- * Options for `ensureAuthenticatedBusinessPlatform`.
- */
-export interface EnsureAuthenticatedBusinessPlatformOptions extends EnsureAuthenticatedAdditionalOptions {
-    /**
-     * Authenticate with the automation token set in the environment, when there is one, instead of the
-     * logged-in user. Only commands that support automation tokens opt in; other callers, such as
-     * Hydrogen's login, keep using the user's session.
-     */
-    allowAutomationToken?: boolean;
-}
 /**
  * Ensure that we have a valid session to access the Business Platform API.
  *
- * @param scopes - Optional array of extra scopes to authenticate with. Ignored when an automation token is used.
+ * @param scopes - Optional array of extra scopes to authenticate with.
  * @param options - Optional extra options to use.
  * @returns The access token for the Business Platform API.
  */
-export declare function ensureAuthenticatedBusinessPlatform(scopes?: BusinessPlatformScope[], options?: EnsureAuthenticatedBusinessPlatformOptions): Promise<string>;
-/**
- * Fails when SHOPIFY_ORGANIZATION_AUTOMATION_TOKEN is set, for commands that can't run with that token.
- *
- * Organization automation tokens can't log in as a user or call a store's Admin API, so commands that need either
- * refuse to run instead of quietly using the person's own login. `ensureAuthenticated` runs this check before any
- * login. Commands that run on a login saved by `shopify store auth` call it before loading that login.
- *
- * @throws AbortError when SHOPIFY_ORGANIZATION_AUTOMATION_TOKEN is set.
- */
-export declare function ensureNoOrganizationAutomationToken(): void;
+export declare function ensureAuthenticatedBusinessPlatform(scopes?: BusinessPlatformScope[], options?: EnsureAuthenticatedAdditionalOptions): Promise<string>;
 /**
  * Logout from Shopify.
  *
packages/cli-kit/dist/private/node/session/exchange.d.ts
@@ -45,10 +45,9 @@ export declare function exchangeAppAutomationTokenForAppManagementAccessToken(to
 /**
  * Given a custom app automation token passed as ENV variable, request a valid Business Platform API token.
  * @param token - The app automation token passed as ENV variable `SHOPIFY_APP_AUTOMATION_TOKEN`
- * @param scopes - The scopes to request. An empty list makes Identity issue every Business Platform scope the token holds.
  * @returns An instance with the application access tokens.
  */
-export declare function exchangeAppAutomationTokenForBusinessPlatformAccessToken(token: string, scopes?: string[]): Promise<{
+export declare function exchangeAppAutomationTokenForBusinessPlatformAccessToken(token: string): Promise<{
     accessToken: string;
     userId: string;
 }>;
packages/cli-kit/dist/public/node/error/schema.d.ts
@@ -30,24 +30,24 @@ export declare const JsonAbortErrorSchema: zod.ZodObject<{
     type: "abort";
     message: string;
     code?: string | undefined;
-    tryMessage?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
         body: string | string[][];
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
+    tryMessage?: string | undefined;
 }, {
     type: "abort";
     message: string;
     code?: string | undefined;
-    tryMessage?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
         body: string | string[][];
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
+    tryMessage?: string | undefined;
 }>;
 export declare const JsonBugErrorSchema: zod.ZodObject<{
     stack: zod.ZodOptional<zod.ZodString>;
@@ -71,7 +71,6 @@ export declare const JsonBugErrorSchema: zod.ZodObject<{
     type: "bug";
     message: string;
     code?: string | undefined;
-    tryMessage?: string | undefined;
     stack?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
@@ -79,11 +78,11 @@ export declare const JsonBugErrorSchema: zod.ZodObject<{
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
+    tryMessage?: string | undefined;
 }, {
     type: "bug";
     message: string;
     code?: string | undefined;
-    tryMessage?: string | undefined;
     stack?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
@@ -91,6 +90,7 @@ export declare const JsonBugErrorSchema: zod.ZodObject<{
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
+    tryMessage?: string | undefined;
 }>;
 export declare const JsonExternalErrorSchema: zod.ZodObject<{
     command: zod.ZodString;
@@ -117,26 +117,26 @@ export declare const JsonExternalErrorSchema: zod.ZodObject<{
     command: string;
     args: string[];
     code?: string | undefined;
-    tryMessage?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
         body: string | string[][];
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
+    tryMessage?: string | undefined;
 }, {
     type: "external";
     message: string;
     command: string;
     args: string[];
     code?: string | undefined;
-    tryMessage?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
         body: string | string[][];
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
+    tryMessage?: string | undefined;
 }>;
 export declare const JsonErrorSchema: zod.ZodUnion<[zod.ZodObject<{
     message: zod.ZodString;
@@ -159,24 +159,24 @@ export declare const JsonErrorSchema: zod.ZodUnion<[zod.ZodObject<{
     type: "abort";
     message: string;
     code?: string | undefined;
-    tryMessage?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
         body: string | string[][];
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
+    tryMessage?: string | undefined;
 }, {
     type: "abort";
     message: string;
     code?: string | undefined;
-    tryMessage?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
         body: string | string[][];
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
+    tryMessage?: string | undefined;
 }>, zod.ZodObject<{
     stack: zod.ZodOptional<zod.ZodString>;
     message: zod.ZodString;
@@ -199,7 +199,6 @@ export declare const JsonErrorSchema: zod.ZodUnion<[zod.ZodObject<{
     type: "bug";
     message: string;
     code?: string | undefined;
-    tryMessage?: string | undefined;
     stack?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
@@ -207,11 +206,11 @@ export declare const JsonErrorSchema: zod.ZodUnion<[zod.ZodObject<{
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
+    tryMessage?: string | undefined;
 }, {
     type: "bug";
     message: string;
     code?: string | undefined;
-    tryMessage?: string | undefined;
     stack?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
@@ -219,6 +218,7 @@ export declare const JsonErrorSchema: zod.ZodUnion<[zod.ZodObject<{
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
+    tryMessage?: string | undefined;
 }>, zod.ZodObject<{
     command: zod.ZodString;
     args: zod.ZodArray<zod.ZodString, "many">;
@@ -244,26 +244,26 @@ export declare const JsonErrorSchema: zod.ZodUnion<[zod.ZodObject<{
     command: string;
     args: string[];
     code?: string | undefined;
-    tryMessage?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
         body: string | string[][];
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
+    tryMessage?: string | undefined;
 }, {
     type: "external";
     message: string;
     command: string;
     args: string[];
     code?: string | undefined;
-    tryMessage?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
         body: string | string[][];
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
+    tryMessage?: string | undefined;
 }>]>;
 export declare const jsonErrorOutputSchema: import("../json-output-schema.js").JsonOutputSchema<zod.ZodObject<{
     error: zod.ZodUnion<[zod.ZodObject<{
@@ -287,24 +287,24 @@ export declare const jsonErrorOutputSchema: import("../json-output-schema.js").J
         type: "abort";
         message: string;
         code?: string | undefined;
-        tryMessage?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
             body: string | string[][];
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
+        tryMessage?: string | undefined;
     }, {
         type: "abort";
         message: string;
         code?: string | undefined;
-        tryMessage?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
             body: string | string[][];
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
+        tryMessage?: string | undefined;
     }>, zod.ZodObject<{
         stack: zod.ZodOptional<zod.ZodString>;
         message: zod.ZodString;
@@ -327,7 +327,6 @@ export declare const jsonErrorOutputSchema: import("../json-output-schema.js").J
         type: "bug";
         message: string;
         code?: string | undefined;
-        tryMessage?: string | undefined;
         stack?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
@@ -335,11 +334,11 @@ export declare const jsonErrorOutputSchema: import("../json-output-schema.js").J
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
+        tryMessage?: string | undefined;
     }, {
         type: "bug";
         message: string;
         code?: string | undefined;
-        tryMessage?: string | undefined;
         stack?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
@@ -347,6 +346,7 @@ export declare const jsonErrorOutputSchema: import("../json-output-schema.js").J
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
+        tryMessage?: string | undefined;
     }>, zod.ZodObject<{
         command: zod.ZodString;
         args: zod.ZodArray<zod.ZodString, "many">;
@@ -372,44 +372,43 @@ export declare const jsonErrorOutputSchema: import("../json-output-schema.js").J
         command: string;
         args: string[];
         code?: string | undefined;
-        tryMessage?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
             body: string | string[][];
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
+        tryMessage?: string | undefined;
     }, {
         type: "external";
         message: string;
         command: string;
         args: string[];
         code?: string | undefined;
-        tryMessage?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
             body: string | string[][];
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
+        tryMessage?: string | undefined;
     }>]>;
 }, "strict", zod.ZodTypeAny, {
     error: {
         type: "abort";
         message: string;
         code?: string | undefined;
-        tryMessage?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
             body: string | string[][];
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
+        tryMessage?: string | undefined;
     } | {
         type: "bug";
         message: string;
         code?: string | undefined;
-        tryMessage?: string | undefined;
         stack?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
@@ -417,37 +416,37 @@ export declare const jsonErrorOutputSchema: import("../json-output-schema.js").J
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
+        tryMessage?: string | undefined;
     } | {
         type: "external";
         message: string;
         command: string;
         args: string[];
         code?: string | undefined;
-        tryMessage?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
             body: string | string[][];
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
+        tryMessage?: string | undefined;
     };
 }, {
     error: {
         type: "abort";
         message: string;
         code?: string | undefined;
-        tryMessage?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
             body: string | string[][];
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
+        tryMessage?: string | undefined;
     } | {
         type: "bug";
         message: string;
         code?: string | undefined;
-        tryMessage?: string | undefined;
         stack?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
@@ -455,18 +454,19 @@ export declare const jsonErrorOutputSchema: import("../json-output-schema.js").J
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
+        tryMessage?: string | undefined;
     } | {
         type: "external";
         message: string;
         command: string;
         args: string[];
         code?: string | undefined;
-        tryMessage?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
             body: string | string[][];
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
+        tryMessage?: string | undefined;
     };
 }>>;
\ No newline at end of file

@jek
jek requested a review from jplhomer October 8, 2026 19:56

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant