防止定时器上的JavaScript注入

时间:2012-07-17 20:01:15

标签: javascript setinterval xss firebase

我正在制作一个浏览器游戏,其中每10秒i递增一次,点算法使用i来确定获得的点数。对我来说,显而易见的方法是使用setInterval(10000)作为计时器,并在函数内部运行点计算。

如何阻止JavaScript注入增加 i ,让应用程序认为用户实际上玩的时间比实际上长?

我使用Firebase作为后端。作为一名PHP程序员,我通常只是通过检查开始和放大来提交玩家点的服务器端验证。结束时间。我想我也可以在Firebase中这样做,所以我可能只回答了我自己的问题......

还有,有没有办法阻止JavaScript注入? (预防,而不是服务器端检测)。

3 个答案:

答案 0 :(得分:3)

你可以使变量基本上是私有的,这意味着用户不可能通过普通的JS注入来改变它们。但是,这不会阻止某人通过调试器拦截你的Javascript,拦截你在客户端和服务器之间的通信,或者做各种其他的摆弄。

要将变量设为私有,只需将其包含在函数内,执行该函数,然后返回包含引用该变量的函数的内容。这称为closure。这很容易做到。

this fiddle中有一个counter变量每秒更新一次(不是每十秒钟一次 - 我赶时间!:-))和另一个变量basePoints这一直加在一起。

Publicly exposed是一个允许你添加到basePoints值的函数,但是没有任何东西允许你添加到计数器。如果没有进入JS引擎,我认为你不能做到这一点(正如调试器所做的那样。)重点是Javascript中没有办法更新counter变量。

var app = this.app = (function() {
    var counter = 0;
    var basePoints = 0;
    var div = document.getElementById("score");
    var addPoints = function(nbr) {
        basePoints += nbr;
        display();            
    };

    document.getElementById("add20").onclick = function() {
        addPoints(20);            
    };

    var display = function() {
        var points = counter + basePoints;
        div.innerHTML = points + " points";
    };

    setInterval(function() {
        counter += 1; 
        display();
    }, 1000);

    return {
        addPoints: addPoints
    };
}());​

答案 1 :(得分:2)

通过确保变量是函数上下文的内部变量并且不是全局变量且无法从全局范围访问,您可以通过bookmarklet之类的东西来阻止对变量的简单操作。这可以像将它放入一个自执行的函数上下文一样简单:

(function() {
    var i;

    // code that uses i

    setTimeout(function() {
        more code that uses i
    }, 1000);
})();

在这种情况下,只有第一个功能块内的代码才能到达变量i

请注意,正如其他人所说,这并不能阻止更复杂的操作,这些操作实际上会在页面执行之前更改源javascript,或者在调试器中中断并操纵那里的内容,因为没有办法阻止它们,但它确实阻止进入页面和更改变量的最简单方法(例如从书签中)。

答案 2 :(得分:1)

通过计算客户端的值并随后推送到服务器端,几乎无法阻止任何类型的高分攻击。只有混淆和不同的技巧才能使黑客攻击或多或少变得复杂,但它们根本无法阻止它。这就是首选服务器端验证或事件更好的服务器端计算的原因。