본문으로 건너뛰기
SDETRole
SDETRole

용어집 · 보안

IDOR(안전하지 않은 직접 객체 참조)

영어: IDOR

다른 이름: Insecure Direct Object Reference, 안전하지 않은 직접 객체 참조, BOLA, Broken Object Level Authorization

정의

요청의 ID만 바꾸면 다른 사용자의 데이터를 읽거나 수정할 수 있게 되는 접근 제어 결함으로, Insecure Direct Object Reference의 약자입니다.

IDOR(Insecure Direct Object Reference, 안전하지 않은 직접 객체 참조)는 애플리케이션이 /api/orders/1043처럼 요청에 담긴 식별자로 레코드를 가져오면서, 로그인한 사용자가 그 레코드에 접근할 권한이 있는지는 전혀 확인하지 않는 취약점입니다. ID를 1044로 바꾸면 다른 사람의 주문이 보입니다. OWASP Top 10 2021의 A01 Broken Access Control에 해당하며, OWASP API Security Top 10에서는 같은 문제를 Broken Object Level Authorization(BOLA)이라고 부릅니다.

예시

Alice가 로그인해서 자신의 주문을 봅니다.

GET /api/orders/1043
Authorization: Bearer <alice-token>

그녀가 숫자를 바꿉니다.

GET /api/orders/1044
Authorization: Bearer <alice-token>

응답이 Bob의 주소와 상품이 담긴 200이라면, 이 엔드포인트는 사용자를 인증하지만 특정 객체에 대한 접근은 인가하지 않는 것입니다. 추측하기 어려운 UUID를 쓰면 추측이 어려워질 뿐 결함이 고쳐지지는 않습니다. ID는 URL, 로그, 공유 링크를 통해 새어 나가기 때문입니다.

테스터가 확인하는 것

각자 자신의 데이터를 가진 테스트 사용자 두 명을 만들고, 모든 엔드포인트와 메서드(조회, 수정, 삭제, 그리고 /users/{id}/invoices 같은 중첩 경로)에서 사용자 A의 자격 증명으로 사용자 B의 객체에 접근해 봅니다. 자동화하기도 쉽습니다. Playwright에서는 다음과 같습니다.

import { test, expect, request } from '@playwright/test';

test("Alice cannot read Bob's order", async () => {
  const alice = await request.newContext({
    baseURL: process.env.API_URL,
    extraHTTPHeaders: { Authorization: `Bearer ${process.env.ALICE_TOKEN}` },
  });
  const res = await alice.get(`/api/orders/${process.env.BOB_ORDER_ID}`);
  expect([403, 404]).toContain(res.status());
  await alice.dispose();
});

403과 404 모두 허용됩니다. 많은 API는 레코드의 존재조차 확인해 주지 않으려고 404를 반환합니다. 다음도 확인하세요.

  • 경로뿐 아니라 요청 본문과 쿼리 문자열에 담긴 ID.
  • IDOR로 데이터를 변경하거나 삭제할 수 있는 쓰기 작업.
  • ID 목록을 받는 일괄 처리(bulk) 및 내보내기 엔드포인트.
  • 멀티 테넌트 시스템의 테넌트 경계.

왜 놓치기 쉬운가

기능 테스트는 보통 한 사용자로 로그인해서 그 사용자의 데이터만 사용하므로 인가 검사가 실행될 일이 없습니다. IDOR는 모든 엔드포인트에 대해 “이 ID가 다른 사람의 것이라면?“이라고 물어야 찾을 수 있습니다. 이런 테스트는 테스트 권한을 받은 시스템에서만 실행하세요.

SDETRole 전체에서 검색할 내용을 입력하세요.

Pagefind 전문 검색 · 브라우저에서 실행됩니다 검색 페이지 열기 →