한국어
  • oauth
  • oauth2
  • security

OAuth 2.1이 도착했습니다: 알아야 할 것들

OAuth 2.1 사양이 계획되었습니다. OAuth 2.0과 OAuth 2.1의 주요 차이점과 이를 Logto에 어떻게 적용했는지 살펴보겠습니다.

Simeng
Simeng
Developer

소개

OAuth 2.0 (RFC 6749)이 2012년에 등장한 이후로 웹 및 모바일 앱의 세계는 많이 변했습니다. 사람들은 데스크탑에서 모바일 장치로 이동하고 있으며, 싱글 페이지 애플리케이션(SPAs)이 대세가 되었습니다. 또한 새로운 프레임워크와 웹 기술이 많이 등장했습니다. 이러한 변화와 함께 보안 문제 또한 증가했습니다. 최신 웹 기술에 발맞추기 위해 인증 코드 교환에 대한 증거 키(PKCE)와 같은 새로운 RFC가 지속적으로 출시되어 OAuth 2.0을 강화하고 있습니다. 오늘날의 보안 요구 사항에 맞는 모든 모범 사례를 그룹화하는 것이 중요해졌으며, 그리하여 OAuth 2.1이 등장하게 되었습니다.

다가오는 OAuth 2.1에서 OAuth 작업 그룹은 모든 모범 사례와 보안 권장 사항을 단일 문서로 통합하는 것을 목표로 하고 있습니다. Logto에서는 OAuth의 최신 표준과 모범 사례를 적극 수용합니다. 이 글에서는 OAuth 2.0과 OAuth 2.1의 주요 차이점과 이를 Logto에 어떻게 적용했는지를 살펴보겠습니다.

모든 OAuth 클라이언트를 위한 PKCE 필수화

OAuth 2.1에서 가장 중요한 변화 중 하나는 인증 코드 플로우를 사용하는 모든 OAuth 클라이언트에 대해 PKCE(Proof Key for Code Exchange)가 필수로 요구된다는 점입니다. PKCE는 인증 코드 탈취 공격을 방지하는 보안 확장 기능입니다. 특히 클라이언트 비밀이 안전하게 저장될 수 없는 모바일 및 싱글 페이지 애플리케이션(SPAs)에 유용합니다.

OAuth 클라이언트는 비밀을 안전하게 저장할 수 있는지 여부에 따라 두 가지 유형으로 분류할 수 있습니다:

  1. 기밀 클라이언트: 서버 렌더링 웹 애플리케이션 및 웹 서버와 같이 비밀을 안전하게 저장할 수 있는 클라이언트입니다. 모든 인증 관련 요청은 서버 측에서 이루어지며 클라이언트 비밀이 노출될 위험이 낮습니다.

  2. 공용 클라이언트: 모바일 앱 및 SPAs와 같이 비밀을 안전하게 저장할 수 없는 클라이언트입니다. 클라이언트 비밀은 클라이언트 측 코드에서 쉽게 추출될 수 있으며 이를 공격자로부터 보호하기 어렵습니다.

공용 클라이언트의 경우 PKCE는 필수 보안 조치입니다. 이는 인증 코드를 시작한 클라이언트만이 인증 코드를 교환할 수 있도록 보장합니다.

PKCE는 무작위 코드 검증자와 코드 검증자를 기반으로 한 코드 챌린지를 생성하여 작동합니다. 코드 검증자는 인증 서버로 전송되며, 코드 챌린지는 인증 코드를 액세스 토큰으로 교환할 때 코드 검증자를 검증하는 데 사용됩니다.

OAuth 2.1에서는 비밀 유지 상태에 관계없이(기밀 또는 공용) 인증 코드 플로우를 사용하는 모든 OAuth 클라이언트에 대해 PKCE가 필수 사항이 됩니다. 이 중요한 변경 사항은 잠재적인 인증 코드 탈취 공격으로부터 모든 OAuth 클라이언트를 보호하도록 보장합니다.

Logto에서는 공용 및 기밀 클라이언트 모두에 대해 PKCE 검증 플로우가 자동으로 활성화됩니다.

SPAs와 모바일 앱의 경우, Logto에서 PKCE는 인증 코드 플로우를 보호하기 위한 필수 보안 조치입니다. 코드 챌린지가 없는 인증 요청은 Logto의 인증 서버에서 즉시 거부됩니다.

기밀 클라이언트(전통적인 웹 애플리케이션)와 관련하여 향상된 레거시 호환성을 위해 Logto는 인증 요청에서 코드 챌린지를 생략하는 것을 허용하지만, 공용 클라이언트의 모범 사례를 따르며 코드 챌린지를 포함하여 PKCE를 채택할 것을 강력히 권장합니다.

리다이렉트 URI의 일치하는 방식

리다이렉트 URI(Uniform Resource Identifier)는 인증 및 승인 과정이 완료된 후 사용자가 인증 서버에서 다시 리다이렉트되는 특정 엔드포인트 또는 URL입니다.

OAuth 플로우 동안 클라이언트 애플리케이션은 초기 인증 요청의 일부로 리다이렉트 URI를 포함합니다. 사용자가 인증 절차를 완료하면 인증 서버는 인증 코드를 포함한 응답을 생성하고 사용자를 지정된 리다이렉트 URI로 다시 리다이렉트합니다. 원래의 리다이렉트 URI와의 차이가 있으면 코드 또는 토큰이 유출될 수 있습니다.

리다이렉트 URI의 정확한 문자열 일치는 OAuth 2.0 Security Best Current Practices 섹션 4.1에서 처음 도입되었습니다. 이 방법은 리다이렉트 URI가 인증 서버에 등록된 것과 정확히 일치해야 함을 보장합니다. 등록된 리다이렉트 URI와 일치하지 않으면 오류 응답이 발생합니다.

우리는 리다이렉트 URI를 위해 와일드카드 일치 방식을 구현해달라는 많은 커뮤니티 요청을 받았습니다. 와일드카드 일치 방식은 다중 서브도메인이나 경로를 관리해야 하는 개발자들에게 편리함을 제공할 수 있지만 개방형 리다이렉트 공격과 같은 보안 위험을 초래할 수 있습니다. 리다이렉트 URI 검증이 없는 것으로 인해 발생할 수 있는 위험성에 대한 실질적인 예시는 A brief OAuth security recap 블로그에서 확인할 수 있습니다.

OAuth 2.1의 엄격한 보안 기준에 따라 Logto는 리다이렉트 URI의 정확한 문자열 일치 방식을 사용합니다. 이 결정은 OAuth 플로우의 보안을 최우선으로 고려한 것입니다. 와일드카드 일치 방식을 사용하는 대신 개발자가 모든 가능한 리다이렉트 URI를 Logto 인증 서버에 등록하도록 권장합니다. 이를 통해 리다이렉트 URI에 대한 철저한 검증이 이루어지며 잠재적인 보안 취약성을 완화할 수 있습니다.

암묵적 플로우가 사용 중단됨

OAuth 2.0의 암묵적 플로우는 사용자가 인증된 후 URL 프래그먼트에 바로 액세스 토큰을 반환하는 SPAs용으로 설계되었습니다. 이 방법은 추가적인 토큰 교환 단계를 피하면서 클라이언트가 즉시 토큰을 받을 수 있게 해주기 때문에 편리했습니다.

하지만 이 편리함은 단점도 가지고 있습니다. 액세스 토큰이 브라우저 히스토리, 리퍼러 헤더 또는 기타 수단을 통해 비허가된 당사자에게 노출될 수 있으며, 특히 액세스 토큰이 오랜 기간 동안 유효할 때 보안 침해 위험이 증가합니다. 예를 들어, 인증 요청이 악의적인 당사자에 의해 가로채졌을 때, 그들은 URL 프래그먼트에서 쉽게 액세스 토큰을 추출하여 사용자를 가장할 수 있습니다.

OAuth 2.0 Security Best Current Practices에서는 다음과 같이 명시되어 있습니다:

클라이언트는 암묵적 승인(response type "token") 또는 인증 응답에서 액세스 토큰을 발급하는 다른 응답 유형을 사용해서는 안 됩니다 (SHOULD NOT).

따라서 암묵적 플로우는 OAuth 2.1 사양에서 공식적으로 제거되었습니다.

Logto에서는 PKCE를 사용하는 인증 코드 플로우가 SPAs 및 모바일 애플리케이션에 유일하게 지원되는 플로우입니다. 인증 코드 플로우는 인증 코드를 교환하여 액세스 토큰을 얻는 더 안전한 방법을 제공합니다.

리소스 소유자 비밀번호 자격 증명(ROPC) 부여가 사용 중단됨

리소스 소유자 비밀번호 자격 증명(ROPC) 부여 유형은 클라이언트가 사용자의 사용자 이름과 비밀번호를 액세스 토큰으로 교환할 수 있도록 합니다. 이는 HTTP 기본 인증 또는 더 안전한 OAuth 토큰화된 플로우를 사용할 수 없는 레거시 애플리케이션을 지원하기 위해 OAuth 2.0 사양에서 처음 도입되었습니다.

ROPC 부여 유형은 OAuth 2.0 사양에서 보안 위험 때문에 권장되지 않는 것으로 표시되었습니다. 사용자의 자격 증명이 클라이언트 애플리케이션에 노출되므로 보안 침해 가능성이 있습니다. 클라이언트 애플리케이션은 사용자의 자격 증명을 저장할 수 있으며, 클라이언트가 손상되면 사용자의 자격 증명이 공격자에게 노출될 수 있습니다.

이후 OAuth 2.0 Security Best Current Practices의 섹션 2.4에서 ROPC 부여 유형의 사용 금지가 더욱 강조되었으며, OAuth 2.1 사양에서 ROPC 부여 유형이 제거되었습니다.

ROPC 부여 유형과 관련된 높은 보안 위험으로 인해 Logto는 이를 절대적으로 지원하지 않습니다. 여전히 레거시 애플리케이션에서 직접 사용자 자격 증명 플로우를 사용하고 있는 경우, 더 안전한 메소드로 마이그레이션하는 것을 강력히 권장합니다, 예를 들어 인증 코드 플로우 또는 클라이언트 자격 증명 부여로 전환하는 것입니다. Logto는 이러한 안전한 OAuth 플로우를 애플리케이션에 손쉽게 통합할 수 있도록 다양한 SDK와 튜토리얼을 제공합니다.

우리는 개발자들이 최고의 제품 경험을 위해 자체 사용자 로그인 인터페이스를 설계하거나 자체 호스팅하기를 원할 수 있다는 것을 이해합니다. Logto에서는 브랜드 설정 및 사용자 정의 CSS를 포함한 다양한 로그인 경험(SIE) 사용자 정의 옵션을 제공합니다. 또한 bring-your-own UI 및 직접 로그인과 같은 유연성을 제공하여 개발자가 로그인 인터페이스를 직접 제공하면서 OAuth 플로우의 보안을 유지할 수 있도록 하는 여러 진행 중인 프로젝트도 있습니다.

결론

OAuth 2.1은 현대적인 웹 및 모바일 앱 요구 사항을 수용하면서 오늘날의 보안 문제를 해결하기 위해 고안된 OAuth 프로토콜의 최신 업그레이드입니다. OAuth 작업 그룹은 최신 보안 표준 및 모범 사례를 충족하기 위해 OAuth 2.1을 활발히 업데이트하고 다듬고 있습니다. 최신 초안인 OAuth 2.1 11은 2024년 5월에 발표되었으며, 최종화를 향해 큰 진전을 이루었습니다. 광범위한 채택이 전망되면서, 우리는 모든 사람들이 OAuth 2.1에서 제시한 모범 사례를 따름으로써 보안을 강화하고 사용자 경험을 개선할 것을 강력히 권장합니다.