users@jersey.java.net

[Jersey] Re: feeding static content

From: Marek Potociar <marek.potociar_at_oracle.com>
Date: Tue, 15 Feb 2011 15:00:32 +0100

Hi,
I don't see any issues wrt. use of the getCanonicalFile() method, but I don't see any code that would check the requested file permissions against the user credentials. Is this something that you intentionally chose to ignore because it is out of the scope for your use case?

Marek



On 13.2.2011, at 22:15, Christopher Piggott wrote:

> I'd like to ask for a peer review of something for security reasons.
> I want to feed static resources from jersey, but I want to do it
> within jersey rather than adding a separate ServletAdapter. This will
> allow me to do some other things, including security-related, weird
> manipulation of headers, and, eventually, my own JSP-like filtering.
>
> One thing that concerned me was the idea that somebody could request
> "http://me/static/../../../../etc/passwd" (for example) to get a
> resource outside of my "root." To protect against this, I compare
> what is being requested against my static resource root and I make
> sure it's not outside of what I wish to offer. I build the path to
> the static resource, then use .getCanonical() to collapse any ..'s,
> then compare the paths.
>
> Does anybody see any holes in this?
>
>
> @Path("/static")
> public class StaticResource {
> public final static String STATIC_PATH = "static";
> @GET
> @Path("{what: .*}")
> public Response getStatic(@PathParam("what") String what) throws
> FileNotFoundException {
> File root = new File(Application.getMainJarDir(), STATIC_PATH);
> File requestedFile = new File(Hub.getMainJarDir(), STATIC_PATH
> + File.separator + what);
>
> try {
> requestedFile = requestedFile.getCanonicalFile();
> } catch (IOException e) {
> return Response.status(Status.FORBIDDEN).entity("Not
> allowed").build();
> }
>
> if (!requestedFile.getAbsolutePath().startsWith(root.getAbsolutePath()))
> {
> return Response.status(Status.FORBIDDEN).entity("Not
> allowed").build();
> }
>
> ResponseBuilder response;
>
> try {
> response = Response.ok().entity(new FileInputStream(requestedFile));
> } catch (FileNotFoundException e) {
> response = Response.status(Status.NOT_FOUND).entity("Not found");
> }
>
> return response.build();
> }
> }
>
> --Chris