#578 Uri Interpolation

brian Wed 6 May 2009

Support URI interpolation as sugar for the following:

`somepath/$foo/file.txt`  =>  "somepath/$foo/file.txt".toUri

The rules would be the same as Str, wrap with ${} for any arbitrary expression, or a single dotted chain for variable names $x or $x.y.z.

brian Wed 6 May 2009

Promoted to ticket #578 and assigned to brian

tactics Wed 6 May 2009

I brought this up in the Localization thread, but it belongs here instead.

Do we really want `dir/$foo` to expand directly to "dir/$foo".toUri? To me, it feels like there may be room for abuse with this, similar to SQL injection. I feel like the individual parts ought to be sanitized.

A simple example of what I'm talking about, consider that you expose some Uri-based filesystem through an API. The file system looks like this

+ (root)
|- scripts
|- public
|  |- images

I want to expose the public directory on the web. I do not want to expose images directly and I certainly don't want to expose scripts!

If I'm not careful, I might write this code as

Obj getResource(Str res)
{
  return `/public/$res`.get
}

A clever user might be call getResource("images/compromisingPhoto.jpg"). The interpolation allows the "/" to be interpreted as part of the Uri structure, and they get my private pictures!

A malicious user might figure out that they can call getResource("../scripts/DbConnect.fan") and now they have the username and password to my database! Eep! Again, this is because a free-form string is being interpreted as part of the Uri's structure.

Of course, careful programming can prevent this. The solution is to be careful about what you're doing. But by default, most programmers aren't careful.

So that's my thoughts on the matter. I think the strings should be escaped. This would prevent convenience of being able to navigate to directories through a string, but it does prevent accidental misuse.

I don't know the exact Uri syntax, but I believe different parts of the Uri need to be escaped differently. In particular, +, =, and & characters can't be used in the query, but are legitimate in the hostname. So, when interpolating a string, these characters sometimes -- but not always -- need to be replaced with their encoded equivalents.

brian Wed 6 May 2009

I don't know the exact Uri syntax, but I believe different parts of the Uri need to be escaped differently.

To re-phrase what you are proposing, is that an interpolated variable is guaranteed to be escaped such that is only one component of its associated URI part:

  • if in a path, it is a name only (doesn't use .. or /)
  • if it is inside a path it doesn't contain a = or &

I can see use cases where I actually want that behavior and where I don't want that behavior. Plus it seems a little hard to really understand what Uri interpolation will do in a given situation.

But can be swayed either way based on everyone wants to do.

qualidafial Wed 6 May 2009

Do we really want dir/$foo to expand directly to "dir/$foo".toUri? To me, it feels like there may be room for abuse with this, similar to SQL injection. I feel like the individual parts ought to be sanitized.

With or without Uri interpolation you would still have to sanitize your inputs in such a situation.

See also: http://xkcd.com/327/

andy Wed 6 May 2009

I think your original proposal is correct - simply sugar for "...".toUri. Its an easy rule to remember. Sanitizing third-party values is an orthagonal issue IMO.

qualidafial Wed 6 May 2009

I think this makes perfect sense. +1

brian Sun 17 May 2009

Ticket resolved in 1.0.43

Uri interpolation is now supported as sugar for string interpolation with a call to Str.toUri:

file := "file.txt"
`/dir/$file`  =>  ("/dir/" + file).toUri

Login or Signup to reply.