[英]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所指出的,諸如where
, mapReduce
和group
允許直接執行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.