IDOR — if문 하나 빠져서 90만 건 유출된 사건
이 토픽을 마치면
IDOR 취약점이 뭔지 설명할 수 있고, 서버 코드에서 이걸 막는 패턴을 알게 됩니다.
방통대에서 벌어진 일
방송통신대학교 홈페이지에서 지원서를 조회하면 URL이 이렇게 생겼습니다:
https://www.knou.ac.kr/application?id=12345누군가 이 숫자를 12346으로 바꿨습니다. 그랬더니 다른 사람의 지원서가 그대로 열렸습니다. 이름, 생년월일, 이메일, 전화번호, 계좌번호, 출신 학교까지 전부 보였습니다.
숫자를 1씩 올리면서 반복하면? 10년치 지원서 약 90만 건을 전부 꺼내볼 수 있었습니다. 해킹 기술이 필요한 것도 아니었습니다. URL 숫자 하나 바꾸는 거니까요.
원인: 서버가 "너 누구야?"를 안 물어본 것
서버 코드가 이런 식이었을 겁니다:
// ❌ 위험한 코드
app.get('/application', async (req, res) => {
const id = req.query.id;
const app = await db.findOne({ id });
res.json(app); // 누가 요청했는지 확인 안 함
});URL에 있는 번호(id=12345)만 보고 바로 데이터를 꺼내줍니다. 이 요청을 보낸 사람이 12345번 지원서의 주인인지 전혀 확인하지 않습니다.
이런 취약점을 IDOR(Insecure Direct Object Reference)라고 합니다. 직역하면 "안전하지 않은 직접 객체 참조" — URL이나 파라미터에 들어있는 ID를 검증 없이 직접 써서 데이터를 꺼내는 겁니다.
해결: 딱 한 줄
// ✅ 안전한 코드
app.get('/application', async (req, res) => {
const id = req.query.id;
const app = await db.findOne({ id });
if (app.userId !== req.user.id) { // ← 이 한 줄
return res.status(403).send('권한 없음');
}
res.json(app);
});"요청한 사람"과 "데이터의 주인"이 같은지 비교하는 if문 하나입니다. 이게 전부입니다. 이 한 줄이 없어서 90만 건이 유출됐습니다.
이 사건에서 배울 점
IDOR는 고급 해킹 기술이 아닙니다. URL 숫자만 바꿔도 되니까 비개발자도 할 수 있습니다. 그만큼 발생 빈도도 높습니다.
서버 코드를 짤 때 항상 이 전제를 깔아야 합니다:
사용자가 보내는 모든 것은 위조될 수 있다.
URL, 쿠키, 폼 데이터, 헤더 — 클라이언트에서 오는 모든 값은 변조 가능합니다. 그래서 서버에서 반드시 **"이 사람이 이 데이터에 접근할 자격이 있는가?"**를 확인해야 합니다.
이 원칙은 IDOR 말고도 모든 서버 보안의 기본입니다.
IDOR이 자주 발생하는 곳
IDOR은 "서버가 권한 검사를 빠뜨린 곳"이면 어디든 발생할 수 있습니다. 흔한 패턴들:
- 파일 다운로드 —
/download?file=report_001.pdf→ 파일명을 바꾸면 남의 보고서가 다운로드됨 - 계정 설정 —
/api/user/42/settings→ ID를 43으로 바꾸면 남의 설정이 보임 - 주문 내역 —
/order/12345→ 주문번호 바꾸면 남의 주문 상세가 보임 - 비밀번호 재설정 —
/reset?token=abc&user_id=42→ user_id를 바꾸면 남의 비밀번호를 바꿀 수 있음
공통점은 전부 URL이나 파라미터에 식별자(ID)가 노출되어 있다는 겁니다. ID가 노출되는 것 자체는 문제가 아닙니다 — 서버에서 "이 사람이 이 ID에 접근할 자격이 있는가?"를 검사하면 됩니다. 이 검사가 빠지면 IDOR입니다.
OWASP(웹 보안 표준 기관)에서 매년 발표하는 취약점 Top 10에 IDOR의 상위 카테고리인 "Broken Access Control"이 2021년부터 1위를 차지하고 있습니다. 그만큼 자주 발생하고, 그만큼 간단하게 막을 수 있는 취약점입니다.
예방 방법을 정리하면: 모든 데이터 접근 API에서 (1) 로그인 확인 → (2) 요청자와 데이터 소유자 일치 확인 두 단계를 반드시 거치세요. 이 두 줄이면 IDOR은 원천 차단됩니다.
핵심
IDOR은 URL의 ID를 바꾸면 남의 데이터가 보이는 취약점입니다. 원인은 서버가 "요청자 = 데이터 주인"인지 확인하지 않은 것이고, 해결은 if문 한 줄입니다. 사용자 입력은 항상 위조 가능하다고 가정하세요.