2012-07-17 91 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或在調試器中斷開並操作那些內容,因爲沒有辦法阻止這些操作,但它確實會阻止最簡單的方法進入頁面並更改變量(如從小書籤中)。