SSI virtual, revisited

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

/site2
/two-include
/subdir
/page.html with

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.

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

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

Hello!

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

So I can access files like this:

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
isn’t supported at all. Relative uri’s in aren’t supported mostly due to lack of
implementation.

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