fix(security): block cloud credential env vars in MCP env cleaner
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import { describe, it, expect, beforeEach, afterEach } from "bun:test"
|
||||
/// <reference types="bun-types" />
|
||||
|
||||
import { describe, it, expect, afterEach } from "bun:test"
|
||||
import { createCleanMcpEnvironment, EXCLUDED_ENV_PATTERNS } from "./env-cleaner"
|
||||
|
||||
describe("createCleanMcpEnvironment", () => {
|
||||
@@ -207,6 +209,16 @@ describe("EXCLUDED_ENV_PATTERNS", () => {
|
||||
{ pattern: "YARN_CACHE_FOLDER", shouldMatch: true },
|
||||
{ pattern: "PNPM_HOME", shouldMatch: true },
|
||||
{ pattern: "NO_UPDATE_NOTIFIER", shouldMatch: true },
|
||||
{ pattern: "GOOGLE_APPLICATION_CREDENTIALS", shouldMatch: true },
|
||||
{ pattern: "GOOGLE_CLOUD_PROJECT", shouldMatch: true },
|
||||
{ pattern: "AZURE_CLIENT_ID", shouldMatch: true },
|
||||
{ pattern: "GCP_SERVICE_ACCOUNT", shouldMatch: true },
|
||||
{ pattern: "FIREBASE_CONFIG", shouldMatch: true },
|
||||
{ pattern: "HEROKU_API_KEY", shouldMatch: true },
|
||||
{ pattern: "DOCKER_AUTH_CONFIG", shouldMatch: true },
|
||||
{ pattern: "KUBECONFIG", shouldMatch: true },
|
||||
{ pattern: "VAULT_TOKEN", shouldMatch: true },
|
||||
{ pattern: "APP_CREDENTIALS", shouldMatch: true },
|
||||
{ pattern: "PATH", shouldMatch: false },
|
||||
{ pattern: "HOME", shouldMatch: false },
|
||||
{ pattern: "NODE_ENV", shouldMatch: false },
|
||||
@@ -289,6 +301,21 @@ describe("secret env var filtering", () => {
|
||||
expect(cleanEnv.DB_PASSWORD).toBeUndefined()
|
||||
expect(cleanEnv.TERM).toBe("xterm-256color")
|
||||
})
|
||||
|
||||
it("filters out exact cloud credential env vars", () => {
|
||||
// given
|
||||
process.env.GOOGLE_APPLICATION_CREDENTIALS = "/tmp/gcp-service-account.json"
|
||||
process.env.GOOGLE_CLOUD_PROJECT = "demo-project"
|
||||
process.env.PATH = "/usr/bin"
|
||||
|
||||
// when
|
||||
const cleanEnv = createCleanMcpEnvironment()
|
||||
|
||||
// then
|
||||
expect(cleanEnv.GOOGLE_APPLICATION_CREDENTIALS).toBeUndefined()
|
||||
expect(cleanEnv.GOOGLE_CLOUD_PROJECT).toBeUndefined()
|
||||
expect(cleanEnv.PATH).toBe("/usr/bin")
|
||||
})
|
||||
})
|
||||
|
||||
describe("suffix-based secret filtering", () => {
|
||||
@@ -382,6 +409,50 @@ describe("suffix-based secret filtering", () => {
|
||||
expect(cleanEnv.SENDGRID_API_KEY).toBeUndefined()
|
||||
expect(cleanEnv.SHELL).toBe("/bin/zsh")
|
||||
})
|
||||
|
||||
it("filters variables ending with _CREDENTIALS", () => {
|
||||
// given
|
||||
process.env.GOOGLE_APPLICATION_CREDENTIALS = "/tmp/gcp-service-account.json"
|
||||
process.env.APP_CREDENTIALS = "service-account"
|
||||
process.env.HOME = "/home/user"
|
||||
|
||||
// when
|
||||
const cleanEnv = createCleanMcpEnvironment()
|
||||
|
||||
// then
|
||||
expect(cleanEnv.GOOGLE_APPLICATION_CREDENTIALS).toBeUndefined()
|
||||
expect(cleanEnv.APP_CREDENTIALS).toBeUndefined()
|
||||
expect(cleanEnv.HOME).toBe("/home/user")
|
||||
})
|
||||
})
|
||||
|
||||
describe("cloud provider env filtering", () => {
|
||||
it("filters cloud provider and infrastructure prefixes without breaking safe vars", () => {
|
||||
// given
|
||||
process.env.AZURE_CLIENT_ID = "azure-client"
|
||||
process.env.GCP_SERVICE_ACCOUNT = "gcp-account"
|
||||
process.env.FIREBASE_CONFIG = "firebase-config"
|
||||
process.env.HEROKU_API_KEY = "heroku-key"
|
||||
process.env.DOCKER_AUTH_CONFIG = '{"auths":{}}'
|
||||
process.env.KUBECONFIG = "/tmp/kubeconfig"
|
||||
process.env.VAULT_TOKEN_HELPER = "vault-helper"
|
||||
process.env.PATH = "/usr/bin"
|
||||
process.env.USER = "testuser"
|
||||
|
||||
// when
|
||||
const cleanEnv = createCleanMcpEnvironment()
|
||||
|
||||
// then
|
||||
expect(cleanEnv.AZURE_CLIENT_ID).toBeUndefined()
|
||||
expect(cleanEnv.GCP_SERVICE_ACCOUNT).toBeUndefined()
|
||||
expect(cleanEnv.FIREBASE_CONFIG).toBeUndefined()
|
||||
expect(cleanEnv.HEROKU_API_KEY).toBeUndefined()
|
||||
expect(cleanEnv.DOCKER_AUTH_CONFIG).toBeUndefined()
|
||||
expect(cleanEnv.KUBECONFIG).toBeUndefined()
|
||||
expect(cleanEnv.VAULT_TOKEN_HELPER).toBeUndefined()
|
||||
expect(cleanEnv.PATH).toBe("/usr/bin")
|
||||
expect(cleanEnv.USER).toBe("testuser")
|
||||
})
|
||||
})
|
||||
|
||||
describe("safe environment variables preserved", () => {
|
||||
|
||||
@@ -12,9 +12,18 @@ export const EXCLUDED_ENV_PATTERNS: RegExp[] = [
|
||||
/^ANTHROPIC_API_KEY$/i,
|
||||
/^AWS_ACCESS_KEY_ID$/i,
|
||||
/^AWS_SECRET_ACCESS_KEY$/i,
|
||||
/^GOOGLE_APPLICATION_CREDENTIALS$/i,
|
||||
/^GOOGLE_CLOUD_PROJECT$/i,
|
||||
/^GITHUB_TOKEN$/i,
|
||||
/^DATABASE_URL$/i,
|
||||
/^OPENAI_API_KEY$/i,
|
||||
/^AZURE_/i,
|
||||
/^GCP_/i,
|
||||
/^FIREBASE_/i,
|
||||
/^HEROKU_/i,
|
||||
/^DOCKER_AUTH/i,
|
||||
/^KUBECONFIG$/i,
|
||||
/^VAULT_/i,
|
||||
|
||||
// Suffix-based patterns for common secret naming conventions
|
||||
/_KEY$/i,
|
||||
@@ -22,6 +31,7 @@ export const EXCLUDED_ENV_PATTERNS: RegExp[] = [
|
||||
/_TOKEN$/i,
|
||||
/_PASSWORD$/i,
|
||||
/_CREDENTIAL$/i,
|
||||
/_CREDENTIALS$/i,
|
||||
/_API_KEY$/i,
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user