Closed ondrejmirtes closed 3 years ago
Latte uses method Filters::escapeJs
.
IMHO your code is just wrong, right solution is this (or something similar):
<script><?php echo \Latte\Runtime\Filters::escapeJs($data); ?></script>
My point is that Json::encode
because of this is not a drop-in replacement for json_encode
so people who just switch to it are vulnerable to bugs like this.
I'm in an environment where I don't use Latte (I'm taking statically generated HTML and injecting a single JSON object in there before sending as an HTTP response) so that's why it might seem weird.
My point is you can't depend on internal behavior of Json::encode
- it converts input to valid JSON
not to HTML-SCRIPT-JSON
so you must use right function for right output. And yes, Json::encode
isn't 1:1 replacement for json_encode
but it's not goal IMHO.
For 1:1 replacement of json_encode
you can use Nette\Safe::json_encode
.
<script><?php echo \Nette\Utils\Json::encode($data); ?></script>
is definitely not safe. It was never my goal, because I have a Latte for HTML. But I think json_encode() is not safe either because it doesn't escape sequences like <!
or ]]>
.
Should Json::encode() escape HTML? I am not sure… What about <div data-info="<?php echo \Nette\Utils\Json::encode($data); ?>"></div>
Thank you for the suggestions. I'm not an escaping expert so feel free to close this issue :)
Oh, there's a bug in Latte\Runtime\Filters::escapeJs
.
This didn't work for me:
str_replace([']]>', '<!'], [']]\x3E', '\x3C!'], $json);
There need to be double quotes:
str_replace([']]>', '<!'], ["]]\x3E", "\x3C!"], $json)
When I'm outputting JSON with user input in an HTML
<script>
tag:it breaks the page if the
$data
include</script>
. When I use the built-in function:it works fine as it escapes forward slashes.
I have two questions:
1) Why is
JSON_UNESCAPED_SLASHES
the default? I can't even get rid of it using$flags
. 2) Does Latte deal with this with context-sensitive escaping? How?Thank you.