Skip to content

Commit 07d394e

Browse files
Adib234gemini-cli-robot
authored andcommitted
Revert unintended credentials exposure (#18840)
1 parent 7030590 commit 07d394e

File tree

6 files changed

+8
-132
lines changed

6 files changed

+8
-132
lines changed

docs/tools/mcp-server.md

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -739,21 +739,10 @@ The MCP integration tracks several states:
739739
cautiously and only for servers you completely control
740740
- **Access tokens:** Be security-aware when configuring environment variables
741741
containing API keys or tokens
742-
- **Environment variable redaction:** By default, the Gemini CLI redacts
743-
sensitive environment variables (such as `GEMINI_API_KEY`, `GOOGLE_API_KEY`,
744-
and variables matching patterns like `*TOKEN*`, `*SECRET*`, `*PASSWORD*`) when
745-
spawning MCP servers using the `stdio` transport. This prevents unintended
746-
exposure of your credentials to third-party servers.
747-
- **Explicit environment variables:** If you need to pass a specific environment
748-
variable to an MCP server, you should define it explicitly in the `env`
749-
property of the server configuration in `settings.json`.
750742
- **Sandbox compatibility:** When using sandboxing, ensure MCP servers are
751-
available within the sandbox environment.
743+
available within the sandbox environment
752744
- **Private data:** Using broadly scoped personal access tokens can lead to
753745
information leakage between repositories.
754-
- **Untrusted servers:** Be extremely cautious when adding MCP servers from
755-
untrusted or third-party sources. Malicious servers could attempt to
756-
exfiltrate data or perform unauthorized actions through the tools they expose.
757746

758747
### Performance and resource management
759748

packages/cli/src/commands/mcp/add.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,6 @@ async function addMcpServer(
128128

129129
settings.setValue(settingsScope, 'mcpServers', mcpServers);
130130

131-
if (transport === 'stdio') {
132-
debugLogger.warn(
133-
'Security Warning: Running MCP servers with stdio transport can expose inherited environment variables. ' +
134-
'While the Gemini CLI redacts common API keys and secrets by default, you should only run servers from trusted sources.',
135-
);
136-
}
137-
138131
if (isExistingServer) {
139132
debugLogger.log(`MCP server "${name}" updated in ${scope} settings.`);
140133
} else {

packages/core/src/services/environmentSanitization.test.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,6 @@ describe('sanitizeEnvironment', () => {
4646
CLIENT_ID: 'sensitive-id',
4747
DB_URI: 'sensitive-uri',
4848
DATABASE_URL: 'sensitive-url',
49-
GEMINI_API_KEY: 'sensitive-gemini-key',
50-
GOOGLE_API_KEY: 'sensitive-google-key',
51-
GOOGLE_APPLICATION_CREDENTIALS: '/path/to/creds.json',
5249
SAFE_VAR: 'is-safe',
5350
};
5451
const sanitized = sanitizeEnvironment(env, EMPTY_OPTIONS);

packages/core/src/services/environmentSanitization.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,6 @@ export const NEVER_ALLOWED_ENVIRONMENT_VARIABLES: ReadonlySet<string> = new Set(
103103
'GOOGLE_CLOUD_PROJECT',
104104
'GOOGLE_CLOUD_ACCOUNT',
105105
'FIREBASE_PROJECT_ID',
106-
'GEMINI_API_KEY',
107-
'GOOGLE_API_KEY',
108-
'GOOGLE_APPLICATION_CREDENTIALS',
109106
],
110107
);
111108

packages/core/src/tools/mcp-client.test.ts

Lines changed: 2 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1623,7 +1623,7 @@ describe('mcp-client', () => {
16231623
{
16241624
command: 'test-command',
16251625
args: ['--foo', 'bar'],
1626-
env: { GEMINI_CLI_FOO: 'bar' },
1626+
env: { FOO: 'bar' },
16271627
cwd: 'test/cwd',
16281628
},
16291629
false,
@@ -1634,80 +1634,11 @@ describe('mcp-client', () => {
16341634
command: 'test-command',
16351635
args: ['--foo', 'bar'],
16361636
cwd: 'test/cwd',
1637-
env: expect.objectContaining({ GEMINI_CLI_FOO: 'bar' }),
1637+
env: expect.objectContaining({ FOO: 'bar' }),
16381638
stderr: 'pipe',
16391639
});
16401640
});
16411641

1642-
it('should redact sensitive environment variables for command transport', async () => {
1643-
const mockedTransport = vi
1644-
.spyOn(SdkClientStdioLib, 'StdioClientTransport')
1645-
.mockReturnValue({} as SdkClientStdioLib.StdioClientTransport);
1646-
1647-
const originalEnv = process.env;
1648-
process.env = {
1649-
...originalEnv,
1650-
GEMINI_API_KEY: 'sensitive-key',
1651-
GEMINI_CLI_SAFE_VAR: 'safe-value',
1652-
};
1653-
// Ensure strict sanitization is not triggered for this test
1654-
delete process.env['GITHUB_SHA'];
1655-
delete process.env['SURFACE'];
1656-
1657-
try {
1658-
await createTransport(
1659-
'test-server',
1660-
{
1661-
command: 'test-command',
1662-
},
1663-
false,
1664-
EMPTY_CONFIG,
1665-
);
1666-
1667-
const callArgs = mockedTransport.mock.calls[0][0];
1668-
expect(callArgs.env).toBeDefined();
1669-
expect(callArgs.env!['GEMINI_CLI_SAFE_VAR']).toBe('safe-value');
1670-
expect(callArgs.env!['GEMINI_API_KEY']).toBeUndefined();
1671-
} finally {
1672-
process.env = originalEnv;
1673-
}
1674-
});
1675-
1676-
it('should include extension settings in environment', async () => {
1677-
const mockedTransport = vi
1678-
.spyOn(SdkClientStdioLib, 'StdioClientTransport')
1679-
.mockReturnValue({} as SdkClientStdioLib.StdioClientTransport);
1680-
1681-
await createTransport(
1682-
'test-server',
1683-
{
1684-
command: 'test-command',
1685-
extension: {
1686-
name: 'test-ext',
1687-
resolvedSettings: [
1688-
{
1689-
envVar: 'GEMINI_CLI_EXT_VAR',
1690-
value: 'ext-value',
1691-
sensitive: false,
1692-
name: 'ext-setting',
1693-
},
1694-
],
1695-
version: '',
1696-
isActive: false,
1697-
path: '',
1698-
contextFiles: [],
1699-
id: '',
1700-
},
1701-
},
1702-
false,
1703-
EMPTY_CONFIG,
1704-
);
1705-
1706-
const callArgs = mockedTransport.mock.calls[0][0];
1707-
expect(callArgs.env).toBeDefined();
1708-
expect(callArgs.env!['GEMINI_CLI_EXT_VAR']).toBe('ext-value');
1709-
});
1710-
17111642
it('should exclude extension settings with undefined values from environment', async () => {
17121643
const mockedTransport = vi
17131644
.spyOn(SdkClientStdioLib, 'StdioClientTransport')

packages/core/src/tools/mcp-client.ts

Lines changed: 5 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,7 @@ import {
3434
} from '@modelcontextprotocol/sdk/types.js';
3535
import { ApprovalMode, PolicyDecision } from '../policy/types.js';
3636
import { parse } from 'shell-quote';
37-
import type {
38-
Config,
39-
GeminiCLIExtension,
40-
MCPServerConfig,
41-
} from '../config/config.js';
37+
import type { Config, MCPServerConfig } from '../config/config.js';
4238
import { AuthProviderType } from '../config/config.js';
4339
import { GoogleCredentialProvider } from '../mcp/google-auth-provider.js';
4440
import { ServiceAccountImpersonationProvider } from '../mcp/sa-impersonation-provider.js';
@@ -1936,23 +1932,10 @@ export async function createTransport(
19361932
command: mcpServerConfig.command,
19371933
args: mcpServerConfig.args || [],
19381934
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
1939-
env: sanitizeEnvironment(
1940-
{
1941-
...process.env,
1942-
...getExtensionEnvironment(mcpServerConfig.extension),
1943-
...(mcpServerConfig.env || {}),
1944-
},
1945-
{
1946-
...sanitizationConfig,
1947-
allowedEnvironmentVariables: [
1948-
...(sanitizationConfig.allowedEnvironmentVariables ?? []),
1949-
...(mcpServerConfig.extension?.resolvedSettings?.map(
1950-
(s) => s.envVar,
1951-
) ?? []),
1952-
],
1953-
enableEnvironmentVariableRedaction: true,
1954-
},
1955-
) as Record<string, string>,
1935+
env: {
1936+
...sanitizeEnvironment(process.env, sanitizationConfig),
1937+
...(mcpServerConfig.env || {}),
1938+
} as Record<string, string>,
19561939
cwd: mcpServerConfig.cwd,
19571940
stderr: 'pipe',
19581941
});
@@ -2027,17 +2010,3 @@ export function isEnabled(
20272010
)
20282011
);
20292012
}
2030-
2031-
function getExtensionEnvironment(
2032-
extension?: GeminiCLIExtension,
2033-
): Record<string, string> {
2034-
const env: Record<string, string> = {};
2035-
if (extension?.resolvedSettings) {
2036-
for (const setting of extension.resolvedSettings) {
2037-
if (setting.value) {
2038-
env[setting.envVar] = setting.value;
2039-
}
2040-
}
2041-
}
2042-
return env;
2043-
}

0 commit comments

Comments
 (0)