Je souhaite définir la profondeur de l'analyse JSON dans le middleware Express express.json()
.
Par exemple, si je définirais l'option pour analyser la depth=1
, alors
{ email: { '$ne': 'user@example.com' } }
sera analysé en
'{ "email": { "$ne": "user@example.com" } }'
-- ou --
Quand je règle la depth=2
, alors
{ email: "[object Object]" }
sera analysé en
'{ "email": { "$ne": "user@example.com" } }'
Etc,
Dans ce cas, il n'y aura pas de problème de profondeur par défaut, car le développeur saura combien d'imbrication il autorisera pendant le développement.
PS: Cela empêchera l'application d'être vulnérable à l'injection NoSQL.
3 Réponses :
J'écris la requête, la profondeur maximale de 6-8 va. lorsque vous utilisez la recherche dans la recherche.
const [result] = await Collection.aggregate([ { $match:statusObj }, { $project:{ _id:1, name:1 } }, { $lookup:{ from:"articles", let: { "cat_id":"$_id"}, pipeline:[ { $match:{ $expr:{ $and: [ { $eq: ["$category_id", "$$cat_id"] }, { $eq: ["$isDeleted", false] }, { $eq: ["$type", type] } ] } } }, { $lookup:{ from:"view_articles", let: { "article_id":"$_id"}, pipeline:[ { $match:{ $expr:{ $and: [ { $eq: ["$article_id", "$$article_id"] }, { $eq: ["$isDeleted", false] } ] } } } ], as:"viewCount" } }, { $addFields:{ noOfViewCount : { $size:"$viewCount"} } } ], as:"articleCategoryData" } }, { $addFields: { postCount: {$size:"$articleCategoryData" }, tempsArray: { $map: { input: "$articleCategoryData", as: "tempData", in: { $add: "$$tempData.noOfViewCount" } } }, }, }, { $addFields: { viewCount:{ $sum:"$tempsArray" } }, }, { $project:{ _id: 1, name: 1, postCount: 1, viewCount: 1 } }, { $facet: { count: [ { $count: "total" } ], result: [{ $match: {} }, { $skip: skipRecord }, { $limit: limit }] } } ]);
vous pouvez définir la profondeur sur 10. Si vous pensez que JSON ne va pas, augmentez-le :)
Cela fait partie de MongoDB. La question concerne express js. Ou dans une bibliothèque d'analyseur de corps plus approfondie par express. Relisez les questions.
Merci de l'avoir et en plus, aidez-moi à limiter la charge utile. seule la profondeur spécifique de réception JSON dans la charge utile.
Écrivez simplement votre propre middleware :
let limit_depth = (obj, current_depth, limit) => { for(const key in obj) { if( obj[key] instanceof Object ) { if( current_depth+1 === limit ) { obj[key] = "[object Object]" // or something similar } else limit_depth(obj[key], current_depth+1, limit) } } } app.use(function(req, res, next) { limit_depth(req.body, 0, depth_limit); next() })
Ou, si vous préférez "[object Object]"
:
const get_depth = (obj) => { let depth = 0 for(const key in obj) { if( obj[key] instanceof Object ) { depth = Math.max(get_depth(obj[key]), depth) } } return depth+1 } const depth_limit = 2 const limit_depth = function(req, res, next) { if( get_depth(req.body) > depth_limit ) throw new Error("Possible NoSQL Injection") next() } app.use(limit_depth)
Puis-je l'utiliser pour créer mon propre middleware?
limit_depth
est un middleware complet.
Au cas où quiconque ne souhaite pas modifier la valeur de req.body
, peut utiliser cette fonction à partir d' ici
function serializer(payload: any, cdepth: number, options: Options): void { const main: any = {} const maxDepth = typeof options.maxNestingLevel == 'number' ? (options.maxNestingLevel == 0 ? 1 : options.maxNestingLevel) : 1 for (const key in payload) { // check for object if (payload[key] instanceof Object) { // check if depth is limited, replace if needed if (cdepth === maxDepth) { main[key] = options.replaceWith } else { // serialize the nested main[key] = serializer(payload[key], cdepth + 1, options) } } else { // add to main object if not to be checked main[key] = payload[key] } } return main }