-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Labels
bugSomething isn't workingSomething isn't workingsecuritySecurity vulnerability fixesSecurity vulnerability fixes
Description
Component
forge-core (registry, tools, security, channels, LLM), forge-cli (commands, TUI wizard, runtime), forge-skills (skill parser, compiler, analyzer, trust)
Description
Four medium priority security hardening items identified via cross-reference with OpenClaw 2026.2.19 / 2026.2.20.
Re-verified 2026-03-12 against latest main (commit 7d2148b). Key changes from original analysis:
- M-9 significantly downgraded: Originally assessed as "fixed". Re-verification found only 1 of 7 temp file locations is secure. Six sites use predictable naming and world-readable
0644permissions. Now tracked here instead of "already fixed".- H-4 (Slack dedup) moved to Phase 2 since it was found to be fully missing, not partial.
Reference: FORGE-SECURITY-UPDATE.md — Phase 3
Steps to reproduce
M-4. Memory Files Stored with Weak Permissions
- Files:
forge-core/memory/filestore.go,forge-core/memory/vectorstore.go - Memory directory created with
0o755(world-readable). Files written with0o644:filestore.go:20—os.MkdirAll(dir, 0o755)filestore.go:48— daily log0o644filestore.go:95— MEMORY.md0o644vectorstore.go:179— index.json0o644
- Any local user can read agent memory, conversation history, and embeddings.
M-7. Skill Environment Override Sanitization
- File:
forge-cli/runtime/subprocess.go(lines 62–68) - Copies entire parent environment (
os.Environ()), then appends skill-provided env vars without sanitization. A skill can setLD_PRELOAD,NODE_OPTIONS,PYTHONPATH, etc. to inject code into tool runtimes.
M-8. Plugin Path Containment
- Files:
forge-skills/local/scanner.go,forge-skills/trust/ - Scanner uses
fs.FSabstraction providing some containment, but no explicit realpath validation, no world-writable directory checks, no lstat checks to distinguish symlinks.
M-9. Temp File Naming and Permissions — Multiple Vulnerable Sites
- Secure (1 of 7):
forge-core/secrets/encrypted_file_provider.go:191— usesos.CreateTemp()+0600 - Vulnerable (6 of 7):
forge-cli/runtime/scheduler_store.go:165—s.path + ".tmp"withos.Create(predictable, default perms)forge-core/runtime/memory_store.go:70—fname + ".tmp"withos.Create(predictable, default perms)forge-cli/cmd/channel.go:71—os.OpenFile(envPath, ..., 0644)(world-readable .env)forge-cli/cmd/init.go:562,828,847,866—os.Create/os.OpenFilewith default or0644permsforge-cli/cmd/serve.go:203—os.OpenFile(logPath, ..., 0644)(world-readable logs)forge-cli/cmd/skills.go:210—os.OpenFile(envPath, ..., 0o644)(world-readable .env)
Expected behavior
- M-4: Memory directory
0o700, files0o600(owner-only access). - M-7: Dangerous env vars (
LD_PRELOAD,NODE_OPTIONS, etc.) blocked with warnings. - M-8: Resolved paths verified within trusted root. World-writable dirs rejected.
- M-9: All temp files use
os.CreateTemp()with0o600permissions.
Actual behavior
- M-4: Directory
0o755, files0o644— world-readable. - M-7: Any env var accepted without sanitization.
- M-8: No realpath validation or permission checks on skill directories.
- M-9: 6 of 7 locations use predictable
path + ".tmp"naming and world-readable0644permissions.
Tasks
M-4. Memory File Permissions
- Change directory permissions from
0o755to0o700infilestore.go:20 - Change file permissions from
0o644to0o600infilestore.go:48,filestore.go:95,vectorstore.go:179 - Add test verifying file and directory permissions after write
M-7. Environment Sanitization
- Create blocklist:
LD_PRELOAD,LD_LIBRARY_PATH,DYLD_INSERT_LIBRARIES,NODE_OPTIONS,PYTHONPATH,PYTHONSTARTUP,RUBYOPT,PERL5LIB,JAVA_TOOL_OPTIONS - Reject skill env overrides setting blocked variables
- Log warnings on blocked variables
- Add tests for blocked and allowed env vars
M-8. Path Containment
- Call
filepath.EvalSymlinks()after path discovery and verify within trusted root - Reject world-writable skill directories
- Warn if dirs owned by different user (Unix)
- Add tests for path escape and permission checks
M-9. Temp File Security
- Replace
path + ".tmp"inscheduler_store.go:165withos.CreateTemp() - Replace
fname + ".tmp"inmemory_store.go:70withos.CreateTemp() - Change
0644to0o600inchannel.go:71,init.go:828,847,serve.go:203,skills.go:210 - Use
os.CreateTemp()forinit.go:562,866 - Add tests verifying temp file permissions
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workingsecuritySecurity vulnerability fixesSecurity vulnerability fixes