GraphQL API 취약점 (PortSwigger Academy) - 개념 정리 (Part 1)
GraphQL이 무엇인지부터 REST API와의 차이, 구조까지 이해하기
GraphQL 이란?
GraphQL은 API를 위한 쿼리 언어이며 서버 측 런타임 이라고 정의를 하는 것 같다.
쉽게 설명하면, 브라우저나 모바일 앱이 서버에게 데이터를 요청할 때
“어떤 형식으로 요청하고, 어떤 형식으로 받을지”를 정하는 방식 중에 하나다.
대표적으로는 REST API와 자주 비교된다.
예를들어, 우리가 웹사이트를 쓸 때 이런 기능들이 있다:
- 상품 목록 보기
- 프로필 보기
- 장바구니 추가
- 게시글 상세 보기
- 댓글 목록 보기
이런 요청은 프론트엔드 → 서버로 보내지며,
서버는 JSON 같은 형태로 데이터를 돌려준다.
이걸 가능하게 해주는 통로가 API다.
그리고 GraphQL은 이 API를 설계하는 방식이다.
REST API vs GraphQL 차이점
REST API는 서버가 정해준 형태로 데이터를 내려준다.
예를 들면,
GET /users/1GET /products/3GET /posts/10/commentsPOST /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번 상품의 name과 price만 응답으로 돌려준다.
차이점 정리
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 API의 GET요청과 비슷한 역할
2. Mutation (수정)
데이터를 변경할 때 사용
mutation {
createProduct(name: "test") {
id
}
}
REST API의 POST, 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필드가 존재함- 각각의 타입도 정의됨
!가 붙은건 필수 값
위 Schema는 Instropection query를 날려서 획득이 가능하다.
GraphQL에는 Instropection이라는 기능이 존재하는데,
서버가 어떤 Schema를 가지고 있는지 query로 조회할 수 있는 기능이다.
원래는 개발 편의를 위해 만들어진 기능이나,
실수로 배포할 경우에는 공격자가 API 구조를 얻을 수 있는 좋은 먹잇감이 된다.
다음 글에서는 GraphQL API의 취약점과 Exploit에 대해 다뤄볼 예정이다.