T05 · Unauthorized Access and Privilege Escalation
- Location
- scripts/notion_apply_records.js:84
- Finding
- Complete Host Environment Exposed to an External Dependency Process<![CDATA[ ## Vulnerability Details **File Location**: `scripts/notion_apply_records.js`, lines 84–85 and 101–104 **Vulnerability Type**: Excessive environment-variable disclosure to a child process **Risk Level**: Medium ### Vulnerable Code ```javascript function safeEnv(extra = {}) { return { ...process.env, ...extra }; } ``` ```javascript const env = safeEnv({ NOTION_VERSION: notionVersion() }); let out = ''; try { out = execFileSync('node', args, { encoding: 'utf-8', env, stdio: ['ignore', 'pipe', 'pipe'] }).trim(); } ``` ### Technical Analysis The script copies the complete parent-process environment into the child process that executes `notionctl.mjs`. This includes not only the Notion credential needed for the operation, but potentially unrelated cloud credentials, database passwords, CI/CD tokens, signing keys, proxy credentials, and other secrets injected into the host agent. The child component is installed separately and is outside this project's reviewed source. Providing it with all available environment variables violates least privilege: the declared functionality requires Notion authentication and limited runtime configuration, not access to every environment-backed secret. Although environment inheritance is common for child processes, it creates a security boundary problem when the child is an independently distributed dependency. The exposure is particularly significant in combination with the unpinned dependency identified separately in this report. ### Attack Path 1. An attacker compromises the installed `notion-api-automation` dependency, its distribution account, or a mutable release. 2. The user invokes `scripts/notion_apply_records.js`. 3. The script resolves and executes the dependency's `notionctl.mjs`. 4. `safeEnv()` passes the complete `process.env` object to that process. 5. The compromised dependency enumerates environment variables and retrieves unrelated credentials. 6. The dependency transmits or other ...[truncated 576 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Replace full environment inheritance with an explicit allowlist. Include only variables required for process execution and the documented Notion workflow, for example: - `PATH` - `HOME`, if module resolution requires it - `NOTION_API_KEY` - Explicitly supported legacy Notion authentication variables, only if necessary - `NOTION_VERSION` - Deliberately supported TLS or proxy variables Example hardening approach: ```javascript function notionctlEnv() { const allowed = [ 'PATH', 'HOME', 'NOTION_API_KEY', 'NOTION_TOKEN', 'NOTION_API_TOKEN', 'HTTPS_PROXY', 'NO_PROXY', 'NODE_EXTRA_CA_CERTS' ]; const env = {}; for (const key of allowed) { if (process.env[key] !== undefined) { env[key] = process.env[key]; } } env.NOTION_VERSION = notionVersion(); return env; } ``` Use this restricted object as the `env` option for `execFileSync`. Document each forwarded variable and remove legacy authentication aliases when compatibility is no longer necessary. Add an automated test confirming that an unrelated sentinel secret in `process.env` is not inherited by the child process. ]]>
