fix(core): strip desktop-mode credentials from Agent command environments (#180)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6f60b242bd
commit
d312d368b8
2 files changed
+28
-2
No files matched your search
@@ -61,7 +61,20 @@ const HARDENED_ENV: NodeJS.ProcessEnv = {
|
|||||||
* self-development case may legitimately want the same data root — sharing state is a config
|
* self-development case may legitimately want the same data root — sharing state is a config
|
||||||
* decision, whereas serving a deployment's code from a workspace checkout never is.
|
* decision, whereas serving a deployment's code from a workspace checkout never is.
|
||||||
*/
|
*/
|
||||||
const STRIPPED_ENV_KEYS = new Set(["PORT", "HOST", "PENGUIN_CLI_ENTRY", "PENGUIN_WEB_DIST"]);
|
const STRIPPED_ENV_KEYS = new Set([
|
||||||
|
"PORT",
|
||||||
|
"HOST",
|
||||||
|
"PENGUIN_CLI_ENTRY",
|
||||||
|
"PENGUIN_WEB_DIST",
|
||||||
|
// Desktop-mode process credentials and wiring: the shell's token authorizes the
|
||||||
|
// server shutdown endpoint (and desktop-login until redeemed), and the port file is
|
||||||
|
// the shell's private channel — neither is a user-facing setting, and leaking them
|
||||||
|
// into Agent-run commands would let a prompt-injected command stop the server.
|
||||||
|
"PENGUIN_DESKTOP_TOKEN",
|
||||||
|
"PENGUIN_PORT_FILE",
|
||||||
|
// Pinned seed password (tests/e2e): a credential, not a data-selection setting.
|
||||||
|
"PENGUIN_SEED_ADMIN_PASSWORD",
|
||||||
|
]);
|
||||||
|
|
||||||
/** The host environment minus {@link STRIPPED_ENV_KEYS}. */
|
/** The host environment minus {@link STRIPPED_ENV_KEYS}. */
|
||||||
function hostEnvForChild(): NodeJS.ProcessEnv {
|
function hostEnvForChild(): NodeJS.ProcessEnv {
|
||||||
|
|||||||
@@ -294,7 +294,15 @@ describe("exec_command — long-running command sessions", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("harness environment variables never reach a spawned command", () => {
|
describe("harness environment variables never reach a spawned command", () => {
|
||||||
const KEYS = ["PORT", "HOST", "PENGUIN_CLI_ENTRY", "PENGUIN_WEB_DIST"] as const;
|
const KEYS = [
|
||||||
|
"PORT",
|
||||||
|
"HOST",
|
||||||
|
"PENGUIN_CLI_ENTRY",
|
||||||
|
"PENGUIN_WEB_DIST",
|
||||||
|
"PENGUIN_DESKTOP_TOKEN",
|
||||||
|
"PENGUIN_PORT_FILE",
|
||||||
|
"PENGUIN_SEED_ADMIN_PASSWORD",
|
||||||
|
] as const;
|
||||||
const saved: Partial<Record<(typeof KEYS)[number], string | undefined>> = {};
|
const saved: Partial<Record<(typeof KEYS)[number], string | undefined>> = {};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -305,6 +313,11 @@ describe("harness environment variables never reach a spawned command", () => {
|
|||||||
process.env.HOST = "127.0.0.1";
|
process.env.HOST = "127.0.0.1";
|
||||||
process.env.PENGUIN_CLI_ENTRY = "/opt/penguin/lib/dist/index.js";
|
process.env.PENGUIN_CLI_ENTRY = "/opt/penguin/lib/dist/index.js";
|
||||||
process.env.PENGUIN_WEB_DIST = "/opt/penguin/web";
|
process.env.PENGUIN_WEB_DIST = "/opt/penguin/web";
|
||||||
|
// The desktop shell's process credentials (see design § "桌面端原型"): a leaked token
|
||||||
|
// would let an Agent-run command call the server's shutdown endpoint.
|
||||||
|
process.env.PENGUIN_DESKTOP_TOKEN = "secret-desktop-token";
|
||||||
|
process.env.PENGUIN_PORT_FILE = "/tmp/port-file";
|
||||||
|
process.env.PENGUIN_SEED_ADMIN_PASSWORD = "penguin-0000";
|
||||||
});
|
});
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
for (const k of KEYS) {
|
for (const k of KEYS) {
|
||||||
|
|||||||
Reference in new issue
Block a user