【问题标题】:ExpressJS set the Depth of JSON ParsingExpressJS 设置 JSON 解析的深度
【发布时间】:2021-01-19 09:28:30
【问题描述】:

我想在Express中间件express.json()中设置JSON解析的深度。

例如,如果我要设置解析depth=1的选项,那么

'{ "email": { "$ne": "user@example.com" } }'

将被解析为

{ email: "[object Object]" }

-- 或--

当我设置depth=2,那么

'{ "email": { "$ne": "user@example.com" } }'

将被解析为

{ email: { '$ne': 'user@example.com' } }

等等,

在这种情况下,不会有默认深度的问题,因为开发人员会知道他们在开发过程中将允许多少嵌套。

PS:它将防止应用程序受到 NoSQL Injection 的攻击。

【问题讨论】:

    标签: json express body-parser


    【解决方案1】:

    写你自己的middleware:

    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)
    

    或者,如果您更喜欢"[object Object]"

    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() })
    

    【讨论】:

    • 我可以用它来创建自己的中间件吗?
    • limit_depth 是一个完整的中间件。
    【解决方案2】:

    我写下查询,最大 6-8 深度。在查找中使用查找时。

      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 }]
            }
          }
    ]);
    

    您可以将深度设置为 10。如果您觉得 JSON 出错了,请增加它 :)

    【讨论】:

    • 这是 MongoDB 的一部分。问题是关于express js的。或者通过 express 在更深入的正文解析器库中。再次阅读问题。
    • 谢谢,除此之外它还帮助我限制了有效载荷。只有特定深度的 JSON 在有效载荷中接收。
    【解决方案3】:

    如果有人不想更改req.body 的值,可以从here 使用此功能

    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
    }
    

    【讨论】:

      猜你喜欢
      • 2020-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多