Skip to content

feat: LORE_HOSTED_MODE — disable FS operations on client-controlled paths#333

Merged
BYK merged 1 commit into
mainfrom
feat/hosted-mode-security
May 15, 2026
Merged

feat: LORE_HOSTED_MODE — disable FS operations on client-controlled paths#333
BYK merged 1 commit into
mainfrom
feat/hosted-mode-security

Conversation

@BYK
Copy link
Copy Markdown
Owner

@BYK BYK commented May 15, 2026

Summary

  • Adds LORE_HOSTED_MODE=1 env var that sets a process-wide flag disabling all filesystem operations using client-controlled paths (from X-Lore-Project header, system prompt inference, or /v1/compact body)
  • Prevents path traversal, arbitrary file read/write, git subprocess execution, and file watcher creation when the gateway runs remotely from untrusted clients
  • Adds 17 tests covering all guard points

Security Issues Addressed

When the gateway runs hosted/remotely, clients supply project paths via headers or request bodies. Without guards, these paths are used for:

Risk Operation File
HIGH execSync("git remote -v", { cwd: clientPath }) core/git.ts
HIGH readFileSync(join(clientPath, ".lore.json")) — controls gateway config core/config.ts
HIGH writeFileSync/readFileSync on .lore.md at client path core/agents-file.ts
HIGH writeFileSync/mkdirSync on AGENTS.md at client path core/agents-file.ts
HIGH Recursive readdirSync + readFileSync on lat.md/ at client path core/lat-reader.ts
MEDIUM fs.watch() on client-controlled file paths gateway/pipeline.ts

Guard Points

All guards check isHostedMode() at function entry, returning safe no-op values:

  1. git.tsgetGitRemote(): returns null immediately
  2. config.tsload(): skips .lore.json read, returns defaults
  3. agents-file.ts — all 6 public functions: exportToFile, shouldImport, importFromFile, loreFileExists, exportLoreFile, shouldImportLoreFile, importLoreFile return false/void
  4. lat-reader.tshasLatDir() returns false, refresh() returns 0
  5. pipeline.tsstartKnowledgeFileWatcher() returns empty cleanup fn
  6. pipeline.tsenableHostedMode() called in initIfNeeded() from GatewayConfig.hostedMode

Idle work FS ops (knowledge export, lat-reader refresh) are guarded transitively via the core no-ops.

Design

  • packages/core/src/hosted.ts: module-level getter/setter (same pattern as log.ts)
  • Flag is set once at process startup, cannot be unset (production safety)
  • _resetHostedModeForTest() exported for test isolation
  • GatewayConfig.hostedMode populated from LORE_HOSTED_MODE env var via isTruthy()
  • Help text and lore start debug output document the new env var

…aths

Add a process-wide hosted mode flag (LORE_HOSTED_MODE=1 env var) that
makes all filesystem operations using client-controlled paths safe no-ops.
This prevents path traversal, arbitrary file read/write, and subprocess
execution when the gateway runs remotely from untrusted clients.

Guard points:
- git.ts: getGitRemote() returns null (no execSync with client cwd)
- config.ts: load() skips .lore.json read, returns defaults
- agents-file.ts: all 6 public functions no-op (export/import/exists)
- lat-reader.ts: hasLatDir() and refresh() no-op
- pipeline.ts: startKnowledgeFileWatcher() returns empty cleanup fn
- pipeline.ts: enableHostedMode() called in initIfNeeded() from config

The flag is set once at startup and cannot be unset. Idle work FS ops
(knowledge export, lat-reader refresh) are guarded transitively via the
core no-ops.
@BYK BYK merged commit 4d7e606 into main May 15, 2026
7 checks passed
@BYK BYK deleted the feat/hosted-mode-security branch May 15, 2026 11:21
This was referenced May 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant