Repository navigation
Conversation
With the userauth and passwordauth options set, the stream transport called setUser() and setPass() on the Uri object it was given, so the caller's object carried the password afterwards and leaked it into logs, later requests and exception messages. An immutable URI got no credentials at all. Send the credentials as an Authorization header instead, unless the request already has one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Summary of Changes
With the
userauth/passwordauthoptions set, the stream transport called$uri->setUser()and$uri->setPass()on theUriobject it was given. After a request the caller's object stringified ashttp://user:secret@host/path, so the password ended up in whatever logged or reused that object, and in exception messages such asCould not connect to resource %s. AUriImmutablegot no credentials at all, because the code only handled the mutableUri.The credentials are now sent as an
Authorization: Basic …header, as the cURL and socket transports effectively do, and the URI object is left alone. If the request already carries anAuthorizationheader it wins, as it did before (PHP's http wrapper does not add the URL's credentials when such a header is present).The finding also suggested cloning the URI before modifying it. That would have kept the credentials in the URL used for the request and in exception messages, so the header was preferred.
Testing Instructions
Tests/Transport/StreamCredentialsTest.php(new, needs the stub):Uristill stringifies without them (before:http://username:secret@…);UriImmutablegets the credentials too (before: none).Documentation Changes Required
docs/classes/TransportInterface.md: theuserauth/passwordauthrow lists all transports and says how the stream transport sends them. #82 changes the next row of the same table, so whichever is merged second needs a trivial rebase.🤖 Generated with Claude Code