使用动态生成的JavaScript保护XSS

时间:2015-04-02 16:15:45

标签: javascript php jquery ajax xss

我必须传递jQuery插件一些数据。我可以传递一个URL,它将使用GET请求获取数据,或直接传递一个数组,这将消除一个服务器请求。有问题的数据是用户提供的,在数据​​库输入时不进行清理。

下面的脚本没有显示插件,但确实显示了我如何将数据传递给客户端,因此它可以直接传递给插件。如图所示,动态生成的JS方法对XSS是可疑的,但是,Ajax / JSON方法似乎并不存在。

对于这种情况,如何保护动态生成的JavaScript方法,并且Ajax / JSON方法是否存在风险?

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>XSS Testing</title>  
        <script src="getStuff.php?type=js" type="text/javascript"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.js" type="text/javascript"></script>
        <script type="text/javascript"> 
            $(function(){
                console.log(stuff);
                $.get( "getStuff.php", function( data ) {
                    console.log(data);
                },'json');
            });
        </script>
    </head>

    <body>
    </body> 
</html> 

getStuff.php

<?php
$getFromDB=array(
    'Mary',
    'x"];alert(\'xss2\');x=["x',
    'John'
);
if(isset($_GET['type']) && $_GET['type']=='js') {
    header('Content-Type: application/javascript;');
    $s='var stuff=[';
    foreach($getFromDB as $row) {
        $s.='"'.$row.'",';
    }
    $s=substr($s, 0, -1).'];';
    echo($s);
}
else {
    header('Content-Type: application/json;');
    echo(json_encode($getFromDB));
}
?>

2 个答案:

答案 0 :(得分:0)

如果您希望使用JSON,为什么不首先验证您正在使用的是什么?

$.get(...)
 .success(function(data) {
    try {
      JSON.parse(data)
    } catch (e) {
      console.error("this isn't actually JSON");
    }
 })

JSON不能包含函数,也不能包含函数调用,所以只要求浏览器查看是否可以进行解析就应该足以让它“在这里有些东西不是真正的JSON数据”。

当然,你的PHP也是如此。 如果您需要特定序列化,请勿构建字符串。在这种情况下,使用通常的PHP方式构造键/映射对象,然后使用内置的json_encode函数将其转换为合法的JSON序列化。

答案 1 :(得分:0)

这几乎就像你设计的你的例子易受黑客攻击一样。你在&#34; js&#34;中没有做任何事情。如果要确保数据是通过适当的转义输出的,那么你只能在&#34; json&#34;情况下。

如果您要包含纯文件的JavaScript文件,请执行以下操作:

<script src="getStuff.php?type=js"></script>

然后getStuff.php需要确保发回的内容正确转义为数据

<?php
$getFromDB=array(
    'Mary',
    'x"];alert(\'xss2\');x=["x',
    'John'
);
if(isset($_GET['type']) && $_GET['type']=='js') {
    header('Content-Type: application/javascript');
    echo('var data = ');
    echo(json_encode($getFromDB));
    echo(';');
}
else {
    header('Content-Type: application/json');
    echo(json_encode($getFromDB));
}
?>

热潮:没有警觉。


附注:你不应该在;字符串的末尾有Content-Type。我在上面删除了它们。