簡體   English   中英

JavaScript NoSQL 注射預防 MongoDB

[英]JavaScript NoSQL Injection prevention in MongoDB

如何防止 JavaScript NoSQL 注入 MongoDB?

我正在處理一個 Node.js 應用程序,我正在將req.body傳遞到 mongoose 模型的保存 function 中,這是一個 json object。我認為幕后有保護措施,但事實並非如此。

Sushant的答案不正確。 需要了解MongoDB中的NoSQL注入。

示例 (從此處獲取

User.findOne({
    "name" : req.params.name, 
    "password" : req.params.password
}, callback); 

如果req.params.password{ $ne: 1 } ,則將在不知道密碼的情況下檢索用戶( $ne表示不等於1 )。

MongoDB驅動程序

您可以使用mongo-sanitize

它將去除輸入中以“ $”開頭的所有鍵,因此您可以將其傳遞給MongoDB,而不必擔心惡意用戶覆蓋。

var sanitize = require('mongo-sanitize');

var name = sanitize(req.params.name);
var password = sanitize(req.params.password);

User.findOne({
    "name" : name, 
    "password" : password
}, callback); 

貓鼬司機

在遵循模式時,如果密碼是字符串字段,它將把對象{ $ne: 1 }為字符串,並且不會造成任何損壞。 在這種情況下,您無需清理,只需記住設置適當的架構即可。

盡管該帖子已過時,但我正在回答。

我知道三種方式。

首先:有一個多功能的內容過濾器 還通過過濾方式提供MongoDB注入保護。

第二個: mongo-sanitize ,幫助程序針對查詢選擇器注入清理mongodb查詢。

第三:在這里看到可以用於MongoDB的此解決方案。 實現起來真的很簡單。 僅使用JavaScript的內置escape()函數。

escape()將字符串轉換為ascii代碼。 $ne轉換為%24ne

var privateKey = escape(req.params.privateKey);

App.findOne({ key: privateKey }, function (err, app) {
  //do something here
}

注意我的答案不正確。 請參考其他答案。

-

客戶端程序在MongoDB中組裝查詢時,將構建BSON對象而不是字符串。 因此,傳統的SQL注入攻擊不是問題。

有關詳細信息,請遵循文檔

更新

避免像eval這樣的表達式可以執行任意JS。 如果要從用戶那里獲取輸入並運行類似eval表達式而不清除輸入,則可能會搞砸。 如JoBu1324所指出的,諸如wheremapReducegroup允許直接執行JS表達式。

為了防止來自結構未知的數據對象的查詢選擇器注入

使用mongo-sanitize通過遞歸進行深度消毒:

const deepSanitize = (value) => {
    if(Array.isArray(value)){
        value.forEach(elm=>deepSanitize(elm))
    }
    if(typeof(value) === 'object' && value !== null){
        Object.values(value).forEach((elm)=>{
            deepSanitize(elm)
        })
    }
    return sanitize(value)
}

例如,使用sanitize(req.query)嵌套查詢選擇器不會被刪除:

const req = {} 
req.query = { _id : { $ne: 1 } } 

console.log(req.query))               // { _id: { '$ne': 1 } }
console.log(sanitize(req.query))      // { _id: { '$ne': 1 } }

使用deepSanitize(req.query)清理對象(包括嵌套對象)是deepSanitize(req.query)

console.log(deepSanitize(req.query))       // { _id: {} }
console.log(req.query)                     // { _id: {} }

{...req.query}消除對象變異:

console.log(deepSanitize({...req.query}))  // { _id: {} }
console.log(req.query)                     // { _id: { '$ne': 1 } }

如果您在 Mongoose 中使用Mongoose Mongoose 6他們引入了sanitizeFilter選項,可以按如下方式使用(來自他們的文檔):

const obj = { username: 'val', pwd: { $ne: null } };
sanitizeFilter(obj);
obj; // { username: 'val', pwd: { $eq: { $ne: null } } });

通過將任何具有名稱以 $ 開頭的屬性的嵌套對象包裝在 $eq 中,來凈化查詢過濾器以防止查詢選擇器注入攻擊。

您還可以將其設置為默認敏感:

mongoose.set('sanitizeFilter', true);

您還可以使用trusted()跳過默認的敏感化:

const user = await User.findOne({
  // Tell Mongoose to not sanitize `{ $ne: true }`
  deleted: mongoose.trusted({ $ne: true }),
  email: req.body.email,
  hashedPassword: req.body.hashedPassword
}).setOptions({ sanitizeFilter: true }); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM