github / github/copilot-cli

@github/copilot SDK mutates host `process.env` to inject `safe.bareRepository=explicit` for all spawned processes

Đang mở
#3,602 1 bình luận 8 reaction 0 người được giao Xem trên GitHub
area:configuration area:tools
Ngôn ngữ chính
Shell
Star
11.2k
Fork
1.9k
Merge trung bình
14 giờ 16 phút
Pull request đã merge (30 ngày)
6

Mô tả

## Summary

The Copilot CLI's `@github/copilot` package (v1.0.49, distributed via npm and also bundled with the GitHub Copilot Chat VS Code extension) unconditionally mutates the host process's `process.env` at SDK initialization to inject a Git hardening setting:

```
GIT_CONFIG_COUNT=
GIT_CONFIG_KEY_=safe.bareRepository
GIT_CONFIG_VALUE_=explicit
```

Because `process.env` is the process-wide environment, this propagates to every child process spawned from that host for its lifetime. When the host is VS Code's extension host (the Copilot Chat extension bundles `@github/copilot` and loads `./sdk`), this includes:

- Debuggee processes launched via "Run / Debug"
- Tests launched via Test Explorer (C# Dev Kit, etc.)
- VS Code tasks
- Tools/CLIs invoked from extensions, chat, or the integrated terminal

Any of those that perform Git operations against bare repositories — a legitimate, common pattern (SwiftPM caches, bare clones, server-side mirrors, tooling that creates ephemeral bare repos) — then fail with:

```
fatal: cannot use bare repository '' (safe.bareRepository is 'explicit')
```

even though the user's own Git configuration says `all` (or is unset, which defaults to `all`). There is no UI for this, no setting to opt out, and from the affected process's point of view the change is invisible — `git config --get safe.bareRepository` in the user's own shell still returns `all` because the override is only carried through `GIT_CONFIG_*` env vars inherited from the SDK host process tree.

## Where

The package source isn't published in this repo, so the evidence is from the shipped artifact:

`/Contents/Resources/app/extensions/copilot/node_modules/@github/copilot/sdk/index.js` (the same `@github/copilot` 1.0.49 that's on npm), minified function:

```js
function bHt() {
let t = parseInt(process.env.GIT_CONFIG_COUNT || "0", 10),
e = Number.isFinite(t) && t >= 0 ? t : 0,
r = Math.min(e, 64);
for (let n = 0; n < r; n++)
if (process.env[`GIT_CONFIG_KEY_${n}`] === "safe.bareRepository" &&
process.env[`GIT_CONFIG_VALUE_${n}`] === "explicit") return;
process.env.GIT_CONFIG_COUNT = String(e + 1);
process.env[`GIT_CONFIG_KEY_${e}`] = "safe.bareRepository";
process.env[`GIT_CONFIG_VALUE_${e}`] = "explicit";
}
```

Invoked from the SDK module's top-level init (`ky = A(() => { ...; bHt(); ... })`), so the mutation happens as soon as the SDK is imported.

If linkable source exists in an internal repo, please update the report — I could only verify against the minified bundle.

## Versions

- `@github/copilot` 1.0.49 (also installable standalone via `npm i -g @github/copilot`)
- Observed via Visual Studio Code 1.122.1, GitHub Copilot Chat extension 0.50.1 (bundles the SDK)

## Repro (standalone, no VS Code required)

```bash
# A Node process that imports the SDK leaks the env vars to its children:
node -e "import('@github/copilot/sdk').then(() => { \
console.log('COUNT=', process.env.GIT_CONFIG_COUNT); \
for (let i = 0; i < Number(process.env.GIT_CONFIG_COUNT||0); i++) \
console.log(i, process.env['GIT_CONFIG_KEY_'+i], '=', process.env['GIT_CONFIG_VALUE_'+i]); \
const { execSync } = require('child_process'); \
execSync('mkdir -p /tmp/bare-repro && git -C /tmp/bare-repro init --bare && git -C /tmp/bare-repro branch test', { stdio: 'inherit' }); \
});"
```

Expected (post-mutation):
```
COUNT= 1
0 safe.bareRepository = explicit
fatal: cannot use bare repository '/tmp/bare-repro' (safe.bareRepository is 'explicit')
```

In VS Code, the same symptom appears in any debuggee/test process the extension host spawns. `git config --show-origin --show-scope --get-all safe.bareRepository` inside that process reports `command command line: explicit` (i.e. it came from the inherited `GIT_CONFIG_*` env triple, not from any config file).

## Impact

- Silently breaks any tool/test that relies on the documented default `safe.bareRepository=all` while running under a host that has imported the SDK — most importantly VS Code with Copilot Chat installed, which is the default in modern installs.
- Symptoms reproduce only inside that host process tree, not in the user's regular shell, making it very hard to diagnose — the user's own Git config is fine; nothing the user controls explains the behavior.
- Already independently reported as downstream breakage attributed to "the Copilot CLI sandbox", e.g. yashasg/value-compass#217 (SwiftPM bare caches failing).
- Filed against the bundling extension as a side-channel at microsoft/vscode#319210; closing in favor of this issue at the source.

## Why this is a scope problem

`safe.bareRepository=explicit` is a personal hardening preference. Git positions it as something a user opts into in their own global config because they personally don't use bare repositories. The SDK silently applying it to the entire host process (and therefore to every child the user spawns from that host) is a global policy change the user did not opt into, cannot opt out of, and cannot even see without inspecting `process.env`. Even users who never call any Git-touching Copilot API are affected, just by Copilot's host process being alive.

## Suggested fix

- Stop mutating `process.env` in the equivalent of `bHt`.
- If the SDK shells out to `git` itself and needs this hardening, pass the `GIT_CONFIG_*` overrides via the `env` option of its own `spawn`/`execFile` calls, scoped to those children only.
- Alternatively, expose an explicit opt-in (and have callers like the VS Code extension decide whether to use it) rather than applying it unconditionally on import.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Hướng nghiên cứu

Bắt đầu với artifact được cung cấp tại /Contents/Resources/app/extensions/copilot/node_modules/@github/copilot/sdk/index.js và hàm bHt được gọi trong quá trình khởi tạo SDK. Chạy bản tái hiện Node độc lập để xác nhận các biến GIT_CONFIG_* được kế thừa và lỗi với bare repository. Được xem là hoàn tất khi SDK không còn thay đổi môi trường host, trong khi các thao tác Git của chính nó vẫn giữ mọi thiết lập scoped cần thiết.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
git, javascript, node.js
Lĩnh vực
cli, devtools, tooling
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Ít trao đổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
38/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.