포스트

GraphQL API 취약점 (PortSwigger Academy) - 개념 정리 (Part 1)

GraphQL이 무엇인지부터 REST API와의 차이, 구조까지 이해하기

GraphQL API 취약점 (PortSwigger Academy) - 개념 정리 (Part 1)

GraphQL 이란?

GraphQL은 API를 위한 쿼리 언어이며 서버 측 런타임 이라고 정의를 하는 것 같다.

쉽게 설명하면, 브라우저나 모바일 앱이 서버에게 데이터를 요청할 때
“어떤 형식으로 요청하고, 어떤 형식으로 받을지”를 정하는 방식 중에 하나다.
대표적으로는 REST API와 자주 비교된다.

예를들어, 우리가 웹사이트를 쓸 때 이런 기능들이 있다:

  • 상품 목록 보기
  • 프로필 보기
  • 장바구니 추가
  • 게시글 상세 보기
  • 댓글 목록 보기

이런 요청은 프론트엔드 → 서버로 보내지며,
서버는 JSON 같은 형태로 데이터를 돌려준다.
이걸 가능하게 해주는 통로가 API다.

그리고 GraphQL은 이 API를 설계하는 방식이다.


REST API vs GraphQL 차이점

REST API는 서버가 정해준 형태로 데이터를 내려준다.

예를 들면,

  • GET /users/1
  • GET /products/3
  • GET /posts/10/comments
  • POST /orders 와 같이, 각 리소스마다 endpoint가 따로 존재한다.

위의 요청을 보내면 서버는

1
2
3
4
5
6
7
{
  "id": 1,
  "name": "shane",
  "email": "shane@example.com",
  "address": "...",
  "phone": "..."
}

와 같이 객체에 대한 모든 정보를 받게 된다.

반면 GraphQL은 보통 endpoing가 거의 하나다. ex) /graphql
그리고 이 endpoint에 내가 어떤 특정 데이터를 원하는지 query 형태로 넣어서 보내면
요청한 데이터 그대로 반환 해준다.

예를 들어

query {
  product(id: 3) {
    name
    price
  }
}

이렇게 보내면 서버는 id 3번 상품nameprice만 응답으로 돌려준다.


차이점 정리

1. Endpoint 구조의 차이

  • REST API → /users, /orders, /products 등 여러개 존재
  • GraphQL → endpoint 하나 (예시: /graphql)

2. 요청 방식의 차이

  • REST API → HTTP method로 구분 (GET, POST 등)
  • GraphQL → query 형태로 요청

3. 데이터 반환 방식의 차이

  • REST API → 서버가 정해준 구조대로 반환
  • GraphQL → 클라이언트가 요청한 구조 그대로 반환

비교 대상이 맞는지는 모르겠지만 REST API는 완제품 PC,
GraphQL은 PC 조립을 위한 부품단위 정도로 비교해두면 될 것 같다.


GraphQL의 장점

예를 들어 아래 정보가 동시에 필요하다고 가정해보자.

  • 유저 이름
  • 유저 프로필 사진
  • 최근 주문 3개
  • 최근 댓글 5개

REST API라면

  • /user/me
  • /user/me/orders
  • /user/me/comments

이런 식으로 여러 번 나눠 요청할 수 있는 반면에 GraphQL은 아래와 같이 한 번에 요청이 가능하다.

query {
  me {
    username //유저 이름
    avatar //프로필 사진
    orders(limit: 3) { //최근 주문 3개
      id
      total
    }
    comments(limit: 5) { //최근 댓글 5개
      body
    }
  }
}

따라서 필요한 데이터만 요청이 가능하며, 여러 데이터를 한 번에 묶어서 가저올 수 있다는 장점이 있다.


GraphQL 구조 이해하기

GraphQL은 크게 3가지 개념으로 나뉜다.

1. Query (조회)

데이터를 읽을 때 사용한다.

query {
  getProduct(id: 123) {
    name
    description
  }
}

REST APIGET요청과 비슷한 역할


2. Mutation (수정)

데이터를 변경할 때 사용

mutation {
  createProduct(name: "test") {
    id
  }
}

REST APIPOST, PUT, DELETE역할


3. Subscription (실시간 데이터)

웹소켓 기반으로 실시간 데이터 스트리밍 같은 데 사용된다. ex) 채팅, 실시간 알림 등.


4. Schema (핵심)

GraphQL에서 제일 중요한 개념이다.

간단히 말하면 서버가 “나는 이런 데이터를 사용해” 라고 명시해주는 문서다.

예시:

1
2
3
4
5
6
type Product {
  id: ID!
  name: String!
  description: String!
  price: Int
}
  • Product라는 객체 존재
  • id, name, description, price 필드가 존재함
  • 각각의 타입도 정의됨
  • !가 붙은건 필수 값

SchemaInstropection query를 날려서 획득이 가능하다.

GraphQL에는 Instropection이라는 기능이 존재하는데,
서버가 어떤 Schema를 가지고 있는지 query로 조회할 수 있는 기능이다.

원래는 개발 편의를 위해 만들어진 기능이나,
실수로 배포할 경우에는 공격자가 API 구조를 얻을 수 있는 좋은 먹잇감이 된다.

다음 글에서는 GraphQL API의 취약점과 Exploit에 대해 다뤄볼 예정이다.


출처: PortSwigger Academy

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.