2

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

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

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

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

4

3 回答 3

3

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

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

这个小提琴中,有一个counter每秒更新的变量(不是每十秒 - 我很着急!:-))和另一个变量,basePoints 它们一起添加到当前分数。

公开的功能是允许您添加到 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
    };
}());​
于 2012-07-17T20:42:03.653 回答
2

您可以通过确保变量在函数上下文内部并且不是全局变量并且不能从全局范围访问来防止通过诸如小书签之类的东西对变量进行简单操作。这可以像这样简单地将其放入一个自执行函数上下文中:

(function() {
    var i;

    // code that uses i

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

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

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

于 2012-07-17T20:44:52.137 回答
1

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

于 2012-07-17T20:10:10.367 回答