0

我通过 jQuery 获取一些 JSON 格式的数据,然后我需要将其显示给用户,但是它容易受到 XSS 攻击。我在这里有什么选择,我应该在将数据放入数据库之前去除字符吗?我正在使用的框架(Kohana)有一个漂亮的功能HTML::Chars();,但由于我用 javascript 显示数据,所以我不能在那里使用它。

一种选择似乎是遍历每个被 json 编码的数组元素并应用于HTML::Chars();它。它是唯一的选择吗,如果是这样,那么这样做的最佳方式是什么?

例子:

  1. 用户输入一些数据:title, body
  2. 数据存储到数据库中
  3. 然后其他一些用户进入站点,从数据库中获取数据数组并导出为 json 格式
  4. 我的 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);
    }
});
4

2 回答 2

1

我建议你像 Drupal 那样做。

Drupal 不过滤任何输入。如果要显示此 HTML 代码而不进行过滤,它会将文本存储在具有 XSS 漏洞的数据库中。

相反,它会过滤输出。你绝对应该在服务器端这样做。

您应该从filter_xss()Drupal 使用的功能中启发自己。

确保它适用于您的每个条目。如果可以的话,请在全球范围内进行,如下所示:

// 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;
}
于 2012-04-26T11:00:36.567 回答
0

您应该在将 mysql_real_escape_string 存储到数据库之前调用它,htmlspecialchars 是可选的。您的问题是您不想只向用户显示 html,因此 htmlspecialchars 将无法工作,因为它会编码类似<a>的内容,&lt;a&gt;因此如果您打算在用户页面上使用 html(您会必须再次将其转回可用的 html,这样就显得多余了)。

在这种情况下,没有简单的答案 - 这取决于您正在处理什么样的 html?如果它是纯粹的演示,<em> <p> <strong>你应该严格解析 html 服务器端并检查它是否只有这些东西,并拒绝或删除任何危险的东西,如<script>. 但它更复杂,因为您还必须对 onClick="do something bad" 等元素属性中的 javascript 感到厌烦。

总之,在使用 PHP 发送 JSON 之前清理你的 html,这是最好的代表:http ://htmlpurifier.org/

于 2012-04-26T11:10:39.513 回答