The only way I can think of to solve this is to require all javascript
insertions to be JSON values. We could automatically convert data
types to JSON. This would require making some assumptions that have
potential for confusion. For example, if you inserted a Text, we would
convert that to a JSON string first to avoid any escaping issues. If
you want to insert javascript code, that would have to be a widget.
Personally I would like to see us move in this direction of very
secure by default. We could always provide an escape hatch.
For shakespeare-text there should continue to be no escaping because
we have no idea what it will be used for.
Here's what it all comes down to: what are people actually using
Julius interpolation for? I don't think it's that commonly used in the
first place, and I definitely don't think people are embedding
user-supplied values in it in general. But that's why I wanted to open
this to the general community: how are you using it?
In my own use cases, whenever I'm embedding user supplied data in JS,
it's going via JSON, and thus all character escaping is being applied
automatically. So for me, this is all a non-issue.
I also think there are better solutions here than just forcing
everything to be JSON, such as forcing the user to explicitly state
the kind of interpolation they want via a sum type. For example:
data JuliusInterpolation = RawText Text | JSON Data.Aeson.Value |
UnsafeText Text
Michael
This is what I just proposed. Doesn't seem too frightening :)
However, Yesod tries to be secure by default and I don't think that
the interpolation should be unsafe by default. Implementation-wise,
I'd prefer having a
newtype RawJulius = RawJulius Text
and have the default interpolation be of JSON. The drawback is that
the only solution that I see to make this work would be to write
something like
-- This is internal
data JuliusInterpolation = Raw Text | Safe Value
class ToJulius a where
toJulius :: a -> JuliusInterpolation
instance ToJulius RawJulius where
toJulius (RawJulius t) = Raw t
instance JSON a => ToJulius a where
toJulius = Safe . toJSON
which needs (at least) OverlappingInstances and UndecidableInstances.
Cheers,
--
Felipe.
I think I'd rather force users to explicitly add the toJSON
themselves, and then we could allow a bunch of ToJulius instances. For
examples, all numeric types should be safe candidates for a ToJulius.
Michael
This should help guide our approach. However, I think there is
advantage to re-using ToJSON and maintaining our approach of allowing
industry standards of either plain javascript or coffeescript.
The biggest issue with jmacro for a Yesod user is that it doesn't have
build in support for type-safe urls, but there shouldn't be any issue
with using it if you want to.