2012-07-04 53 views
1
var x = Object.create(null); 
x["hello"] = "world"; 

但我可以允許未經驗證的用戶輸入作爲鍵嗎?我想用它作爲玩家的名字 - >玩家對象地圖。玩家的名字只能被32的長度限制。我擔心如果有特殊的屬性鍵可以讓玩家獲得對服務器的控制權。作爲標準的Object的安全性是否真的由標準保證?

編輯:我沒有製作網絡服務器。 JavaScript將通過嵌入遊戲服務器的SpiderMonkey運行在服務器端。如果有人劫持運行在那裏的JavaScript,他們可能會毀了遊戲。

回答

2

一句話:沒有,只記得Google Docs __proto__ fail

您應該使用Hash狀類,或者至少訪問這些鍵前綴:

var hash = {}, key = "something-evil", value = Math.PI; 
hash["$" + key] = value; 
console.log(hash["$" + key] == value); 
+0

'__proto__'來自Object.prototype,至少在我的Firefox上。如果我用'null'原型創建一個對象,它沒有'__proto__'。 – lamefun

+0

是的,但它也支持在webkit&opera中,如果使用Object.create(null)創建對象,則__proto__設置器仍然有效,因爲它不是來自Object.prototype,而是反映Chrome和Opera中的inner [[Prototype]]屬性。 你說得對,FF在這裏是個例外。 – pozs

0

不,一個物體基本上是一張空白的石板,沒有特殊的鍵。最重要的是,即使有人剽竊你的Javascript,但是他們很可能不會控制你的服務器,除非你使用的是非常寬鬆的安全策略(比如把root密碼放在你的Javascript或類似的東西中)。

+0

我想使用JavaScript服務器 - 通過將JavaScript引擎嵌入到遊戲服務器中。儘管我不會將系統功能暴露給它,但是有人會毀了遊戲仍然是不可取的。 – lamefun

+0

啊,在這種情況下,它取決於你在嵌入式引擎中的內容,以及你用於嵌入式引擎的軟件。 – robbrit

0

您無法控制將發送到您的Web服務器的內容。完全一樣。永遠。

因此,您需要限制您的服務器將執行的操作,以響應發送給它的任何內容。其中一部分是驗證所有用戶輸入,即使它是代表由您的代碼創建的JavaScript對象的JSON。

2

屬性鍵總是字符串。你永遠不會遇到問題與任何屬性名的,除了可能:

  • Object.prototype.hasOwnProperty。例如在:

    var obj = {hasOwnProperty:'fail'}; 
    for (var i in obj) { 
        if (obj.hasOwnProperty(i)) ; // ... 
    } 
    

    可以通過使用Object.keys(obj).forEach(...)或解決:

    for (var i in obj) { 
        if (Object.hasOwnProperty.call(obj, i)) ; // ... 
    } 
    
  • 唯一的危險是,你如何處理與對象引起的。前面的例子並不罕見,用法是hasOwnProperty,但可以用來破壞你的腳本,因爲你不要指望鍵名是hasOwnProperty。這同樣可以應用於.toString,或者可以通過設置新名稱而被覆蓋的對象的任何其他屬性。
+0

不會Object.create(null)創建一個甚至沒有hasOwnProperty的對象? – lamefun

+0

@lamefun是的,這是正確的。你的代碼是安全的,因爲你不希望*任何預定義的屬性/方法。那麼,「財產鑰匙總是字符串」應該足以睡得好;) –

+0

令人驚訝的是,我遇到了一個今天在一些舊代碼中造成的bug。基於用戶輸入將屬性添加到對象,並且可能會導致hasOwnProperty屬性被添加。你的建議正是我所做的,所以+1! –

相關問題