我通过jQuery获取了一些JSON格式的数据,然后我需要向用户显示它,但是它容易受到XSS攻击。我在这里有什么选择,我应该在将数据放入数据库之前去除字符吗?我正在使用的框架(Kohana)有一个漂亮的功能HTML::Chars();
,但由于我使用javascript显示数据,所以我不能在那里使用它。
一种选择似乎是遍历每个正在 json 编码的数组元素并对其应用HTML::Chars();
。这是唯一的选择吗,如果是这样,那么这样做的最佳方法是什么?
例:
- 用户输入一些数据:
title, body
- 数据存储到数据库中
- 然后其他用户进入站点,数据数组从数据库中获取并导出为 JSON 格式
- 我的jQuery脚本正在获取json并将新元素附加到我的页面正文。
法典:
$(document).ready(function(){
$.ajax({
url: '/timeline/latest/1',
dataType: 'json',
success: function(data){
$.each(data, function(key, val) {
switch (val.type){
case 'post': // I have only made post so far
addPost(val);
break;
}
});
}
});
})
function addPost(val){
$('.content .timeline').prepend(val.title + '<br />' + val.body); // xss vulnerable
}
从数据库获取数据
<?php
class Controller_Timeline extends Controller{
public function Action_Latest(){
$parentID = $this->request->param('id');
$modelTimeline = new Model_Timeline();
// Here I get latest entries, big array
$latest = $modelTimeline->Latest($parentID);
// Response it and encode with JSON
$this->response->body(json_encode($latest));
}
}
到目前为止,我的解决方案是这样的,在我回显出$latest我遍历数组并应用反 xss 功能之前,我不知道它有多理想:
array_walk($latest, function(&$latest){
foreach ($latest as &$key){
$key = HTML::chars($key);
}
});
我建议你像Drupal一样做。
Drupal不会过滤任何输入。它将文本存储在具有XSS漏洞的数据库中,如果要显示此HTML代码而不被过滤。
相反,它会根据输出进行筛选。您绝对应该在服务器端执行此操作。
你应该从Drupal使用filter_xss()
函数中激发自己的灵感。
确保它适用于您的每个条目。当然,如果可以的话,请在全球范围内执行此操作,如下所示:
// In the Model_Timeline class
public function Latest( $id ) {
// Get your array, and then
foreach ( $array as $entry ) {
// Filter each entry
// I use $util->filter_xss but use it how you implemented it
$entry = $util->filter_xss( $entry );
}
// And return the filtered array
return $array;
}
你应该在将mysql_real_escape_string存储在数据库中之前调用它,htmlspecialchars 是可选的。您的问题是您不想只向用户显示 html,因此 htmlspecialchars 将不起作用,因为它将 <a>
等内容编码为<a>
因此如果您打算在用户页面上使用 html,则不适合(您必须再次将其重新转换为可用的 html,因此它是多余的)。
在这种情况下,没有简单的答案 - 这取决于您正在处理哪种 html?如果它像<em>
<p>
<strong>
那样纯粹是表示性的,你应该严格解析 html 服务器端并检查它只有这些东西,并拒绝或删除任何危险的东西,如 <script>
.不过它更复杂,因为你也必须厌倦元素属性中的javascript,如onClick="do something bad"。
总之,在使用 PHP 发送 JSON 之前清理您的 html,这有最好的代表:http://htmlpurifier.org/