fix(no-ticket): stricter acceptance of api hosts and proxies#315
Merged
Conversation
Contributor
There was a problem hiding this comment.
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 untrustedapi_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.
5346f73 to
d1d1b8e
Compare
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>
d1d1b8e to
6a31cf5
Compare
BartoszBlizniak
approved these changes
Jun 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Directory-relative config files (
config.iniis searched in the current working directory first) can setapi_host/api_proxyto an arbitrary endpoint. Because credentials are attached to whatever host/proxy is configured, a malicious repository shipping a./config.inicould cause the nextcloudsmithcommand 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:
api_hostoriginates from a cwd config and was not supplied via--api-host/CLOUDSMITH_API_HOST, it must be under*.cloudsmith.ioor*.cloudsmith.com.api_proxyoriginating from such a source is rejected outright (there is no sensible domain allow-list for proxies).--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-suffixesoption /CLOUDSMITH_ALLOWED_API_HOST_SUFFIXESenv var — wired through Click only, never the config-file schema, so an untrusted config cannot whitelist its own domain.Type of Change
Additional Notes
Low blast radius: only a directory-relative
config.inisetting a non-cloudsmithapi_hostor anyapi_proxyis 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=falseandapi_headersfrom untrusted config are the same MITM class and could be guarded similarly.🤖 Generated with Claude Code