-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Closed
Description
Issue: Overly Restrictive .env File Blocking
Summary
The Read tool blocks access to ANY file containing ".env" in its path, preventing legitimate reads of:
- Environment configuration files (
.env.local,.env.development,.env.production) - Source code files with "env" in the path (
environment/,config/env/) - Template/example files that should be readable (
.env.template)
Reproduction
Current Behavior
// Trying to read any file with "env" in path
Read({ filePath: ".env.local" })
// ❌ Error: "The user has blocked you from reading .env.local, DO NOT make further attempts to read it"
Read({ filePath: "src/config/environment.ts" })
// ❌ Error: "The user has blocked you from reading src/config/environment.ts, DO NOT make further attempts to read it"
Read({ filePath: ".env.template" })
// ❌ Error: "The user has blocked you from reading .env.template, DO NOT make further attempts to read it"Files Currently Blocked
❌ Blocked (shouldn't be):
.env.local,.env.development,.env.production.env.templatesrc/environment/config.tsconfig/env/settings.ts- Any path containing "env"
✅ Allowed (whitelist):
.env.sample- Files ending with
.example
Root Cause
Location: packages/opencode/src/tool/read.ts:63-74
const block = iife(() => {
const whitelist = [".env.sample", ".example"]
if (whitelist.some((w) => filepath.endsWith(w))) return false
if (filepath.includes(".env")) return true // ❌ TOO BROAD
return false
})
if (block) {
throw new Error(`The user has blocked you from reading ${filepath}, DO NOT make further attempts to read it`)
}Problem: The check filepath.includes(".env") blocks:
- Any file with "env" anywhere in the path (not just .env files)
- All .env variants (
.env.local,.env.development, etc.) - Template files that are safe to read
Impact
Development Workflow Issues
- Configuration Discovery: Cannot read environment config files to understand app setup
- Template Usage: Cannot read
.env.templateor.env.examplefiles - Source Code: Cannot read legitimate source files with "env" in path
- Debugging: Cannot inspect environment configuration when troubleshooting
Security Intent
The blocking was likely intended to:
- ✅ Prevent leaking secrets in
.env - ✅ Protect production credentials
However, it's too aggressive and blocks safe files.
Proposed Solution
Recommended Fix: Basename-Based Blocking
Make the blocking more precise by checking only the filename, not the full path:
const block = iife(() => {
const whitelist = [
".env.sample",
".env.example",
".example",
".env.template",
".env.schema"
]
if (whitelist.some((w) => filepath.endsWith(w))) return false
// Only block files that ARE actual .env files (basename check)
const basename = path.basename(filepath)
if (basename.startsWith(".env")) return true
return false
})
if (block) {
throw new Error(`The user has blocked you from reading ${filepath}, DO NOT make further attempts to read it`)
}Alternative: Pattern-Based Whitelist
More explicit pattern matching:
const block = iife(() => {
const basename = path.basename(filepath)
// Whitelist: Safe template/example files
const safePatterns = [
/\.env\.sample$/,
/\.env\.example$/,
/\.env\.template$/,
/\.env\.schema$/,
/\.example$/
]
if (safePatterns.some(pattern => pattern.test(filepath))) {
return false
}
// Block: Actual .env files with potential secrets
const blockPatterns = [
/^\.env$/, // .env
/^\.env\.local$/, // .env.local
/^\.env\.development$/, // .env.development
/^\.env\.production$/, // .env.production
/^\.env\.staging$/, // .env.staging
/^\.env\.test$/, // .env.test
/^\.env\.[a-z]+\.local$/ // .env.*.local
]
return blockPatterns.some(pattern => pattern.test(basename))
})Comparison Table
| File Path | Current Behavior | After Fix |
|---|---|---|
.env |
❌ Blocked | ❌ Blocked (correct) |
.env.local |
❌ Blocked | ❌ Blocked (correct) |
.env.production |
❌ Blocked | ❌ Blocked (correct) |
.env.sample |
✅ Allowed | ✅ Allowed |
.env.example |
✅ Allowed | ✅ Allowed |
.env.template |
❌ Blocked | ✅ Allowed (fix) |
src/environment.ts |
❌ Blocked | ✅ Allowed (fix) |
config/env/settings.ts |
❌ Blocked | ✅ Allowed (fix) |
.example |
✅ Allowed | ✅ Allowed |
Testing
To verify fix:
// Test 1: Block actual .env files
Read({ filePath: ".env" })
// Should throw: blocked
Read({ filePath: ".env.local" })
// Should throw: blocked
// Test 2: Allow template files
Read({ filePath: ".env.template" })
// Should succeed
Read({ filePath: ".env.example" })
// Should succeed
// Test 3: Allow source files with "env" in path
Read({ filePath: "src/config/environment.ts" })
// Should succeed
Read({ filePath: "utils/envParser.ts" })
// Should succeedSecurity Considerations
The fix maintains security by:
- ✅ Still blocking
.envand variants (.env.local,.env.production, etc.) - ✅ Preventing accidental secret leakage
- ✅ Allowing safe template/example files
- ✅ Not blocking legitimate source code
Additional Context
- Security Goal: Prevent reading files with actual secrets
- User Experience: Allow reading configuration templates and source code
- Best Practice: Use
.env.exampleor.env.templatefor documentation - Related Code:
packages/opencode/src/tool/read.ts
References
- Twelve-Factor App: https://12factor.net/config
- dotenv best practices: https://github.com/motdotla/dotenv#should-i-commit-my-env-file
bennyzen, jdtzmn, muness and adamjhf
Metadata
Metadata
Assignees
Labels
No labels