diff --git a/.jules/sentinel.md b/.jules/sentinel.md index a6c92980..c7b49c79 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -126,3 +126,15 @@ Error messages should never include raw values from sensitive sources like envir **Prevention:** 1. Avoid including raw values in error messages when the source is potentially sensitive (env vars, auth headers). 2. Use generic error messages for validation failures of sensitive data. + +## 2026-04-20 - [MEDIUM] Environment Variable Leakage in Configuration Error Messages + +**Vulnerability:** +Several configuration parsers (`EnvConfigParser`, `MCPServer`, and `artifact-signing-config`) were throwing `ConfigurationError` messages that included the raw, invalid values provided by environment variables. For example, `throw new ConfigurationError(\`...got '${entry}'\`);`. If an administrator mistakenly mapped an environment variable containing a sensitive secret (like an API key or a secret threshold) to one of these configuration fields, the invalid value (the secret) would be logged or returned to the user in the error message. + +**Learning:** +Validation and configuration error messages must be careful not to echo back the exact invalid input when that input originates from a source that might contain sensitive data, such as environment variables. A seemingly harmless error message can inadvertently become an information disclosure vector. + +**Prevention:** +1. Do not include raw input values in error messages for configuration parameters derived from environment variables. +2. State the expected format or type in the error message without reflecting the invalid input. diff --git a/src/automation/artifact-signing-config.ts b/src/automation/artifact-signing-config.ts index 1b328b7f..678f0613 100644 --- a/src/automation/artifact-signing-config.ts +++ b/src/automation/artifact-signing-config.ts @@ -53,5 +53,5 @@ function parseExplicitBoolean(value: string | undefined, envName: string): boole return false; } - throw new ConfigurationError(`${envName} must be either 'true' or 'false', got '${normalized}'.`); + throw new ConfigurationError(`${envName} must be either 'true' or 'false'.`); } diff --git a/src/mcp/mcp-server.ts b/src/mcp/mcp-server.ts index 9e35ac39..e26dfeed 100644 --- a/src/mcp/mcp-server.ts +++ b/src/mcp/mcp-server.ts @@ -2483,7 +2483,7 @@ export class MCPServer { const parsed = Number(raw); if (Number.isNaN(parsed) || parsed <= 0) { throw new ConfigurationError( - `Invalid MCP4_TOOL_FILTER_WARN_THRESHOLD_PCT: expected positive number, got '${raw}'.` + `Invalid MCP4_TOOL_FILTER_WARN_THRESHOLD_PCT: expected positive number.` ); } return parsed; diff --git a/src/tool-filter/config/env-config-parser.ts b/src/tool-filter/config/env-config-parser.ts index e11a617f..178d3a93 100644 --- a/src/tool-filter/config/env-config-parser.ts +++ b/src/tool-filter/config/env-config-parser.ts @@ -100,7 +100,7 @@ export class EnvConfigParser { } throw new ConfigurationError( - `MCP4_TOOL_FILTER_ALLOW_CATEGORIES supports only 'list' and 'read', got '${entry}'` + `MCP4_TOOL_FILTER_ALLOW_CATEGORIES supports only 'list' and 'read'` ); }