[ZPT] Path interpolation

jeffrey jeffrey@cuemedia.com
Fri, 02 Aug 2002 13:49:05 GMT


Evan Simpson writes:

> I just noticed that 
> http://dev.zope.org/Wikis/DevSite/Projects/ZPT/VariablesInPaths appears 
> to have the approval of both Guido and Jim, so I'm hoping to clean up 
> one detail and then implement it.
> 
> The detail is this: if "path:$x" uses simple string interpolation (which 
> the syntax strongly implies), then given x="a/b", this expression is 
> equivalent to "path:a/b".  This isn't a problem if you defined 'x', but 
> it's a potential security hole if 'x' came from an untrusted source.
> 
> For example, if you put the following into a template:
> 
>    <img tal:attributes="src here/images/foo_${request/foonum}" />
> 
> ...then a hostile request with query string "foonum=003/path/to/bar" 
> could cause traversal to an arbitrary object.

For this particular case, how does this differ from using:

  tal:attributes="src string:./images/foo_${request/foonum}" ?

For images, that path is going to have to be traversed anyways when the
browser goes to render the image.  Likewise, doing path interpolation in a
Python expression could yield the same results:

   tal:attributes="src python:path('here/images/foo_%s' % request.foonum)"

Or even:

   tal:attributes="src python:path('here/images/foo_%s' %
path('request/foonum'))"

Or is there something in the "VariablesInPaths' way of handling this that
is different from these other means?  I think the problem you specify above
already exists in other forms.

> This is why the current (undocumented) syntax "path:var1/?var2" is 
> designed so that "?var2" is always a single path step when 'var2' 
> contains a string.  It *does* traverse multiple steps if 'var2' contains 
> a sequence, which combined with Zope's ':list' marshalling causes the 
> same problem :-(

It's not exactly Undocumented.  Shane's made comments in both the Zope Book
area and the old Wiki containing the specs.  :)

> Normally I would expect the default case to the safe one, while allowing 
> you to explicitly accept risk (as with HTML-escaping and the 'structure' 
> keyword).  In this case, though, I suspect that the vast majority of 
> usage will not involve untrusted data, and the expected semantics of '$' 
> are strong enough to choose the other course.
> 
> I recommend that '$'-expansion be treated as simple string 
> interpolation, and that an alternate syntax should be provided which 
> renders slashes in the value inert.  This could be '?', suitably 
> altered, so that "here/images/foo_?{request/foonum}" would cause the 
> example above to look for (and probably fail to find) an object in 
> 'here/images' with the id "foo_003/path/to/bar".
> 
> I would also strip '?' of its sequence-expanding capability, and hand it 
> to '$'.  This would make "path:a${x}3" equivalent to "path:abc/123" when 
> 'x' contains ['bc', '12'].
> 
> Cheers,
> 
> Evan @ 4-am