Skip to content

Prefer the most specific index authentication policy#193

Closed
zaniebot wants to merge 1 commit into
mainfrom
zb/bughunt200/154-authenticate-never-index-overlap
Closed

Prefer the most specific index authentication policy#193
zaniebot wants to merge 1 commit into
mainfrom
zb/bughunt200/154-authenticate-never-index-overlap

Conversation

@zaniebot

@zaniebot zaniebot commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Warning: truncated output (original token count: 6603)
Total output lines: 351

Index authentication policy uses unordered FxHashSet::iter().find(..) rather than the most-specific root, so a broad authenticated index can send credentials beneath a nested authenticate = "never" root. Select the longest matching root after normalizing trailing slashes, make equal-specificity conflicts fail safe by preferring never, and reject credentials already attached to a request before they can be sent. The policy was added specifically to prevent credential leakage in uv#11896, and this complements the path-boundary matching fix in uv#19154.

uv auth login under umask 000 creates a world-readable credentials directory and credentials/lock files, storing the token verbatim. Create private directories and locks and atomically replace the credential file with private permissions, without chmod-on-read or an exposure window. Coordinate the overlapping native-auth storage rewrite (uv#18907).

Auth login accepts localhost and 127.0.0.1 over HTTP but rejects the equivalent IPv6 loopback http://[::1]:.... Recognize ::1 as local without relaxing the localhost-only security policy introduced in uv#15755; this shares the native-auth surface being rewritten in uv#18907.

Redirect handling only moves URL credentials into Authorization when the username is nonempty, so a password-only redirect such as https://:token@host/... fails authentication and can expose the token. Apply and redact a present password with an empty username. Redirect-auth changes previously broke Azure/GCP flows and were reverted (uv#13041, uv#13215); preserve signed/cross-origin semantics and coordinate uv#20214 and uv#17343.

Pyx token-cache decoding calls String::from_utf8(..).expect(..), so a truncated or non-UTF8 cached token can abort authenticated operations. Return a typed decoding error instead of panicking.

When DisplaySafeUrl::parse rejects a malformed redirect Location, the error interpolates the raw value and can expose embedded credentials. Redact the unparsed authority before reporting it. Keep this strictly separate from redirect routing/authentication, whose Azure/GCP behavior has prior reverts (uv#13041, uv#13215, uv#20214).

Hugging Face token bytes are passed to HeaderValue::from_bytes(..).expect(..), so a malformed HF_TOKEN containing a line break can panic ordinary authentication. Validate bearer-token bytes at construction and return a typed error without rendering the credential.

HTTP-cache min-fresh subtracts Unix-epoch seconds from freshness lifetime, making ordinary entries immediately stale, while max-stale reads the stored/original request instead of the presented request. Apply the current request directives to the calculated age according to RFC 9111, alongside the recent cache-age and exact-expiration fixes in uv#20178 and uv#20183.

A project declaring configured-name==1.0 can emit an internally consistent different_name-9.0-py3-none-any.whl and report success because the direct-wheel build plan supplies no expected identity. Validate normalized static identity and stage the wheel until validation passes, preventing a rejected artifact from remaining publishable in dist/ while preserving existing output. Retain UV_SKIP_WHEEL_FILENAME_CHECK=1 and version.without_local() compatibility for malformed/nightly wheels (uv#16046); keep this distinct from filename/METADATA and sdist/wheel consistency.

Ordinary uv python install matches an existing managed installation only by its key and ignores an explicit UV_PYTHON_*_BUILD pin, so an outdated build is retained. Compare the requested build identity before reuse, completing the reproducible-build pinning requested in uv#14263 and the installed-build marker added in uv#15314. Managed install/download finalization is concurrently changing in uv#20286, uv#19840, and uv#20309.

A newline in uv venv --prompt can inject a second pyvenv.cfg key such as include-system-site-packages = true, silently changing environment isolation. Reject CR/LF before creating the environment so failure leaves no partia…3103 tokens truncated…aw names, so private-one and PRIVATE_ONE can both consume UV_INDEX_PRIVATE_ONE_* and send the same credentials to different indexes. Detect the credential collision and provide an explicit diagnostic/escape; the hyphen-to-underscore mapping is intentional (uv#18935), and globally rejecting colliding names when no credential variable exists is breaking.

Requirements-file --no-binary/--only-binary a,b is rejected even though pip and uv's CLI accept comma-separated package policies. Parse the package list consistently, including :all: and :none: resets, completing the pip-compatibility work introduced in uv#2680 for uv#1461. Coordinate the active requirements-option rewrite in uv#16489.

Repeated --no-binary/--only-binary directives across nested requirements can lose ordering: a child :none: reset may leave the parent's policy active. Replay policy events in source order so reset and last-wins semantics match pip, extending the compatibility work introduced in uv#2680 for uv#1461. Coordinate the active requirements-option rewrite in uv#16489.

Valid attached pip forms such as -rfile, -cfile, -fpath, -iURL, and -epath require an unnecessary separator in uv. Accept attached short-option values and resolve local -f paths against the parser working directory, preserving the existing -r/-c declaring-file and -e working-directory semantics established in uv#1421.

Include, index, and find-links values containing a literal # are truncated as comments when no whitespace precedes the hash. Preserve hashes within option values while retaining normal whitespace-delimited comments.

pip permits replacement --index-url directives, including across nested includes, while uv rejects repetition. Apply ordered last-wins handling consistently. This reverses uv's deliberate ambiguity error from uv#1146: an included requirements/constraints file can override an operator-controlled index, a previously identified security concern (uv#6407). Coordinate the active parser rewrite (uv#16489).

Unknown prefixes such as --prefixed-option can be interpreted as --pre, while --no-indexed can become an ed requirement. Require complete option-name matches before dispatch so unsupported flags cannot silently change resolution, preserving the warn-and-ignore behavior introduced in uv#10420. Coordinate the active requirements-option rewrite in uv#16489.

PEP 508 marker parsing incorrectly requires whitespace before an opening parenthesis and rejects valid and(/or( grouped expressions. Accept the grammar form without changing ordinary marker tokenization.

python_version in "3.12.1" on Python 3.12 evaluates incorrectly because version/range lowering discards PEP 508 substring-membership semantics. Preserve string membership; this intentionally revisits the algebra/performance tradeoff in uv#6172, which documented the divergence to keep marker operations tractable. Raw substring BDD nodes change universal-lock/fork representation and performance, so keep that compatibility tradeoff explicit.

Universal compile drops markers from editable requirements such as -e ./project ; sys_platform == "linux", making them unconditional on other platforms. Preserve editable environment markers through lowering and simplification. This touches the same editable-requirements lowering path as active uv#19151.

An exclusive prerelease bound such as >1a1 can incorrectly reject an installed 1.post1 even though the post-release is compatible. Correct the greater-than prerelease/post-release comparison while preserving local-version normalization, complementing the earlier exclusive-comparison fix in uv#12836 for uv#12834.

Legacy .egg-info uninstalls need to read entry_points.txt to remove console and GUI launchers, but loading and parsing currently live in the wheel reader. Add an EntryPoints reader that owns missing-file handling and parsing while preserving existing script and versioned pip-launcher behavior from uv#1593. This is a behavior-neutral prerequisite for completing the legacy-uninstall support introduced in uv#3380.

Moved to: astral-sh/uv-dev#174.

@zaniebot
zaniebot force-pushed the zb/bughunt200/154-authenticate-never-index-overlap branch from 4fd1032 to 630805d Compare July 15, 2026 18:16
@zaniebot zaniebot closed this Jul 16, 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.

2 participants