Amazon web services GraphQL:如何防止嵌套攻击以访问未经授权的数据?

Amazon web services GraphQL:如何防止嵌套攻击以访问未经授权的数据?,amazon-web-services,security,graphql,aws-appsync,Amazon Web Services,Security,Graphql,Aws Appsync,我正在运行一个AWS AppSync GraphQL API服务,尽管根据我所知,这个问题同样适用于apollo服务器 从我对GraphQL解析器及其链接方式的理解来看,恶意授权客户端似乎可以对其有权访问的对象发出经过身份验证的请求,然后将请求链接到正文中,以便最终访问未经授权的记录一种或多种有效的设计模式可以防止此类攻击 例如,我将使用一个不是我实际的情况,但应该足够简单,以了解我的意思。假设我们正在运行一个学生成绩数据库 有称为学生、年级和课程的类型 为了方便起见,当您查找学生时,其中有一个

我正在运行一个AWS AppSync GraphQL API服务,尽管根据我所知,这个问题同样适用于apollo服务器

从我对GraphQL解析器及其链接方式的理解来看,恶意授权客户端似乎可以对其有权访问的对象发出经过身份验证的请求,然后将请求链接到正文中,以便最终访问未经授权的记录一种或多种有效的设计模式可以防止此类攻击

例如,我将使用一个不是我实际的情况,但应该足够简单,以了解我的意思。假设我们正在运行一个学生成绩数据库

有称为学生、年级和课程的类型

为了方便起见,当您查找学生时,其中有一个返回分数的解析器。此外,为了方便起见,当您查找成绩时,它所在的课程有一个解析器。此外,为了方便起见,当你查找课程时,你可以看到注册学生

现在,作为一名学生,我有充分的理由称之为:

query {
  getMyRecord {
    name
    studentId
    ssn
    grades {
      gradeValue
      semester
      course {
        name
        courseId
        courseNumber
      }
    }
  }
}
这将是一个非常正常的电话。此外,GraphQLAPI还支持课程管理员和教授使用的方法,因此他们完全有权调用以下内容:

query {
  getCourse {
    name
    courseId
    courseNumber
    students {
      studentId
      name
    }
  }
}
同样,我们的GraphQLAPI支持一个非常合理的东西

问题在于,恶意学生可能会检查模式,并决定将上面的第一个查询扩展为:

query {
  getMyRecord {
    name
    studentId
    ssn
    grades {
      gradeValue
      semester
      course {
        name
        courseId
        courseNumber
        students { #note here!
          name
          ssn
          grades {
            gradeValue
            #... and so on!
          }
        }
      }
    }
  }
}
这将导致恶意地开始看到其他学生的成绩和ssn,他们正在学习的课程,这些课程的注册学生,等等

我可以想出一些设计模式来防止这种情况,但它们似乎都不雅观。特别是,我可以在链式冲突解决程序的每一步重新运行授权程序,但这将大大增加工作量,99%的调用都会重复大量工作


我非常期待了解用于防范此类攻击的既定设计模式。

在大多数GraphQL框架中,授权是在字段级别处理的。您可以通过上下文对象将用户和/或他们的角色和权限注入到解析器中,然后在解析器本身中包含任何授权逻辑。像这样的流行库可以提供一种更好的方法来实现这一点,并使创建可重用规则变得更容易——然而,归根结底,这仍然是相同的想法

这里的关键是,这种授权逻辑不仅应该应用于根级别的字段,还可能应用于表示数据中关系的其他字段(如示例中的
学生
字段)

我不使用AppSync,但我相信我会详细描述如何在该上下文中应用这种模式


另一种方法是在域或存储层处理授权。例如,PostGraphile利用行级安全性强制执行授权规则。这可以让您在节点级别实现授权(用户有权访问哪些资源,而不是访问哪些字段)。

我不知道您使用的是哪种授权类型,但您可以设定使用的条件。如果您使用的是AWS\u IAMAMAZON\u COGNITO\u USER\u POOLS授权,则您拥有上下文中的
用户名
,您可以基于
用户名
返回响应。例如,在
学生
解析器映射响应中,您可能有:

{
   #if($context.result["username"] == "$context.identity.username")
      $utils.toJson($context.result);
   #end
}
如果
用户名
与此检查不匹配,则只返回空响应