← 메인으로

🪪 전자금융 보안 모의해킹 · 거래 시 소유주 검증 (금융 IDOR)

Target: 계좌 조회/이체 서비스
평가기준: 위험도 5 WEB-SER 부적절한 이용자 인가
💡 쉽게 말하면
내 계좌번호 칸에 남의 번호를 적었더니 남의 잔액이 보인다면? 서버가 "이 계좌가 정말 당신 것인지" 확인하지 않은 탓입니다. 거래마다 소유주를 확인해야 합니다.
🔓 공격 시뮬레이션 (Red Team)
🛡️ 대응 방안 (Blue Team)
계좌 거래내역 조회🔒 Secured Channel
로그인한 이용자가 요청한 계좌번호 파라미터의 소유주가 본인인지 서버가 확인하지 않으면, 파라미터만 바꿔 타인의 계좌·거래내역을 조회/이체할 수 있습니다(금융형 IDOR).
⚡ 소유주 검증 우회(IDOR)
본인 계좌 → 타인 계좌번호로 변조
OFF
🖥️ 금융 시스템 처리 로그
[SYSTEM] Core Banking Channel ready.
[INFO] 거래 요청 대기 중...
⚖️ 컴플라이언스 위반 분석
공격 실행 후 분석 결과가 표시됩니다.
[심각] 전자금융 보안 기준 위반 감지
  • 평가기준 [전자금융] 거래 시 소유주 검증(위험도 5)
  • 부적절한 이용자 인가(IN) / 불충분한 권한 검증
  • 개인정보보호법 제29조 안전조치 의무 위반
🛡️ 대응 코드/설정 실습

서버는 모든 거래에서 세션 이용자와 대상 계좌의 소유 관계를 확인해야 합니다. 파라미터를 신뢰하지 않도록 인가 로직을 보완하세요.

📚 금융보안원 평가기준 / 조치 가이드

1. 점검 항목

이용자 인증/인가 > 거래 시 소유주 검증

2. 위험 분석

  • 파라미터 변조로 타인 계좌·카드·계약 조회/이체
  • 대량 자동조회 시 정보 유출 확대

3. 조치 방법

  • 모든 거래에서 세션 주체–자원 소유관계 검증
  • 직접 식별자 대신 간접 참조(매핑 테이블) 사용
  • 권한 검증을 서버 측에서 일관 적용
🏗️ 현대 금융 IT 환경에서의 변형
OWASP API #1BFFGraphQL오픈뱅킹

어디가 달라졌나

이 취약점은 오늘날 OWASP API Security Top 10 의 1위(BOLA, Broken Object Level Authorization) 입니다. API 우선 아키텍처에서 더 위험해진 이유는 엔드포인트가 화면이 아니라 자원 단위이기 때문입니다 — /accounts/{id}/transactions 는 화면 흐름과 무관하게 누구나 직접 호출할 수 있습니다.

현대 스택에서의 조치

  • 게이트웨이는 이 검증을 못 합니다. JWT 의 sub 는 알지만 "이 계좌가 그 사람 것인지"는 도메인 지식이라, 반드시 서비스 계층에서 확인해야 합니다.
  • GraphQL 이라면 노드 단위 인가가 필요합니다. 리졸버마다 소유권을 확인하지 않으면 중첩 쿼리로 우회됩니다.
  • 오픈뱅킹/마이데이터는 동의 범위(scope)와 계좌 목록을 서버가 보관하고, 요청 계좌가 그 목록에 있는지 매 호출 확인합니다.
# FastAPI — 의존성으로 강제해 "빠뜨릴 수 없게" 만든다
async def owned_account(account_id: str, user=Depends(current_user)) -> Account:
    acc = await repo.get(account_id)
    if acc is None or acc.owner_id != user.id:
        raise HTTPException(404)     # 403 이 아니라 404 — 계좌 존재 여부도 숨긴다
    return acc

@router.get("/accounts/{account_id}/transactions")
async def txns(acc: Account = Depends(owned_account)): ...
놓치기 쉬운 곳 — 403 을 주면 "그 계좌는 존재한다"를 알려 주는 셈입니다. 계좌번호 순회로 실계좌 목록을 만들 수 있으므로, 남의 자원에는 404 가 안전합니다.