dev@glassfish.java.net

Re: REST API and slashes in resource names

From: Oleksiy Stashok <Oleksiy.Stashok_at_Sun.COM>
Date: Wed, 02 Jun 2010 19:54:11 +0200

> Shing Wai (and Amy) tell me that the web container suffers from the
> same vulnerability that the Tomcat changelog warns of. Ken and I
> have both confirmed this via testing (curl http://localhost:8080/foo%2Fbar.html
> returns the contents of foo/bar.html when it shouldn't).
>
> That being said, do we proceed with the double encoding, or press
> for a fix from the web container, which may not be very
> straightforward. The web container doesn't follow the same code
> path in handling requests, but here is how things work with the
> GrizzlyAdapters that the console and REST API use. In
> ContainerMapper.java, at line 193ff, we see:
>
> String uriEncoding = (String)
> grizzlyEmbeddedHttp.getProperty("uriEncoding");
> HttpRequestURIDecoder.decode(decodedURI, urlDecoder,
> uriEncoding, null);
> adapter = map(req, decodedURI, mappingData);
>
> Grizzly is asked, via HttpRequestURIDecoder, to decode the requested
> URL, which is where we're seeing our security check/failure, and
> THEN the adapter is requested.
>
> This may be the path of madness, but I disabled the call to
> HttpRequestURIDecoder, which lets the processing proceed. The
> request then does make it to
> GrizzlyAdapter.service(Request,Response), but fails again for
> similar reasons. This time, though, it should not. The call to
> HttpRequestURIDecoder is passed a UDecoder pulled from the request,
> which, in the case of RestAdapter, has allowEncodedSlash set to true
> in my local tree. It seems, though, there's a bug in Grizzly's
> UDecoder where the ivar allowEncodedSlash is hidden by a method
> parameter of the same name, whose value has been set to false. I've
> filed an issue with the Grizzly team (https://grizzly.dev.java.net/issues/show_bug.cgi?id=828
> ) and am waiting for feedback on that.
I've fixed that one. Please use the patch provided on the issuetracker.




>
> While I wait for their analysis, what are the downsides to disabling
> the call to HttpRequestURIDecoder.decode() in ContainerMapper? I'll
> kick off QL now and see if that turns up anything...
>
> On 6/2/10 4:16 AM, Paul Sandoz wrote:
>>
>> Hi Ken,
>>
>> For a RESTful system the client should not be constructing URIs
>> unless informed how to do so by representations from the server
>> (e.g. HTML forms) otherwise it unduly couples the client and
>> service. So the construction of such URIs, and the placement in
>> representations, is a server-side issue not a client-side issue.
>>
>> IIRC i think the RESTful admin service is in accordance with that.
>>
>> Paul.
>>
>> On Jun 2, 2010, at 12:03 AM, Ken Paulsen wrote:
>>
>>>
>>> In an attempt to summarize our options and the requirements (as I
>>> understand them):
>>>
>>> Requirements:
>>>
>>> Path element must be URL safe
>>> Path element must not be ambiguous
>>> Path element must not restrict the URL namespace further
>>> Solution must be generic so it may be applied to any other use-
>>> case with invalid URL characters
>>> Solution should be as natural & simple as possible to REST
>>> developers.
>>> Options for '/' within REST path element:
>>>
>>> .../management/domain/resource/admin-object-resource/jndi/foo/
>>> property
>>> Security Concerns: ??
>>> Client Coding issues: None.
>>> Readability: OK (JNDI name may be confused for part of the path)
>>> Ambiguous: Yes (JNDI slashes are not distinguishable from the path
>>> elements)
>>> Other Issues: Just the ambiguity.
>>> .../management/domain/resource/admin-object-resource/jndi%2Ffoo/
>>> property
>>> Security Concerns: ??
>>> Client Coding issues: Must call urlencode on JNDI name (simple &
>>> expected)
>>> Readability: Good
>>> Ambiguous: No
>>> Other Issues: Grizzly may not allow %2F???
>>> .../management/domain/resource/admin-object-resource/(jndi/foo)/
>>> property
>>> Security Concerns: ??
>>> Client Coding issues: Must know to put parenthesis "()" around
>>> JNDI name and to NOT urlencode it.
>>> Readability:
>>> OK. This is not a typical solution so it looks funny. '/' inside
>>> ()'s
>>> may be confusing (looks like 2 tokens: "(jndi" and "foo)".
>>> Ambiguous:
>>> No. However, you need to know the special rules to read it
>>> correctly
>>> (i.e. ()'s have higher precendence than '/'). This is not a
>>> standard
>>> and will be confusing.
>>> Other Issues: None.
>>> .../management/domain/resource/admin-object-resource/jndi%252Ffoo/
>>> property
>>> Security Concerns: Nothing known.
>>> Client Coding issues:
>>> Must call urlencode on JNDI name 2x. This may be confusing as to
>>> why it
>>> must be called 2x. However, it is simple to implement since it
>>> uses a
>>> standard encoding.
>>> Readability: OK. Will be confusing that it is encoded 2x instead
>>> of the standard of 1x.
>>> Ambiguous: No
>>> Other Issues: None.
>>> .../management/domain/resource/admin-object-resource/property?
>>> jndiName=jndi_at_2Ffoo
>>> Security Concerns: Nothing known.
>>> Client Coding issues: Must call urlencode on JNDI name (simple &
>>> expected); must add a Query String parameter.
>>> Readability: OK (see other issues)
>>> Ambiguous: Yes (see other issues)
>>> Other Issues:
>>> Query String parameters are not ordered in Java and cannot be
>>> related
>>> to a particular path element easily. This does not provide good a
>>> general solution to allowing '/' characters in path elements. It
>>> makes
>>> it difficult to read the path as a relative path identifying a
>>> single
>>> object. It also may be ambiguous if more than 1 path element
>>> needs to
>>> allow '/' in its name.
>>>
>>> I look forward to discussing this at the admin iteam...
>>>
>>> Ken
>>>
>>>
>>> On 06/01/2010 12:00 PM, Bruno Harbulot wrote:
>>>>
>>>>
>>>> On 01/06/10 17:23, Paul Sandoz wrote:
>>>>
>>>>>> On 01/06/10 11:47, Andreas Loew wrote:
>>>>>>> Hi Paul,
>>>>>>>
>>>>>>> Paul Sandoz schrieb:
>>>>>>>
>>>>>>>>> Not quite: '{' and '}' are just "unsafe" characters,
>>>>>>>>
>>>>>>>> They are disallowed in the URI syntax:
>>>>>>>>
>>>>>>>> http://greenbytes.de/tech/webdav/rfc2396.html#rfc.section.2.4.3
>>>>>>>
>>>>>>> while I don't want to argue with you about the subtleties of
>>>>>>> the fact
>>>>>>> that curly brackets are *not* part of *neither* "reserved" *nor*
>>>>>>> "unreserved" characters, it seems to me that the following
>>>>>>> would be
>>>>>>> fully sanctioned by the spec:
>>>>>>>
>>>>>>> .../management/domain/resources/admin-object-resource/(jndi/foo)
>>>>>>>
>>>>>>> because "normal" brackets are "unreserved" characters: "Data
>>>>>>> characters
>>>>>>> that are allowed in a URI but do not have a reserved purpose
>>>>>>> are called
>>>>>>> unreserved."
>>>>>>>
>>>>>>> So how about wrapping resource values that contain "reserved"
>>>>>>> characters
>>>>>>> by a pair of (unreserved) "normal" brackets '(' and ')'?
>>>>>>
>>>>>> I'm not sure whether you want to take more recent RFCs into
>>>>>> consideration, but in RFC 3986, which obsoletes RFC 2389,
>>>>>
>>>>> Good point. I was using the URI spec that is referenced by HTTP
>>>>> 1.1
>>>>> (maybe the work on tidying up the HTTP spec will update the
>>>>> reference?)
>>>>>
>>>>>
>>>>>> parentheses are reserved characters:
>>>>>>
>>>>>> http://tools.ietf.org/html/rfc3986#section-2.2
>>>>>>
>>>>>> Section 2.4 is probably relevant to this discussion too
>>>>>> (especially
>>>>>> its last sentence).
>>>>>>
>>>>>
>>>>> I am not sure what the last sentence actually means in terms of
>>>>> parsing
>>>>> a URI :-) but i strongly suspect for HTTP schemes and the path
>>>>> component
>>>>> that '(' and ')' are OK. Jersey does not encode such characters
>>>>> when URI
>>>>> building path components e.g.:
>>>>>
>>>>> URI u = UriBuilder.fromPath("/(xxx/yyy)/zzz").build();
>>>>>
>>>>> BTW IIRC Microsoft's Astoria uses '[' and ']' for delimitation
>>>>> and those
>>>>> are percent encoded.
>>>>>
>>>>> It would be so much easier if we could use %2F !
>>>>
>>>> I guess Jersey might not follow the newer RFC.
>>>> What I meant with the relevance of the last sentence of section
>>>> 2.4, is that it more or less implies that, once the path
>>>> components (separated with '/' have been split) and %2F decoded,
>>>> further tools in the dispatch chain shouldn't split them further.
>>>>
>>>> I wasn't aware of the security issue with %2F and proxy servers,
>>>> but it sounds more like a case of fixing the way the server
>>>> behind the proxy interprets them when it shouldn't.
>>>>
>>>>
>>>> Coming back to the original problem... To be honest, I don't use
>>>> Glassfish every day so I'm not sure whether I'm going to go off
>>>> topic here, but from a REST point of view, there's no such thing
>>>> as a RESTful URI (and I think no one had used that expression in
>>>> the thread so far, so no problem here ;-) ).
>>>>
>>>> This is a question that often comes back on the rest-discuss
>>>> list, but the important point in REST is how you can link and get
>>>> the resources.
>>>> Considering that the query part is an integral part of the URI
>>>> (although some implementations don't necessarily view it this
>>>> way), these two elements are more or less equivalent in terms of
>>>> "URI RESTfulness":
>>>> <a href="http://myblog.example/pages/1">First page</a>
>>>> <a href="http://myblog.example/?page=1">First page</a>
>>>>
>>>> People often think that RESTful systems must have "RESTful URIs"
>>>> that are query-free. That's not strictly true as far as the REST
>>>> constraint are concerned from a theoretical point of view.
>>>> It's mostly an aesthetic matter, which is frankly barely relevant
>>>> if you follow the hypermedia constraints of REST. Having a query
>>>> in the URI is often a bad sign when the parameters symbolise
>>>> actions (e.g. "?action=delete"), so that's probably why they're
>>>> often discouraged.
>>>>
>>>> Whilst <http://localhost:4848/management/domain/resources/admin-object-resource/jndi-foo?convertDash=true
>>>> > could be considered as symbolising an action (arguable, since
>>>> it clearly wasn't the intent),
>>>> it sounds like <http://localhost:4848/management/domain/resources/admin-object-resource/?resource=jndi%2Ffoo
>>>> > would be just fine.
>>>>
>>>> Where having a query part or not matters is in terms of
>>>> implementation, regarding how the query is dispatched to whatever
>>>> needs to process that query. That's of course where the problem
>>>> is here. I think the two main downsides of using a query are that
>>>> not all proxy cache the requests with queries and that it also
>>>> makes it harder to use another query on that resource or to build
>>>> a sub-hierarchy (I'm not sure if it would be the case here).
>>>>
>>>>
>>>> Best wishes,
>>>>
>>>> Bruno.
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: dev-unsubscribe_at_glassfish.dev.java.net
>>>> For additional commands, e-mail: dev-help_at_glassfish.dev.java.net
>>>>
>>
>
>
> --
> Jason Lee
> Senior Member of Technical Staff
> GlassFish Administration Console
>
> Oracle Corporation
> Phone x31197/+1 405-343-1964
> Blog http://blogs.steeplesoft.com