전체 가이드
중간 심각도API 보안

공개된 GraphQL 인트로스펙션: 문제가 되는 이유와 끄는 방법

GraphQL 인트로스펙션은 API의 전체 스키마(모든 타입, 필드, 인자, 뮤테이션)를 반환하는 내장 쿼리입니다. 개발에는 필수적이지만 비공개 API의 프로덕션에서는 접근할 수 없어야 합니다. 켜 두면 백엔드 전체 공격 표면의 지도가 됩니다.

무엇인가요

모든 GraphQL 서버는 소수의 메타 필드를 구현하며, 대표적인 것이 __schema와 __type입니다. `query { __schema { types { name fields { name } } } }`를 /graphql에 한 번 POST하기만 하면 전체 타입 정의가 반환됩니다.

GraphiQL, Apollo Sandbox, Playground UI 같은 도구는 쿼리 자동 완성과 스키마 탐색기 표시를 위해 인트로스펙션에 의존합니다. 개발 중에는 바라던 동작이지만, 비공개 API의 프로덕션에서는 전 세계 누구나 같은 지도를 내려받을 수 있다는 뜻입니다.

왜 중요한가요

스키마에는 모델, 관계, 노출하는 모든 뮤테이션의 이름이 담겨 있습니다. 외부에서 발견되리라 예상하지 않았던 관리자용, 내부용, 사용 중단된 필드도 예외가 아닙니다. 공격자는 이를 이용해 인증 우회, IDOR, 인젝션 버그를 탐색할 작업 목록을 만듭니다.

모든 필드에 권한 검사가 올바르게 적용되어 있더라도 refundOrder, impersonateUser, exportBackup 같은 숨겨진 뮤테이션이 스스로를 드러내서는 안 됩니다. 인트로스펙션은 공격자의 정찰 단계를 몇 시간의 추측에서 요청 한 번으로 바꿔 버립니다.

고치는 방법

Apollo Server에서 인트로스펙션 비활성화하기

NODE_ENV가 production일 때 인트로스펙션을 끄세요. 로컬에서는 켜 두어 팀이 Sandbox에서 계속 스키마를 탐색할 수 있게 하세요.

import { ApolloServer } from "@apollo/server";

const server = new ApolloServer({
  typeDefs,
  resolvers,
  introspection: process.env.NODE_ENV !== "production",
});
GraphQL Yoga / graphql-http에서 비활성화하기

Yoga에는 전용 플러그인이 있고, graphql-http에서는 graphql-js의 검증 규칙을 사용할 수 있습니다. 둘 다 인트로스펙션 쿼리를 실행 전에 차단합니다.

// GraphQL Yoga
import { createYoga } from "graphql-yoga";
import { useDisableIntrospection } from "@graphql-yoga/plugin-disable-introspection";

export const yoga = createYoga({
  schema,
  plugins: process.env.NODE_ENV === "production" ? [useDisableIntrospection()] : [],
});

// graphql-http (or express-graphql)
import { NoSchemaIntrospectionCustomRule } from "graphql";

const validationRules = process.env.NODE_ENV === "production"
  ? [NoSchemaIntrospectionCustomRule]
  : [];
프로덕션에서 스키마 탐색기 UI 제거하기

GraphiQL, Playground, Apollo Sandbox는 사람이 스키마를 탐색하도록 돕기 위한 것으로, 공개 프로덕션 엔드포인트에는 어울리지 않습니다. 인증 검사 뒤에 두거나 프로덕션 빌드에서는 아예 마운트하지 마세요.

차단 목록보다 권한 부여를 우선하기

인트로스펙션 비활성화는 보안 강화 조치이지 접근 제어가 아닙니다. 모든 필드에는 여전히 리졸버 수준의 적절한 권한 검사가 필요합니다. 그렇지 않으면 필드 이름을 추측한 누구나 그것을 호출할 수 있습니다. 인트로스펙션 차단은 유일한 방어 계층이 아니라 여러 계층 중 하나로 다루세요.

자주 묻는 질문

스키마를 숨기는 것은 결국 은닉에 의한 보안 아닌가요?

부분적으로는 그렇습니다. 끈질긴 공격자는 여전히 필드 이름을 무차별 대입으로 알아낼 수 있습니다. 하지만 정찰을 저렴하고 완전하게 만들어 주지 않는 것만으로도 가치가 있습니다. 상용 GraphQL API 가이드와 OWASP GraphQL 치트 시트는 모두 프로덕션에서 인트로스펙션을 비활성화할 것을 권장합니다.

개발자가 스키마를 탐색하길 원하는 공개 API라면 어떻게 하나요?

스키마를 의도적으로 제공하세요. Schema Definition Language 파일을 공개하거나, 문서 사이트를 운영하거나, 인증 후에만 인트로스펙션을 노출하는 방법이 있습니다. 익명 POST 한 번으로 모든 것을 반환하는 것과는 완전히 다릅니다.

AppSafe는 이것을 어떻게 탐지하나요?

AppSafe는 /graphql과 /api/graphql에 작은 인트로스펙션 쿼리를 POST하고, 200 상태와 함께 __schema 응답이 오는지 확인합니다. 응답이 오면 'API 보안' 카테고리에서 중간 심각도로 보고합니다.

내 앱도 영향을 받나요?

AppSafe는 이 문제와 수십 가지 다른 문제를 한 번의 무료 스캔으로 점검합니다.

내 앱 무료 스캔