Azure의 GraphQL: 11부 - DoS 쿼리 방지
Post
, related
에 대한 새로운 "가상"필드를 GraphQL 스키마에 추가했습니다.type Post {
id: ID!
title: String!
url: Url!
date: Date
tags: [String!]!
description: String
content: String!
related(tag: String): [Post!]
}
하지만 그렇게 하는 과정에서 문제가 추가되었습니다. 이 쿼리를 예로 들어 보겠습니다.
query {
posts {
related {
related {
related {
related {
related {
related {
related {
related {
title
}
}
}
}
}
}
}
}
}
}
이런... 여기서 무슨 일이 일어날까요? 정확히 당신이 생각하는 것, 내 API에 대한 일련의 재귀 쿼리와 나는 방금 내 서버에 대한 서비스 거부, DoS, 공격 벡터를 생성했습니다(분산되지 않았기 때문에 DDoS 공격이 아닙니다).
그러나 이것은 GraphQL 관점에서 완벽하게 유효합니다. 노출하라고 지시한 그래프를 걷고 있을 뿐입니다. 하지만 저는 그것이 제 서버를 다운시키는 것을 원하지 않았습니다! 이것은 단일 유형의 GraphQL 스키마이지만 더 복잡한 스키마에서는 다른 유형을 통해 원본으로 다시 재귀할 수 있는 유형이 있다는 것이 현실적입니다.
Azure API 관리 GraphQL 정책
좋은 소식입니다. APIM 정책을 활용하여 이 문제를 직접 해결할 수 있습니다. 이번에는
<validate-graphql-request>
policy 을 사용하겠습니다.이 정책은 인바운드 정책입니다. 즉, 요청이 백엔드로 전달되기 전에 적용됩니다. 이 경우에는 GraphQL 리졸버 정책으로 미리 정의한 규칙에 대해 가로채고 유효성을 검사할 수 있습니다.
정책의 두 가지 최상위 속성인
max-size
및 max-depth
에 초점을 맞출 것입니다.max-size
정책은 인바운드 요청 크기 제한을 적용하는 데 사용됩니다. 즉, 100kb를 초과하는 모든 요청을 거부하므로 과도한 쿼리 크기로 인해 과도한 쿼리 크기가 발생할 수 있으므로 단일 요청에서 재시도할 수 있는 데이터의 양을 제한합니다. 데이터베이스 작업을 수행 중입니다.이를 APIM 정책의
<inbound>
섹션에 추가합니다.<policies>
<inbound>
<base />
<validate-graphql-request error-variable-name="size" max-size="10240" />
</inbound>
<!-- snip -->
</policies>
이것은 유용한 정책입니다. 특히 다양한 유형과 필드를 많이 노출하는 큰 GraphQL 스키마가 있지만 실제로 문제를 해결하지는 못할 것입니다. 크기 모자. 대신 정책의
max-depth
부분을 사용하려고 합니다.max-depth
를 사용하면 쿼리를 거부하기 전에 요청이 수행할 수 있는 중첩 수준을 지정할 수 있습니다. 정책을 업데이트해 보겠습니다.<policies>
<inbound>
<base />
<validate-graphql-request error-variable-name="size" max-size="10240" max-depth="3" />
</inbound>
<!-- snip -->
</policies>
max-depth
에서 알아야 할 한 가지는 GraphQL 작업 유형( query
또는 mutation
)으로 시작하는 1 기반 인덱스를 사용한다는 것입니다. 즉, 깊이가 3이면 다음을 허용합니다.query {
postsByTag(tag: "graphql") {
title
related {
title
}
}
}
그러나이 쿼리는 유효하지 않습니다.
query {
postsByTag(tag: "graphql") {
title
related {
title
related {
title
}
}
}
}
그리고 위의 쿼리를 실행하면 다음 본문과 함께
400 Bad Request
상태를 제공합니다.{
"statusCode": 400,
"message": "The query is too nested to execute, its depth is more than 3 "
}
성공! 우리는 게이트웨이 수준에서 블록을 생성했습니다. 즉, 다운스트림 서버가 불량 쿼리에 의해 적중되는 것에 대해 걱정하지 않아도 됩니다.
결론
GraphQL의 간과하기 쉬운 측면 중 하나는 그래프로 작업하고 그래프에서 탐색 및 악용될 수 있는 재귀 참조를 만들어 백엔드에 대한 DoS 공격 벡터를 생성할 수 있다는 것입니다.
그러나 Azure API Management의 GraphQL 정책으로 쉽게 처리할 수 있는 것입니다.
max-depth
정책의 <validate-graphql-request>
부분을 사용하면 클라이언트가 수행하는 작업에서 과도한 중첩을 방지할 수 있으며 이를 max-size
속성과 결합하여 크고 평평한 요청을 방지할 수 있습니다.특정 리졸버 필드 또는 경로에 대한 액세스를 제한하는 것과 같이 정책에 설정할 수 있는 다른 규칙이 있지만 독자에게 연습 문제로 남겨두겠습니다. 😉
Reference
이 문제에 관하여(Azure의 GraphQL: 11부 - DoS 쿼리 방지), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/azure/graphql-on-azure-part-11-avoiding-dos-queries-4715텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)