2012-07-17 90 views
1

我正在制作一个浏览器游戏,其中每10秒增加i,并且点算法使用i来确定获奖点数。对我来说,明显的方法是使用setInterval(10000)作为定时器,并在函数内部运行点计算。防止计时器上的JavaScript注入

如何防止JavaScript注入增加i,使得应用程序认为用户实际上已经打了超过他真的有?

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

还有,是否有一种方法可以防止JavaScript注入? (阻止,而不是服务器端检测)。

+0

你应该试图限制变量的范围,而不是阻止代码注入。 – TheZ 2012-07-17 20:04:53

+3

机会是你的JavaScript已经使它不可能为我注入一个新的值到一个函数,因为它不会在该函数之外可用,但我们永远不会知道,因为你没有包含任何代码... – 2012-07-17 20:06:27

回答

3

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

要创建一个变量private,只需将其包含在一个函数中,执行该函数并返回包含引用该变量的函数的内容。这被称为closure。这很容易做到。

this fiddle有一个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 
    }; 
}());​ 
1

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

2

则只需确保变量是内部的功能环境和不是一个全局变量,而不是从全球范围访问防止通过之类的bookmarklet变量的简单操作。这可能是因为把它变成一个自我执行功能方面像下面这样简单:

(function() { 
    var i; 

    // code that uses i 

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

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

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