kubeclient
kubeclient copied to clipboard
Can't use proxy user:password with percent encoded characters
RFC 3986 defines a set of reserved characters that can't appear directly in URL components like the userinfo. It also defines the percent encoding mechanism to escape them when needed. That means that an URI containing characters like $
or ?
in the userinfo need to be encoded. For example, if the user is myuser
and the password is $?xxxx
then the proxy URI should be like this:
http://myuser:%24%[email protected]:3128
The Ruby URI.parse
methods accepts this syntax, but it doesn't do the corresponding decoding. The program that uses this URI needs to do the decoding explicitly before using it:
require 'cgi'
require 'uri'
uri = URI.parse('http://myuser:%24%[email protected]:3128')
password = CGI.unescape(uri.password)
...
But apparently, for proxy URIs, rest-client
uses directly the value returned by the password
method. See rest-client/rest-client#661 for details.
In addition this gem also does the same itself:
https://github.com/abonas/kubeclient/blob/359e8c167c3f4356504c133160ed52aa4b4b8131/lib/kubeclient/watch_stream.rb#L59-L60
As a result when the password contain percent encoded characters this gem uses a wrong proxy password, and the proxy authentication fails.
I believe the same also applies to percent-encoded username. RFC doesn't talk of password specifically; AFAICT it says percent encoding applies to any component, and syntax for whole whole userinfo field clearly shows percent encoding is applicable:
userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
username encoding does happen in the wild for example when using email as username https://stackoverflow.com/questions/10050877/url-username-with.
(edited issue title, feel free to edit back if you disagree)
I think if we agree on this fix, we will have to do it in kubeclient anyway, because getting it into rest-client stable version will take time. I think we should, @cben WDYT?
Can such a fix introduce a problem? i.e someone has a proxy with this password "%". he previously could construct a client with proxy: http://user:%@...
. The user could still make it work by using escaped %: http://user:%25@...
but he would have to change code. Is this scenario real? should we take it into consideration? I think not but still sharing.
rest-client seems to escape the url user and password but not the proxy user and password.
I don't think backward compatibility is a blocker. That's the beauty of RFCs :-) If we're confident we understood the RFC right (I'm satisfied), then http://user:%ab@...
is simply wrong URL for the password %ab
. It's just a bug, we fix it and document the change.
Do you see any sane way for kubeclient to fix non-watch methods before rest-client itself is fixed?
Looks like we can easily fix watch methods (based on http gem), but I'm not sure we should until we fix the rest — different methods using different proxy settings for same URL would be very confusing...
See: https://github.com/rest-client/rest-client/pull/665