2015-09-27 59 views
6

我正在尝试使用Eloquent查询的结果,并将其结果作为JSON响应输出。我的应用程序使用Slim和Twig来生成HTML响应,但是我不确定我是否应该使用Twig来生成JSON。使用Twig生成纯JSON响应是否合适?

我知道我可以使用PHP的原生echo json_encode(...)函数,但是如果我的数据库包含HTML实体,这会创建潜在的XSS漏洞。 Twig应该负责适当地转移我的输出。

我知道this question,但它似乎没有提供相关答案。我也知道json_encode过滤器,但是当我这样做:

/api/users-json.twig

{ 
    "rows" : {{rows | json_encode}} 
} 

/API /用户控制器:

// 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" : [{&quot;user_name&quot;:&quot;alex&quot;,&quot;message&quot;:&quot;grawr!&quot;},{&quot;user_name&quot;:&quot;h4xx0r&quot;,&quot;message&quot;:&quot;&lt;script&gt;alert(&#039;hello, I can execute JS on your website!&#039;);&lt;\/script&gt;&quot;}] 
} 

这是不可解释的客户端没有进一步处理。根据我的浏览器,内容类型正确设置为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":"&lt;script&gt;alert(&#039;hello, I can execute JS on your website!&#039;);&lt;\/script&gt;"}] 
} 

注意h4xx0r的“消息”现在逃了出来,但响应的整体结构被保留为有效的JSON。

我当然可以循环遍历每一行并手动将每个值,然后echo json_encode或将其传递给Twig。但这似乎应该是Twig的责任!

编辑:这似乎是PHP的filter_var_array,与json_encode相结合,是一个合理的替代使用的树枝:

$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":"&#60;script&#62;alert(&#39;hello, I can execute JS on your website!&#39;);&#60;\/script&#62;"}]} 

但我现在还不能确定这是否是改为“应该”用枝条来完成。

有没有办法用Slim和Twig来做到这一点?或者,我完全错误的轨道上,并应该是我的客户端(JS)代码的责任,以正确地转义内容之前渲染?

+0

我不认为阻止XSS军营是Twig的责任。为了防止它,你必须过滤你的输入,而不是输出。 –

+0

@gustavo这是不正确的。当然,你应该总是在可能的情况下**过滤**输入,但是**转义**是应该在输出中完成的。转义输入是[antipattern](http://security.stackexchange.com/a/42521/74909)。 – alexw

+0

呃,你在问修辞吗? – alexw

回答

0

Twig将渲染任何给定的变量作为html编码。但是,由于您希望json对结果进行编码,因此您需要自行迭代数据,因为Twig不会为您深入研究数组。