# SSI virtual, revisited

**URL:** <https://www.ruby-forum.com/t/ssi-virtual-revisited/175468>\
**Category:** NGINX\
**Created:** [September 14, 2009, 12:05pm UTC](https://www.ruby-forum.com/t/ssi-virtual-revisited/175468 "2009-09-14T12:05:16Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Toni\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/f04885/32.png) [@Toni\_M](https://www.ruby-forum.com/u/Toni_M)\
**Post date:** [September 14, 2009, 12:05pm UTC](https://www.ruby-forum.com/t/ssi-virtual-revisited/175468/1 "2009-09-14T12:05:16Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Toni\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/f04885/32.png) [@Toni\_M](https://www.ruby-forum.com/u/Toni_M)\
**Post date:** [September 14, 2009, 1:18pm UTC](https://www.ruby-forum.com/t/ssi-virtual-revisited/175468/2 "2009-09-14T13:18:26Z")

</div>

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.
