SSI virtual, revisited

Maxim Dounin mdounin at mdounin.ru
Mon Sep 14 15:04:36 MSD 2009


Hello!

On Mon, Sep 14, 2009 at 11:56:31AM +0200, Toni Mueller wrote:

> 
> Hi,
> 
> I'm still pondering about how to enable virtual paths with ".." in
> them. Although I can imagine why they have been disallowed, I am
> dissatisfied with this course of events. It breaks my usage scenario,
> which is to be able to have trees of web pages with some include files
> at the top level, and include them with relative paths from whereever,
> but don't require these trees to be mapped to a document root.
> 
> So I can access files like this:
> 
> /site1
>      /one-include
>      /subdir
>             /page.html with <!--#include virtual="../one-include"-->
> 
> /site2
>      /two-include
>      /subdir
>             /page.html with <!--#include virtual="../two-include"-->
> 
> and freely copy around the directories site1 and site2 (in this
> example) to whatever location I see fit, w/o having to change anything.
> 
> 
> 
> I assume that the intent in the change, introduced long ago, was to
> prevent people from ascending above the document root, no matter what,
> and and that users of SSI already incur a performance penalty to have
> the actual SSI work done.

Not really.  This is the reason why <!--#include file="..." --> 
isn't supported at all.  Relative uri's in <!--#include 
virtual="..." --> aren't supported mostly due to lack of 
implementation.

> My cursory reading of the 0.7.61 source code suggests that the current
> course of events is like this:
> 
> ... parse page
> ngx_http_parse_unsafe_uri(include-path) -> error out if this contains "../"
> ... do the actual work.
> 
> 
> I suggest the following change (and advice implementing it, or comments
> why this is a bad idea):
> 
> 
> At startup, transform document-root to a realpath:
> 
> rp = realpath(documentroot)
> rp_len = strlen(rp)
> 
> At request processing time, do this:
> 
> ... parse page
> 
> real_include_path = realpath(include-path);
> 
> if (rp is not a proper prefix of real_include_path) -> error out
> ...do the actual work

Sounds wrong for me.  Consider the following configuration:

   root /path/to/root;

   location /blah/ {
       root /;
   }

In this configuration anything in /blah/ filesystem path is 
accessible via nginx, but not anything under / (despite the fact 
that root *is* / for requests to /blah/something.html).  As long 
as you try to work with *files* - you are in trouble.

Instead, you have to stay in *uri* namespace, resolve relative paths 
there, and then translate it to file paths via normal request 
path.  After all, it's include *virtual*.

Maxim Dounin

> 
> 
> I can not assess the performance effect of this change now, but it
> would imho solve the traversal problem, and allow safe upwards
> references like I use, too.
> 
> The prefix check would then become something like
> 
> strncmp(rp, real_include_path, rp_len)
> 
> 
> Comments are much appreciated!
> 
> 
> 
> Kind regards,
> --Toni++
> 





More information about the nginx mailing list