Petr Kadlec created CXF-7931:
--------------------------------

             Summary: WebTarget re-encodes query in URI
                 Key: CXF-7931
                 URL: https://issues.apache.org/jira/browse/CXF-7931
             Project: CXF
          Issue Type: Bug
          Components: JAX-RS
    Affects Versions: 3.1.8
         Environment: Tested on Windows in TomEE-plus 7.0.2, which contains, 
IIANM, CXF 3.1.8.
            Reporter: Petr Kadlec


Creating a WebTarget with a given URI instance (or anything else, see below) 
does not make the request use the given URI; before the real request is made, 
the query part of the URI (and possibly other parts) is re-encoded. For a 
specific example, colons in the query are replaced with their URI-encoded 
version, %3A (even though it is unnecessary, colons belong to the pchar class 
allowed in the query component, see 3.4 and 3.3 of RFC 3986; however, the point 
is not that the re-encoding is "too strict", the point is that the re-encoding 
takes place at all).

While it may look harmlessly at a first glance (%3A and : are just two variants 
how to encode the same text), it is in fact not harmless at all. Specifically, 
SAML2 requests using the HTTP-redirect binding are sensitive to the exact text 
of the request URI because of the request signatures. See the explicit remark 
in [SAMLBindings] 3.4.4.1:
{quote}Further, note that URL-encoding is not canonical; that is, there are 
multiple legal encodings for a given value. The relying party MUST therefore 
perform the verification step using the original URL-encoded values it received 
on the query string. It is not sufficient to re-encode the parameters after 
they have been processed by software because the resulting encoding may not 
match the signer's encoding.
{quote}
So if a SAML2 request is passed or proxied using CXF, it gets broken if it 
contains anything encoded in a different way than CXF's UriBuilderImpl choose 
to encode it.

Moreover, AFAICT, there is no way to override this behavior. Even implementing 
our own UriBuilder which strives to keep the URI intact, and passing it to the 
.target(UriBuilder) overload, it's contents is retrieved via getCurrentURI(), 
the resulting (still-correct) URI is then (in resetCurrentUri()) passed to a 
new explicitly-constructed UriBuilderImpl, parsing to be re-encoded later.

 

Reproducible example:

{{ClientBuilder.newBuilder()}}
{{    .build()}}
{{    .target(new URI("http://localhost:5544/x?q=1:2";))}}
{{    .request(MediaType.APPLICATION_JSON)}}
{{    .get();}}

Expected: a HTTP request is made to {{/x?q=1:2}}.

Actual: a HTTP request is made to {{/x%3Aq=1:2}}.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to