Nodejs中Mongodb被恶意插入一条数据,但_id却为null
Nodejs中Mongodb被恶意插入一条数据,但_id却为null
我用的是mongoose,代码是这样写的:
MODEL("Articl").articles.update({
_id : id
}, {
$push : {
comment : data
}
}, {
upsert : true
}, function (err, result) {})
我知道upsert:true存在问题,但我想知道为什么被恶意插入的document的 _id为null,
求可能存在的情况,谢谢大家!
data里包含了 **_id * 这个key吧
[@DoubleSpout](/user/DoubleSpout) 插入的document中,data包含了一个**_id**,就是外面的没有,下面为插入后的数据:
{
_id : null,
comment : [{
_id : "54b9b077526961a141e4611f",
content : ""
}
],
createtime : "2015-01-17T01:59:49.533Z"
}
想知道前面:
MODEL("Articl").articles
是怎麼發生的?
[@chinghanho](/user/chinghanho) 定义的一个schema:
var schma = mongoose.Schema({
title: {
type: String,
trim: true,
length: 40
},
createtime: {
type: Date,
default: Date.now,
unique: true
},
comment: [
{
username:String
content:String
}
]
});
exports.articles = mongoose.model(“articles”, schma);
我嘗試照個做了一次,沒有發生這個問題,你看看:
var mongoose = require('mongoose')
mongoose.connect(‘mongodb://localhost:27017/test’)
var ArticleSchema = new mongoose.Schema({
comments: [{
username: { type: String },
content: { type: String }
}]
})
mongoose.model(‘Article’, ArticleSchema)
var Article = mongoose.model(‘Article’)
var comment = {
username: ‘chh’,
content: ‘hello world’
}
Article.create({
comments: [ comment ]
},
function (err, article) {
if (err) return console.log(err)
Article.update(
{ _id: article._id },
{ $push: { comments: { username: ‘david’, content: ‘foobar’ } } },
{ upsert : true },
function () {
Article.find({ _id: article._id }).exec(function (err, articles) {
console.log(articles)
// [ { _id: 54b9e6ca6426ef590d317a56,
// __v: 0,
// comments:
// [ { username: 'chh',
// content: 'hello world',
// _id: 54b9e6ca6426ef590d317a57 },
// { content: 'foobar',
// username: 'jobs',
// _id: 54b9e6ca6426ef590d317a58 } ] } ]
})
})
})
[@chinghanho](/user/chinghanho) 是啊,我也尝试了好多次了,不知道别人是怎么恶意插入的
当使用 mongoose
和 MongoDB 进行操作时,如果在 update
操作中使用了 upsert: true
并且 _id
不存在或为 null
,可能会导致意外的行为。具体来说,当你尝试更新一个不存在的文档,并且该文档的 _id
字段没有提供有效的值时,MongoDB 会默认创建一个新的文档,而这个新文档的 _id
将会是一个自动生成的唯一标识符。
在你的代码示例中,upsert: true
的设置意味着如果找不到匹配的文档,则会创建一个新的文档。如果在这个过程中 _id
未被正确设置或者为 null
,MongoDB 会在创建新文档时生成一个新的 _id
。
可能存在的原因
- 缺少有效的
_id
:在更新或插入操作中,如果没有提供有效的_id
,MongoDB 默认会生成一个新的_id
。 - 错误的数据结构:在传递的数据中,可能
_id
被错误地设置为null
或其他无效值。 - 代码逻辑问题:可能在某些情况下,你忘记给
_id
赋值,或者在某些条件下_id
被意外地设为null
。
示例代码
假设你有一个名为 Article
的 Mongoose 模型,你可以通过以下方式来确保 _id
在插入或更新时不会为 null
:
const mongoose = require('mongoose');
const { Schema } = mongoose;
// 定义 Article 模型
const articleSchema = new Schema({
title: String,
comments: [{ body: String, date: Date }]
});
const Article = mongoose.model('Article', articleSchema);
// 更新或插入操作
async function updateOrInsertArticle(id, data) {
try {
const result = await Article.updateOne(
{ _id: mongoose.Types.ObjectId(id) },
{ $push: { comments: data } },
{ upsert: true }
);
console.log(result);
} catch (error) {
console.error(error);
}
}
// 使用示例
updateOrInsertArticle('some-id', { body: 'Hello', date: new Date() });
关键点
- 使用
mongoose.Types.ObjectId
确保_id
是有效的。 - 使用
updateOne
方法替代update
,以获得更好的可读性和功能。 - 在实际应用中,确保
_id
始终有效,避免由于_id
为null
导致的异常行为。
通过以上方法,可以有效地避免 _id
为 null
的情况,确保数据库操作的稳定性和可靠性。
在你的代码中使用 upsert: true
的情况下,如果找不到匹配的文档,则会创建一个新的文档。如果 _id
字段没有被明确设置,MongoDB 默认会生成一个 ObjectId。然而,在某些情况下,如果插入过程中出现错误或者有意为之,_id
可能会被设置为 null
。
这种情况可能的原因包括:
- 代码逻辑错误:确保在插入操作前
_id
已经被正确赋值。 - 恶意攻击:攻击者可能故意在插入数据时将
_id
设置为null
。 - 验证和默认值配置问题:检查 Mongoose 模式定义中是否有关于
_id
的验证或默认值设置。
为了更好地排查问题,建议添加更多的错误处理逻辑,并检查 MongoDB 中的相关记录。
当你使用 upsert: true
的时候,如果查询条件没有匹配到任何文档,MongoDB 将会创建一个新的文档。如果在这个过程中 _id
没有被正确指定,那么 MongoDB 默认会给 _id
赋一个 ObjectId。
但是,在你的案例中,如果 _id
为 null
,可能是因为以下几种情况:
-
手动设置为空:有可能在更新逻辑中,有人故意或无意地将
_id
设置为了null
。 -
默认值错误:如果你的模型定义中
_id
字段的默认值被错误地设置为了null
或者未定义,那么新插入的文档中的_id
可能会变成null
。 -
数据验证问题:确保你的数据验证机制能够捕捉到这种情况,并抛出错误或进行相应的处理。
-
代码逻辑错误:检查是否有其他地方的代码逻辑导致了
_id
被意外赋值为null
。
建议你检查模型定义和相关代码逻辑,确保 _id
在任何情况下都能得到正确的生成。同时,添加更多的错误处理和日志记录来帮助追踪问题的根源。