Skip to content

fix(no-ticket): stricter acceptance of api hosts and proxies#315

Merged
cloudsmith-iduffy merged 1 commit into
masterfrom
iduffy/stricter-api-host-acceptance
Jun 16, 2026
Merged

fix(no-ticket): stricter acceptance of api hosts and proxies#315
cloudsmith-iduffy merged 1 commit into
masterfrom
iduffy/stricter-api-host-acceptance

Conversation

@cloudsmith-iduffy

Copy link
Copy Markdown
Contributor

Description

Directory-relative config files (config.ini is searched in the current working directory first) can set api_host / api_proxy to an arbitrary endpoint. Because credentials are attached to whatever host/proxy is configured, a malicious repository shipping a ./config.ini could cause the next cloudsmith command run inside it to leak the user's API key or bearer token to an attacker-controlled endpoint.

This change enforces an allow-list only on untrusted (directory-relative) sources:

  • When the effective api_host originates from a cwd config and was not supplied via --api-host / CLOUDSMITH_API_HOST, it must be under *.cloudsmith.io or *.cloudsmith.com.
  • Any api_proxy originating from such a source is rejected outright (there is no sensible domain allow-list for proxies).
  • Trusted sources — CLI flags, environment variables, user/home config, and an explicit --config-file — are unaffected, preserving dedicated/on-prem deployments that use custom hosts.

Hostname matching parses the URL netloc (defending …cloudsmith.io.evil.com, …cloudsmith.io@evil.com, port/userinfo tricks). Additional trusted suffixes can be supplied via the hidden --allowed-api-host-suffixes option / CLOUDSMITH_ALLOWED_API_HOST_SUFFIXES env var — wired through Click only, never the config-file schema, so an untrusted config cannot whitelist its own domain.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Refactoring
  • Other (please describe)

Additional Notes

Low blast radius: only a directory-relative config.ini setting a non-cloudsmith api_host or any api_proxy is affected — exactly the credential-redirection cases reported. Values from env vars, flags, and user/home config are untouched.

Follow-ups noted but intentionally out of scope: api_ssl_verify=false and api_headers from untrusted config are the same MITM class and could be guarded similarly.

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings June 15, 2026 22:28
@cloudsmith-iduffy cloudsmith-iduffy requested a review from a team as a code owner June 15, 2026 22:28
Comment thread cloudsmith_cli/cli/tests/test_api_host_validation.py Fixed
Comment thread cloudsmith_cli/cli/tests/test_api_host_validation.py Fixed
Comment thread cloudsmith_cli/cli/tests/test_api_host_validation.py Fixed
Comment thread cloudsmith_cli/cli/tests/test_api_host_validation.py Fixed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Hardens the CLI against credential exfiltration via directory-local (./config.ini) configuration by restricting untrusted api_host values to Cloudsmith domains and disallowing untrusted api_proxy entirely, while keeping trusted sources (flags/env/home config/explicit --config-file) functional for dedicated/on-prem setups.

Changes:

  • Added hostname extraction + suffix allow-list validation for api_host, plus unconditional rejection for untrusted api_proxy.
  • Introduced a CLI-only (hidden) escape hatch for additional allowed host suffixes via --allowed-api-host-suffixes / CLOUDSMITH_ALLOWED_API_HOST_SUFFIXES.
  • Added config-reader support for extracting values specifically from directory-relative config, plus a focused test suite.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
cloudsmith_cli/cli/validators.py Adds hostname parsing and allow-list enforcement helpers for untrusted API endpoint settings.
cloudsmith_cli/cli/decorators.py Wires enforcement into session initialization and adds hidden option/env var to extend trusted suffixes.
cloudsmith_cli/cli/config.py Implements reading specific keys from directory-relative config and quote-stripping behavior.
cloudsmith_cli/cli/tests/test_api_host_validation.py Adds unit tests covering hostname parsing, allow-list behavior, and enforcement gating logic.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread cloudsmith_cli/cli/config.py Outdated
Comment thread cloudsmith_cli/cli/validators.py
Comment thread cloudsmith_cli/cli/validators.py
@cloudsmith-iduffy cloudsmith-iduffy force-pushed the iduffy/stricter-api-host-acceptance branch 2 times, most recently from 5346f73 to d1d1b8e Compare June 15, 2026 22:51
A directory-relative config.ini (searched in the cwd first) could set
api_host or api_proxy to an attacker-controlled endpoint; credentials
are attached to whatever host/proxy is configured, leaking the API key
or bearer token to that endpoint.

Enforce only on untrusted (directory-relative) sources: when the
effective api_host/api_proxy originates from a cwd config and was not
supplied via flag/env, the host must match an allow-listed suffix.
api_host allows *.cloudsmith.io / *.cloudsmith.com by default; api_proxy
has no public default and is rejected unless an allowed suffix is
supplied via the environment. Trusted sources (flags, env vars,
user/home config, explicit --config-file) are unaffected, preserving
dedicated-deployment use.

Additional trusted suffixes are supplied via the hidden
--allowed-api-host-suffixes / --allowed-api-proxy-suffixes options
(CLOUDSMITH_ALLOWED_API_HOST_SUFFIXES / CLOUDSMITH_ALLOWED_API_PROXY_SUFFIXES
env vars), never via the config-file schema, so an untrusted config
cannot whitelist its own domain.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cloudsmith-iduffy cloudsmith-iduffy force-pushed the iduffy/stricter-api-host-acceptance branch from d1d1b8e to 6a31cf5 Compare June 15, 2026 22:55
@cloudsmith-iduffy cloudsmith-iduffy merged commit 20598c4 into master Jun 16, 2026
40 checks passed
@cloudsmith-iduffy cloudsmith-iduffy deleted the iduffy/stricter-api-host-acceptance branch June 16, 2026 11:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants