Skip to content

config: gate repo-local extractor plugins behind opt-in - #1201

Merged
zzet merged 1 commit into
mainfrom
fix/extractor-plugins-local-opt-in
Oct 31, 2026
Merged

zzet merged 1 commit into
mainfrom
fix/extractor-plugins-local-opt-in

Conversation

@zzet

@zzet zzet commented Oct 31, 2026 •

Copy link
Copy Markdown
Owner

Problem

index.extractor_plugins in a repo-local .gortex.yaml registers external subprocess passes that run an arbitrary, operator-configured command over each matching file's content (executor_plugin.go execs e.command with repo content on stdin and GORTEX_FILE_PATH in the env).
The config is read from <repoRoot>/.gortex.yaml (config.go:863, manager.go:231-242), which is committed to the repo, so a cloned repo can force the victim's indexer to execute attacker-chosen code — with no allowlist or sandbox. The field is copied wholesale from workspace config into the effective config (manager.go:399), so there is no distinction between trusted and repo-supplied plugins.

Fix

Extractor plugins declared in repo-local config are dropped unless the operator opts in with GORTEX_ALLOW_LOCAL_EXTRACTOR_PLUGINS=1, mirroring the existing GORTEX_ALLOW_LOCAL_PROVIDERS gate for repo-local providers.json. Compiled defaults are untouched (the gate fires only when a workspace config is present). Global/operator-trusted config is unaffected.

Test

TestGetRepoConfig_RepoLocalExtractorPluginsGated verifies the plugin is dropped without the flag and restored with it.

index.extractor_plugins in a repo-local .gortex.yaml runs arbitrary,
operator-configured commands over repo file content on the indexer's
behalf (executor_plugin.go). A cloned repo carrying a malicious entry
would execute attacker-chosen code when the victim tracks it. Require
explicit opt-in via GORTEX_ALLOW_LOCAL_EXTRACTOR_PLUGINS, mirroring the
GORTEX_ALLOW_LOCAL_PROVIDERS gate for repo-local providers.json.
@zzet
zzet merged commit b142486 into main Oct 31, 2026
25 checks passed
zzet added a commit that referenced this pull request Oct 31, 2026
Config.LLM.Custom (inline llm.custom in a repo-local .gortex.yaml) sets an
OpenAI-compatible base_url for the active provider. Unlike repo-local
providers.json, which is gated by GORTEX_ALLOW_LOCAL_PROVIDERS, the inline
llm.custom block is loaded unconditionally, so a cloned repo carrying a
malicious base_url makes the daemon send prompts and any configured API key
to that host with no host allowlist.

Drop llm.custom from repo-local config unless the operator opts in via
GORTEX_ALLOW_LOCAL_PROVIDERS, reusing that gate for repo-local
providers.json. Compiled defaults and global config are untouched.

The original branch forked from a pre-C1 main and its diff overlapped
#1201's extractor-plugins gate in repoConfig; this is the same fix
re-targeted onto current main so it merges cleanly.
@zzet
zzet deleted the fix/extractor-plugins-local-opt-in branch October 31, 2026 12:04
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