2015-08-28 60 views
3

我使用流星,我很擔心可能的安全漏洞。我只希望用戶能夠創建修改數據庫中的某些字段。在這個例子中,我希望他們能夠創建或更新的唯一內容是一個派對的namedescription字段。如何只允許某些文檔字段在Meteor中插入和更新?

Parties.allow({ 
    insert: function (userId, party) { 
    return userId && party.owner === userId; 
    }, 
    update: function (userId, party, fields, modifier) { 
    return userId && party.owner === userId; 
    }, 
}); 

這是我在角流星教程看到的代碼,但它看起來像有人可以添加使用Minimongo他們在控制檯通緝的瀏覽器的任何字段。有沒有一種方法可以輕鬆定義可以使用的字段,並拒絕所有不使用這些字段的插入和更新?我可以寫一個簡單的函數,這是否更新:

function ensureFieldsAreOk(acceptableFields,fieldsInQuestion){ 
    for(i = 0; i < fieldsInQuestion.length; ++i){ 
     if(acceptableFields.indexOf(fieldsInQuestion[i]) === -1){ 
      console.log("Hacking attempt detected"); 
      return false; 
     } 
    } 
    return true; 
} 

要INSERT命令我可以用用Object.keys(party)作爲可接受的字段列表同樣的功能做到這一點。

我無法想象我是第一個想到這件事的人;必須有一個處理這個問題的標準方法。

+0

或者,你可以考慮[使用方法]( https://stackoverflow.com/questions/27330321/meteor-method-vs-deny-allow-rules)。 –

回答

1

我沒有看到這樣做有什麼問題,我不知道任何更合適的方式。儘管使用下劃線可以減少測試的難度:

Parties.allow({ 
    insert: function (userId, party) { 
    return userId && party.owner === userId 
      && _.difference(_.keys(party), acceptableFields).length == 0; 
    }, 
    update: function (userId, party, fields, modifier) { 
    return userId && party.owner === userId 
      && _.difference(fields, acceptableFields).length == 0 
    } 
}); 
1

不用擔心,您的問題完全有效。我在Meteor應用程序中處理這個問題的方式是篩選正在插入或更新的文檔。由於傳遞給insertupdate權限函數的參數不同,我插入和更新的方法不同。

我建議直接使用下面的代碼或類似的,以適應您可能已經根據您的標準上面指定的任何其他需要的東西:

Parties.allow({ 
    insert: function(userId, doc) { 
     var allow = true; 

     if(!userId || doc.owner !== userId) { 
      allow = false; 
     } 

     Object.keys(doc).forEach(function(docKey) { 
      if(acceptableFields.indexOf(docKey) < 0) { 
       allow = false; 
      } 
     }); 

     return allow; 
    }, 
    update: function(userId, doc, fieldNames, modifier) { 
     var allow = true; 

     if(!userId || doc.owner !== userId) { 
      allow = false; 
     } 

     fieldNames.forEach(function(fieldName) { 
      if(acceptableFields.indexOf(fieldName) < 0) { 
       allow = false; 
      } 
     }); 

     return allow; 
    } 
}); 

,你可以在代碼示例中看到的,我已經包括檢查用戶是否已登錄,以及用戶是否是他們試圖插入或更新數據庫的文檔的所有者。此外,insert函數直接檢查文檔的關鍵字(顯然,如果必須檢查比頂級關鍵字更深的關鍵字,比如我的代碼示例,則可以進行更徹底的檢查),並且在列表中未包含任何關鍵字可接受的領域。對於update函數,由於doc參數是未更改的文檔,因此您需要檢查fieldNames參數。與insert函數一樣,如果您需要對比頂級密鑰更深入的密鑰執行檢查,則可以直接檢查modifier參數並挖掘插入嘗試中引用的每個密鑰。對於您可能需要的所有信息來確定最終解決方案的外觀,請查看Meteor文檔的this section

最後,我寫了我的答案,使用通用的Javascript,以防你想採取的路線。顯然,你可以使用像Underscore和其他庫來增強我的建議。