2
votes

ExpressJS a défini la profondeur de l'analyse JSON

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.


0 commentaires

3 Réponses :


0
votes

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 :)


2 commentaires

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.



1
votes

É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)


2 commentaires

Puis-je l'utiliser pour créer mon propre middleware?


limit_depth est un middleware complet.



0
votes

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
}


0 commentaires