kubeclient icon indicating copy to clipboard operation
kubeclient copied to clipboard

Can't use proxy user:password with percent encoded characters

Open jhernand opened this issue 6 years ago • 4 comments

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.

jhernand avatar Apr 24 '18 07:04 jhernand

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)

cben avatar Apr 24 '18 10:04 cben

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.

moolitayer avatar Apr 24 '18 11:04 moolitayer

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...

cben avatar Apr 24 '18 11:04 cben

See: https://github.com/rest-client/rest-client/pull/665

jrafanie avatar Jun 05 '18 15:06 jrafanie