웹해킹

OAuth와 OIDC

jiwonniii 2026. 5. 10. 12:40

 

사용자(user) 나(mine,우리가 만든 서비스), their(구글이나 페이스북)

사용자가 원하는 바를 도달하기 위해서는 내가 their에 있는 정보를 가지고 와야한다 

그렇게 하기 위해서 user의 아이디와 비번이 필요하다

그럼 이 방법을 사용하게 된다면 user와 mine모두 단점을 겪게 된다

user는 자신의 아이디와 비번을 넘김으로써 자신의 정보를 다 넘겼다는 생각과

mine은 이 중요한 데이터를 잘 가지고 있어야한다는 보안적인 문제도 지니고 있다

 

이때 생겨난 개념이 바로 OAth라는 개념이다 바로 accessToken을 발급해주는 것이다

accessToken을 발급 해주면 뭐가 좋을까??

  • 사용자의 id와 비번을 알 필요가 없다
  • 사용자의 필수적으로 필요한 기능만 허용해준다

이 두가지 장점을 지니고 있다

이런것들을 본적이있는데 이것에 사용되는 것이 OAuth이다.

 

Role

자 이제 실제 역할에 대해 익혀보자

user는 자원을 가지고 있다는 의미에서 Resource Owner이다

client는 아까 mine을 의미하고 (resource server를 이용하는 고객)

아까는 their로써 하나 였다면

이번에는 Resource Server 자원을 가지고 있는 서버 이다

Authorization Server는 인증 보안의 역할을 하고있는 서버이다

 

  • Authorization Server: "이 사람 맞아? 토큰 줄게" → accounts.google.com 같은 곳
  • Resource Server: "토큰 보여줘. 맞네, 데이터 줄게" → www.googleapis.com 같은 곳

 

 

Register

 

먼저 client가 resource server에 등록을 한다

 

ID(외부에 노출되어도 되는값)와 Secret(비밀번호,외부에 노출되면 안된다),

Authorized redirect URIs: 리소스 서버가 권한을 전달하면서 이 주소로 전달해 달라는 의미이다

 

 

이렇게 등록을 하게 되면 client id와 secret, URL을 알게된다

Resource Server의 모드 기능이 아니라 4개중 2개만 필요하다면 2개만 제공하도록 하는게 서로에게 더 좋다.

 

그 다음으로  ResourceOwner에게 authorization code를 전달한다

client도 이를 리소스 오너에 의해 받게 된다

 

client_secret을 resource server에 전달한다

이과정은 모두 토큰을 얻기위함이다

resource server는 client에게 accesstoken을 전달한다

 

이 accesstoken은 기능 b와 c에대한 토큰이다

이런 과정을 통해서 accesstoken을 발급받게 된다.

 

 

 

 

API

Application Programming Interface

 

Refresh Token

accesstoken은 1시간~60일 정도 기간이 정해져 잇다

이 기간이 끝나면 새로 손쉽게 발급하기 위한것이 Refresh Token이다 

Access Token을 발급할때 Refresh Token을 발급한다.

이때 토큰 에러가 발생하면 Refresh Token을 Authorization서버로 전송하여 토큰을 새로 받게 된다. 

 

<총정리 그림>

 

 

 

+추가 정리

 

  • state: client가 만든 랜덤값. 인증 요청 보낼 때 같이 보내고, 콜백에서 돌아온 값이 같은지 확인. CSRF 방어용. 없으면 공격자가 자기 인증 흐름을 피해자에게 강제로 끼워넣을 수 있음.
  • nonce (OIDC 전용): ID Token에 박히는 일회용 값. 재전송 공격(replay) 방어용. 본인이 QR에서 발견한 그 취약점이 정확히 이거.
  • redirect_uri: Register 때 등록한 URL과 인증 요청에서 보낸 URL이 정확히 일치해야 함. 검증 허술하면 authorization code가 공격자 서버로 감.
  • PKCE (Proof Key for Code Exchange): 모바일/SPA에서는 client_secret을 안전하게 못 숨기니까, 매번 임시 비밀값(code_verifier)을 만들어서 쓰는 보완책.

OAuth2.0과 OIDC 차이점 정리:

OAuth 2.0

1. 사용목적: 별도 회원가입 없이 기존 계정으로 서비스 이용이 가능하다 사용자는 비밀번호를 서비스에 제공하지 않아도 된다

앞에서 설명한 것과 동일하다

OIDC

OAuth 2.0프레임워크를 기반 OpenID Connect protocol제공

 

아까 OAuth에서 볼수 없다 ID Token이 발급된다

ID Token은 언제 나올까?

사용자가 구글 로그인을 할때 데이터 접근 권한만 받는게 아니라 이사람이 누구인지까지 한번에 확인하고 싶을때

OIDC를 사용한다

  • OIDC = OAuth 2.0 + ID Token
  • OIDC 방식으로 요청하면, 서버는 응답할 때 Access Token과 ID Token을 함께 보내줍니다.

이해하기 쉽게 비유를 들자면

 

  • OAuth 2.0 (기본 모델): 전화, 문자만 되는 피처폰. (목적: 데이터 접근 권한 부여)
  • OIDC (업그레이드 모델): 피처폰 기능에 '고성능 카메라'와 '신분증 앱'이 추가된 스마트폰. (목적: 권한 부여 + 사용자 인증)

 

차이점

1. OAuth2.0을 사용 할 경우 리소스 서버에서는 사용자 접근 권한만 확인 가능

2. OIDC 인증을 진행 할 경우 리소스 서버에서는 사용자 접근 권한 및 사용자 인증 가능

3. OIDC 인증 적용 할 경우 SSO 적용으로 개인 맞춤형 서비스 제공 가능.

출처: https://json8.tistory.com/196 [Jay Son 프로그램 놀이터:티스토리]

 

Port swigger풀어보기

1.

•Redirect_url: 코드를 받을 주소
•Response_type: 동작 방식 선언
•Scope: 범위
•State: 난수 토큰
각각 이렇게 의미한다

 

실제 포트스위거 랩을 봐보자

버프슈트로 중간에 보았다 client_id와 redirect_url, response_type과 nonce, scope값이 있다

 

wiener와 peter로 로그인 하였더니 username과 password가 다음과 같이 담기게 되었다

wiener계정으로 로그인이 가능하엿다

post요청이 하나 있엇다

그래서 여기서 email을 carlos@carlos-montoya.net.
로 변경을 하였고

그결과 문제를 해결 할 수 있엇다 간단히 포트 스위거 해결법을 알아가는 느낌?

 

해결~~

 

2.

이 문제를 풀다보면 url이랑 uri의 차이점이 궁금해진다.

 

 

  • URI가 URL을 포함하는 상위 개념 위 그림을 보면 알 수 있다 모든 URL은 URI에 속하지만 모든 URI가 URL인 것은 아니다
  • 사람으로 비유하자면 URI는 주민등록번호나 이름처럼 그 사람을 특정할 수 있는 식별 정보이고, URL은 그 사람을 실제로 찾아갈 수 있는 구체적인 집 주소(도로명 주소)에 해당

여기서는 Redirect_url을 건드려야 한다!!!!!

즉 공격자인 나에게 오게 하는것이다 

참고로

 

참고로 /oauth에 대해 건드릴 것이기에 url에 /oauth가 있는것만 확인하면 된다.

 

wiener로 로그인을 해본다

첫번째 /oauth에서 온것을 확인해보자

get으로 id와 redirect_uri와 response_type scope(범위)를 받는다

 

두번째로 온 /oauth이다 

 

첫번째로 get으로 받는 /oauth이다 

여기서 할 수 있는 생각은 uri를 공격자인 나에게 하면 중간에 채갈 수 있지 않을까 라는 생각이다

https://oauth-0ae000480359573180143d1102ad00fb.oauth-server.net/auth?client_id=j3u6n3nkthiurmbnwpekk&redirect_uri=https://0a4d0091031657f780c53f9d00400079.web-security-academy.net/oauth-callback&response_type=code&scope=openid%20profile%20email

여기에는 exploit서버가 존재한다

즉 uri를 url로 변경하자

 

exploit서버에서 다음과 같이 보낸다

 

code가 나에게 온것을 확인할 수 있다

이 code는 admin의 code일것 따라서 중간에 버프 슈트로 이거를 입력 하면 되지않을까 하는 생각이다

 

 

admin의 계정으로 로그인 하기 성공

성공

 

이 문제의 공격은 code의 도착지 url을 바꿔서 공격이 가능 하였따

 

2. Redirect URI 변조 (인가 코드 탈취)

원리

피해자가 정상적으로 발급받은 인가 코드를 공격자 서버로 빼돌려, 공격자가 피해자 계정으로 로그인하는 취약점입니다. 로그인의 주도권이 피해자에게 있으며, 공격자는 마지막 도착지만 가로챕니다.

 시나리오

  • 공격자는 클라이언트 앱의 OAuth 로그인 요청 URL에서 redirect_uri 파라미터를 공격자의 서버 주소로 조작합니다.
  • 조작된 링크를 피해자에게 전달하여 클릭을 유도합니다.
  • 피해자가 링크를 클릭해 자신의 계정으로 정상적으로 로그인을 완료합니다.
  • 인증 서버는 조작된 redirect_uri(공격자 서버)로 피해자의 인가 코드를 전송합니다.
  • 공격자는 받은 인가 코드를 이용해 피해자의 계정으로 서비스에 로그인합니다.

대응 방안

  • 사전에 등록된 URI와 정확히 일치하는지 확인하는 화이트리스트(Exact match) 검증 로직을 구현해야 합니다.

3. State 검증 누락 (CSRF를 통한 계정 강제 연동)

원리

공격자가 자신의 소셜 계정으로 발급받은 인가 코드를 피해자의 세션에 억지로 주입하는 취약점입니다. 공격자가 미리 받아둔 코드를 이용해 피해자의 본 계정에 공격자의 소셜 계정을 강제로 묶는 것이 목적입니다.

시나리오

  • 공격자가 자신의 소셜 계정으로 로그인을 시도하여 코드를 발급받은 직후, 프록시 도구를 이용해 요청을 멈춰 잡습니다.
  • 공격자는 자신의 코드가 포함된 콜백 URL을 생성하여 피해자에게 전달하고 클릭을 유도합니다.
  • 해당 서비스에 이미 로그인되어 있던 피해자가 뭣 모르고 링크를 클릭합니다.
  • 피해자의 브라우저가 공격자의 코드를 서비스 서버에 대신 제출합니다.
  • 서버는 현재 로그인된 피해자의 계정에 전달받은 코드(공격자의 계정)를 연동해 버립니다.
  • 이후 공격자는 언제든 자신의 계정으로 로그인하여 피해자의 정보를 탈취하거나 악의적인 행위를 할 수 있습니다.

대응 방안

  • CSRF 공격을 방어하기 위해 state 파라미터를 반드시 사용해야 합니다.
  • state가 없으면 누가 Oauth 서버에 요청 및 응답을 하는지 판별할 수 없습니다.
  • 로그인 요청 시 클라이언트는 예측 불가능한 난수(state)를 생성하여 인증 서버로 보내고, 동일한 값을 사용자의 세션에 임시 저장합니다.
  • 인가 코드와 함께 state 값이 반환되면, 클라이언트는 반환된 값과 세션에 저장된 값이 일치하는지 검증하여 위조된 요청을 차단해야 합니다.