T09 · Insecure Skill Coding Practices
- Location
scripts/rwlib/endpoint.py:478- Finding
Repository-Controlled Model Configuration Can Exfiltrate Document Passages and Rabbit-Scoped Credentials
- Content
View full analysis
Vulnerability Details
File Location:
scripts/rwlib/endpoint.py:478-515,scripts/rwlib/endpoint.py:280-287; invocation flow inscripts/scan.py:1448-1503
Vulnerability Type: Repository configuration trust-boundary violation
Risk Level: MediumVulnerable Code
python def resolve(target_path=None, overrides=None): """(Endpoint or None, note). Which model server applies, and who said so. Order: an explicit override from the command line, then the nearest `.rabbit-model` beside the document, then the nearest one above the working directory, then the environment, then nothing. """ overrides = overrides or {} if overrides.get("base_url"): config = dict(overrides) key = config.pop("_key", None) or os.environ.get(ENV_API_KEY) source = "--model-endpoint" bad = problems(config, source) if bad: return None, " ".join(bad) try: return _build(config, key, source), "endpoint from %s" % source except EndpointError as exc: return None, str(exc) start_dirs = [] if target_path: start_dirs.append(os.path.dirname(os.path.abspath(target_path))) start_dirs.append(os.getcwd()) path = next((p for p in (_find_config(d) for d in start_dirs) if p), None) if path: try: with open(path, encoding="utf-8") as fh: config = json.load(fh) except (OSError, ValueError) as exc: return None, "%s could not be read: %s" % (path, exc) bad = problems(config, path) if bad: return None, " ".join(bad) env_name = config.pop("api_key_env", None) key = os.environ.get(env_name) if env_name else None if env_name and not key: return None, ("%s names api_key_env %r but that variable is not " "set in this environme ...[truncated 4123 chars]- Remediation
View remediation
Remediation Suggestions
- Do not trust repository-local endpoint configuration by default. Refuse
.rabbit-modelfiles located inside a Git working tree unless the user supplies an explicit trust flag. - Require destination confirmation before transmission. For repository-controlled configurations, display the resolved scheme, hostname, port, model, configuration path, credential-variable name, and planned passage count, then require affirmative confirmation before the first request.
- Provide a noninteractive trust mechanism. Add an explicit option such as
--trust-model-config PATHor--allow-repository-model-configfor CI and scripted use. The option should be required for each untrusted configuration source. - Move endpoint trust to user-owned storage. Prefer a configuration file outside project repositories with restrictive permissions, and allow repository files to reference only a pre-approved endpoint alias rather than an arbitrary URL.
- Prevent repositories from selecting credentials. Resolve
api_key_envonly from user-owned configuration or require an explicit command-line selection. Repository configuration should never choose which environment variable becomes an authorization credential. - Implement an endpoint allowlist or trust database. Record user-approved origins and reject unexpected changes to the URL, scheme, hostname, or port.
- Make planning the safe first step. Require
--model-planbefore using an untrusted or newly observed endpoint, or combine planning and confirmation into the first-run workflow. - Preserve current transport controls. Continue rejecting non-loopback plaintext HTTP by default, scrubbing credentials from errors, limiting environment-variable names, and sending only the minimum passages needed.
- Do not trust repository-local endpoint configuration by default. Refuse
