我正在尝试获取Eloquent查询的结果,并将其结果输出为JSON响应。我的应用程序使用Slim和Twig生成HTML响应,但我不确定是否应该使用Twig来生成JSON。
我知道我可以使用PHP的本机echo json_encode(...)
函数,但如果我的数据库包含HTML实体,则会产生潜在的XSS漏洞。 Twig应该负责适当地逃避我的输出。
我知道this question,但它似乎没有提供相关的答案。我也知道json_encode
过滤器,但是当我这样做时:
/api/users-json.twig
{
"rows" : {{rows | json_encode}}
}
/ api / users 控制器:
// Simulate database query results
$result = [
"rows" => [
[
"user_name" => "alex",
"message" => "grawr!"
],
[
"user_name" => "h4xx0r",
"message" => "<script>alert('hello, I can execute JS on your website!');</script>"
]
]
];
$app->response->headers->set('Content-Type', 'application/json; charset=utf-8');
$app->render("api/users-json.twig", $result);
回复如下:
{
"rows" : [{"user_name":"alex","message":"grawr!"},{"user_name":"h4xx0r","message":"<script>alert('hello, I can execute JS on your website!');<\/script>"}]
}
如果没有进一步处理,这是不可解释的客户端。根据我的浏览器,内容类型已正确设置为application/json
。
我当然可以这样做: /api/users-json.twig
{
"rows" : {{rows | json_encode | raw}}
}
这给了我回复:
{
"rows" : [{"user_name":"alex","message":"grawr!"},{"user_name":"h4xx0r","message":"<script>alert('hello, I can execute JS on your website!');<\/script>"}]
}
但如果我要在客户端代码中呈现h4xx0r的消息,我就会接受XSS攻击。
我认为“正确”的输出将是:
{
"rows" : [{"user_name":"alex","message":"grawr!"},{"user_name":"h4xx0r","message":"<script>alert('hello, I can execute JS on your website!');<\/script>"}]
}
请注意,h4xx0r的“消息”现在已转义,但整个响应的结构将保留为有效的JSON。
当然,我可以遍历每一行并手动htmlspecialchars
每个值,然后echo json_encode
或将其传递给Twig。但这似乎应该是Twig的责任!
编辑:似乎PHP的filter_var_array
与json_encode
结合使用是使用Twig的合理替代方法:
$app->response->headers->set('Content-Type', 'application/json; charset=utf-8');
echo json_encode(filter_var_array($result, FILTER_SANITIZE_SPECIAL_CHARS));
产地:
{"rows":[{"user_name":"alex","message":"grawr!"},{"user_name":"h4xx0r","message":"<script>alert('hello, I can execute JS on your website!');<\/script>"}]}
但是我仍然不确定这是否应该用Twig来完成。
有没有办法用Slim和Twig做到这一点?或者,我是完全错误的轨道,并且我的客户端(JS)代码是否有责任在呈现之前正确地转义内容?
答案 0 :(得分:0)
Twig会将任何给定变量渲染为html编码。但是,由于你想对结果进行json编码,你需要自己迭代数据,因为Twig没有为你钻研数组。