본문 바로가기
IT

OAuth 2.0 보안 취약점: CSRF, Clickjacking 공격 방지 전략 2026

by IT박사 2026. 5. 16.

OAuth 2.0은 우리 서비스와 다른 서비스를 연결하는 '열쇠'와 같습니다. 이 열쇠를 안전하게 관리하지 못하면 큰 문제가 발생할 수 있죠. 이번 글에서는 OAuth 2.0의 보안 취약점을 짚어보고, 특히 CSRF와 Clickjacking 공격을 막는 실질적인 방법들을 자세히 살펴보겠습니다.

1. API 보안, 왜 OAuth 2.0에 주목해야 할까?

API 보안은 현대 웹 및 모바일 애플리케이션 개발에서 중요한 고려 사항입니다. OAuth 2.0은 API 접근 권한을 안전하게 위임하는 데 널리 사용되는 인증 프로토콜입니다. 이 프로토콜은 사용자 인증 정보를 직접 공유하지 않고도 애플리케이션이 제한된 액세스 권한을 얻을 수 있도록 합니다. OAuth 2.0의 중요성이 커짐에 따라, 이 프로토콜의 보안 취약점을 이해하고 적절한 대응 방안을 마련하는 것이 필수적입니다.

본 글에서는 OAuth 2.0의 주요 보안 취약점, 특히 CSRF(Cross-Site Request Forgery) 및 Clickjacking 공격에 초점을 맞춥니다. 이러한 공격의 원리를 설명하고, 실제 발생 가능한 시나리오를 제시합니다. 또한, 이러한 공격을 효과적으로 방지하기 위한 전략과 구현 방법을 상세히 안내합니다.

OAuth 2.0을 사용하는 개발자와 시스템 관리자는 이 글을 통해 API 보안을 강화하고 사용자 데이터를 보호하는 데 필요한 지식을 얻을 수 있습니다. 구체적인 방어 전략을 통해 실제 공격 시나리오에 효과적으로 대응할 수 있도록 돕는 것이 목표입니다. 따라서 안전한 API 개발 및 운영에 기여할 수 있을 것입니다.

→ 1.1 OAuth 2.0의 역할과 중요성

OAuth 2.0은 다양한 애플리케이션과 서비스 간의 안전한 상호 작용을 가능하게 합니다. 예를 들어, 사용자는 특정 웹사이트에 로그인할 때 자신의 Google 계정을 사용하여 인증할 수 있습니다. 이 과정에서 웹사이트는 사용자의 Google 계정 비밀번호를 알 필요 없이, Google로부터 제한적인 접근 권한을 위임받습니다. 이러한 방식은 사용자 경험을 향상시키고 보안 위험을 줄이는 데 기여합니다.

하지만 OAuth 2.0 프로토콜 자체에도 취약점이 존재하며, 이를 간과할 경우 심각한 보안 문제로 이어질 수 있습니다. 따라서 OAuth 2.0을 올바르게 이해하고 구현하는 것이 중요합니다. 다음 섹션에서는 OAuth 2.0의 구체적인 취약점과 그 대응 방안에 대해 자세히 살펴보겠습니다.

2. OAuth 2.0 핵심: 인증과 권한 부여 완벽 해부

OAuth 2.0은 인증(Authentication)과 권한 부여(Authorization)라는 두 가지 핵심 개념을 분리하여 API 보안을 강화합니다. 인증은 사용자가 누구인지 확인하는 과정입니다. 권한 부여는 사용자가 특정 리소스에 접근할 수 있는 권한을 부여하는 과정입니다. 이 두 가지 과정을 통해 OAuth 2.0은 사용자 경험을 향상시키고, 보안성을 높이는 데 기여합니다.

인증 과정은 주로 사용자 ID와 비밀번호, 또는 소셜 로그인 등을 통해 이루어집니다. OAuth 2.0에서는 사용자의 인증 정보를 직접 저장하지 않습니다. 대신, 인증 서버를 통해 사용자를 인증하고, 권한 부여 서버에서 접근 토큰(Access Token)을 발급합니다. 접근 토큰은 클라이언트 애플리케이션이 API에 접근할 때 사용하는 일종의 '열쇠' 역할을 합니다.

권한 부여는 사용자가 클라이언트 애플리케이션에게 특정 API에 대한 접근 권한을 위임하는 과정입니다. 예를 들어, 사용자가 사진 공유 앱에 자신의 구글 포토 앨범에 접근할 수 있는 권한을 부여하는 경우가 있습니다. 이 때, OAuth 2.0은 사용자의 동의를 얻어 접근 토큰을 발급하고, 사진 공유 앱은 이 토큰을 사용하여 구글 포토 API에 접근합니다.

→ 2.1 OAuth 2.0 주요 구성 요소

OAuth 2.0은 여러 구성 요소로 이루어져 있으며, 각 구성 요소는 특정 역할을 수행합니다. 클라이언트(Client)는 사용자를 대신하여 API에 접근하는 애플리케이션입니다. 리소스 서버(Resource Server)는 보호된 사용자 리소스를 호스팅하는 서버입니다. 권한 부여 서버(Authorization Server)는 접근 토큰을 발급하는 서버입니다. 마지막으로, 리소스 소유자(Resource Owner)는 보호된 리소스의 소유자, 즉 사용자를 의미합니다.

이러한 구성 요소들이 상호 작용하여 안전한 API 접근을 보장합니다. 클라이언트는 권한 부여 서버에 권한을 요청하고, 사용자는 권한 부여 서버에서 클라이언트에게 권한을 위임합니다. 권한 부여 서버는 접근 토큰을 발급하고, 클라이언트는 이 토큰을 사용하여 리소스 서버에 접근합니다. 이 과정에서 사용자의 인증 정보는 클라이언트에게 노출되지 않습니다.

예를 들어, 사용자가 'ABC 지도' 앱을 통해 자신의 위치 정보를 친구들과 공유하고자 할 때, 'ABC 지도' 앱은 OAuth 2.0을 사용하여 사용자의 위치 정보 접근 권한을 요청합니다. 사용자는 권한 부여 서버에서 'ABC 지도' 앱에게 위치 정보 접근 권한을 부여하고, 'ABC 지도' 앱은 접근 토큰을 획득하여 위치 정보 API에 접근합니다. 이처럼 OAuth 2.0은 사용자 중심의 안전한 API 접근을 가능하게 합니다.

📌 핵심 요약

  • ✓ ✓ OAuth 2.0은 인증과 권한 부여 분리
  • ✓ ✓ 접근 토큰은 API 접근 '열쇠' 역할 수행
  • ✓ ✓ 클라이언트는 사용자를 대신해 API 접근
  • ✓ ✓ 권한 부여 서버가 접근 토큰을 발급합니다

3. CSRF 공격 완벽 차단: 5가지 강력 대응 전략

CSRF(Cross-Site Request Forgery) 공격은 사용자가 자신의 의도와 다르게 웹 사이트에 요청을 보내도록 만드는 공격입니다. 공격자는 사용자의 권한을 도용하여 원치 않는 작업을 수행할 수 있습니다. 따라서 CSRF 공격에 대한 효과적인 대응 전략은 웹 애플리케이션 보안에 필수적입니다.

CSRF 공격은 사용자가 인증된 상태에서 악성 웹 사이트를 방문했을 때 발생합니다. 이 웹 사이트는 사용자의 브라우저가 대상 웹 사이트에 악성 요청을 보내도록 유도합니다. 대상 웹 사이트는 이 요청이 사용자의 정상적인 요청인 것으로 오인하여 작업을 수행합니다.

→ 3.1 1. SameSite 쿠키 설정

SameSite 쿠키는 CSRF 공격을 완화하는 효과적인 방법 중 하나입니다. SameSite 쿠키는 쿠키가 전송될 수 있는 컨텍스트를 제한합니다. Strict, Lax, None 세 가지 속성 값을 가질 수 있습니다.

Strict 속성은 쿠키가 동일한 사이트 내의 요청에만 전송되도록 합니다. Lax 속성은 GET 요청과 같이 안전한 방식으로 작동하는 요청에 대해서만 쿠키를 전송합니다. None 속성은 쿠키가 모든 요청에 전송되도록 하지만, Secure 속성과 함께 사용하여 HTTPS 연결에서만 전송되도록 해야 합니다.

→ 3.2 2. CSRF 토큰 사용

CSRF 토큰은 서버에서 생성되어 클라이언트에게 전달되는 고유한 값입니다. 클라이언트는 폼 제출 또는 API 요청 시 이 토큰을 함께 전송해야 합니다. 서버는 요청을 처리하기 전에 토큰의 유효성을 검사합니다.

CSRF 토큰은 예측 불가능해야 하며, 각 사용자 세션마다 고유해야 합니다. 토큰은 숨겨진 필드나 HTTP 헤더에 포함될 수 있습니다. 토큰 검증 실패 시, 서버는 요청을 거부하고 오류 메시지를 반환해야 합니다.

이중 제출 쿠키 방식은 CSRF 토큰과 유사하지만, 서버 측에 상태를 저장하지 않습니다. 서버는 쿠키에 임의의 값을 설정하고, 동일한 값을 요청 파라미터에도 포함시킵니다. 클라이언트는 쿠키 값과 요청 파라미터 값을 비교하여 일치하는지 확인합니다.

이 방식은 서버 측에 상태를 저장할 필요가 없어 확장성이 뛰어나지만, XSS(Cross-Site Scripting) 공격에 취약할 수 있습니다. 따라서 XSS 공격 방지 대책과 함께 사용하는 것이 좋습니다.

→ 3.4 4. Referer 헤더 검사

Referer 헤더는 HTTP 요청에 포함된 헤더로, 요청이 시작된 페이지의 URL을 나타냅니다. 서버는 Referer 헤더를 검사하여 요청이 예상된 출처에서 왔는지 확인할 수 있습니다. 하지만 Referer 헤더는 위조될 수 있으며, 모든 브라우저에서 항상 제공되는 것은 아니므로, 완벽한 방어 수단은 아닙니다.

따라서 Referer 헤더 검사는 다른 CSRF 방어 기법과 함께 사용하는 것이 좋습니다. 예를 들어, Referer 헤더가 비어 있거나 예상되지 않은 도메인을 가리키는 경우 요청을 거부할 수 있습니다.

→ 3.5 5. 사용자 상호 작용 요구

중요한 작업을 수행하기 전에 사용자에게 추가적인 상호 작용을 요구하는 것은 CSRF 공격을 방지하는 효과적인 방법입니다. 예를 들어, 비밀번호 변경, 계정 삭제와 같은 작업 전에 비밀번호를 다시 입력하도록 요구할 수 있습니다.

또 다른 방법은 CAPTCHA(Completely Automated Public Turing test to tell Computers and Humans Apart)를 사용하는 것입니다. CAPTCHA는 사용자가 로봇이 아닌 사람인지 확인하는 데 사용됩니다. 이러한 방법들은 공격자가 자동화된 스크립트를 사용하여 CSRF 공격을 수행하는 것을 어렵게 만듭니다.

4. Clickjacking 방어: X-Frame-Options 설정의 중요성

Clickjacking은 사용자가 인지하지 못한 채 악성 웹 사이트에서 의도치 않은 작업을 수행하도록 유도하는 공격입니다. 공격자는 악성 웹 사이트에 대상 웹 사이트를 <iframe>으로 삽입합니다. 사용자가 인지하지 못한 채 클릭을 유도하여 계정 설정 변경, 구매 등의 행위를 수행하게 됩니다. X-Frame-Options HTTP 응답 헤더는 이러한 Clickjacking 공격으로부터 웹 사이트를 보호하는 중요한 메커니즘입니다.

X-Frame-Options 헤더는 웹 브라우저에게 해당 페이지를 <iframe>, <frame>, <object> 태그 내에 표시할 수 있는지를 제어합니다. 이 헤더를 올바르게 설정하면, 공격자가 사용자의 웹 페이지를 자신의 웹 페이지에 삽입하여 Clickjacking 공격을 시도하는 것을 방지할 수 있습니다. 따라서 X-Frame-Options 헤더를 설정하는 것은 웹 애플리케이션 보안에 필수적인 요소입니다.

→ 4.1 X-Frame-Options 헤더의 값

X-Frame-Options 헤더는 다음과 같은 세 가지 값을 가질 수 있습니다.

  • DENY: 페이지를 어떤 프레임에서도 표시하지 않습니다. 이는 가장 강력한 Clickjacking 방어 방법입니다.
  • SAMEORIGIN: 페이지를 동일한 출처(origin)의 프레임 내에서만 표시합니다.
  • ALLOW-FROM uri: 지정된 URI에서만 페이지를 프레임 내에 표시합니다. (최신 브라우저에서는 지원이 중단되었을 수 있습니다.)

대부분의 경우 DENY 또는 SAMEORIGIN이 적절한 선택입니다. 만약 웹 페이지가 다른 도메인의 프레임 내에서 정상적으로 작동해야 하는 특별한 이유가 없다면, DENY를 사용하는 것이 가장 안전합니다. SAMEORIGIN은 동일한 도메인 내의 다른 페이지에서 iframe을 사용해야 하는 경우에 유용합니다.

→ 4.2 X-Frame-Options 설정 예시

웹 서버 설정에서 X-Frame-Options 헤더를 설정할 수 있습니다. 예를 들어, Apache 웹 서버에서는 다음과 같이 설정할 수 있습니다.


Header always set X-Frame-Options "DENY"

Nginx 웹 서버에서는 다음과 같이 설정할 수 있습니다.


add_header X-Frame-Options "DENY";

이 설정을 통해 웹 사이트는 Clickjacking 공격으로부터 보호됩니다. X-Frame-Options 헤더 설정은 간단하지만 효과적인 보안 방법입니다.

적절한 X-Frame-Options 헤더 설정을 통해 Clickjacking 공격을 효과적으로 방어할 수 있습니다. 웹 애플리케이션 보안을 강화하기 위해 X-Frame-Options 헤더를 설정하는 것을 권장합니다. 또한, Content Security Policy (CSP)의 frame-ancestors 지시어를 사용하여 더 강력한 Clickjacking 방어를 구현할 수도 있습니다.

📊 X-Frame-Options 설정

설명 보안 강도 사용 시나리오
DENY 모든 프레임 거부 최고 민감 정보 페이지
SAMEORIGIN 동일 출처만 허용 높음 대부분 웹 페이지
ALLOW-FROM uri 특정 URI만 허용 낮음 제한적 사용 (지원 중단 가능성)
미설정 프레임 제한 없음 최저 Clickjacking에 취약

5. 토큰 탈취 예방: 안전한 저장 및 관리 모범 사례

OAuth 2.0 환경에서 토큰 탈취는 심각한 보안 위협입니다. 토큰이 탈취되면 공격자는 사용자를 사칭하여 API에 접근할 수 있습니다. 따라서 토큰을 안전하게 저장하고 관리하는 것은 매우 중요합니다.

토큰을 안전하게 저장하기 위한 첫 번째 단계는 암호화입니다. 저장 시에는 AES-256과 같은 강력한 암호화 알고리즘을 사용해야 합니다. 또한, 토큰을 저장하는 저장소 자체도 안전하게 보호해야 합니다.

→ 5.1 안전한 저장소 선택

토큰을 저장하는 안전한 저장소를 선택하는 것은 매우 중요합니다. 서버 측에서는 하드웨어 보안 모듈(HSM)이나 보안 enclave를 사용하는 것이 좋습니다. 클라이언트 측에서는 운영체제가 제공하는 보안 저장소를 활용할 수 있습니다.

예를 들어, iOS에서는 Keychain을, Android에서는 KeyStore를 사용할 수 있습니다. 이러한 저장소는 운영체제 수준에서 보안을 제공하므로 비교적 안전합니다. 또한, 토큰을 평문으로 저장하는 것은 절대적으로 피해야 합니다.

→ 5.2 토큰 관리 모범 사례

토큰 관리 측면에서는 짧은 유효 기간을 설정하는 것이 좋습니다. 유효 기간이 짧으면 토큰이 탈취되더라도 피해를 최소화할 수 있습니다. 또한, Refresh Token Rotation을 적용하여 토큰 탈취 시도를 무효화할 수 있습니다.

Refresh Token Rotation은 Refresh Token을 사용하여 새로운 Access Token과 Refresh Token을 발급받을 때, 기존 Refresh Token을 폐기하는 방식입니다. 만약 공격자가 Refresh Token을 탈취하더라도, 해당 토큰은 이미 폐기되었으므로 사용할 수 없습니다. 따라서 Refresh Token Rotation은 토큰 탈취로 인한 피해를 줄이는 데 효과적입니다.

또한, 토큰을 사용하는 API 호출 시에는 TLS (Transport Layer Security)를 사용하여 통신을 암호화해야 합니다. 이를 통해 중간자 공격(Man-in-the-Middle attack)으로부터 토큰을 보호할 수 있습니다. TLS 1.3 이상의 최신 버전을 사용하는 것이 좋습니다.

6. OAuth 2.0 보안 강화: 실천을 위한 핵심 체크리스트

OAuth 2.0을 안전하게 구현하기 위해서는 체크리스트를 활용하여 보안 설정을 점검하는 것이 중요합니다. 다음은 OAuth 2.0 환경에서 발생할 수 있는 보안 취약점을 예방하고 시스템을 강화하기 위한 핵심 점검 사항입니다.

→ 6.1 CSRF 방지 점검

CSRF 공격은 사용자의 의도와 다른 요청을 서버로 전송하여 악의적인 행위를 수행하는 공격입니다. 이를 방지하기 위해 다음 사항을 점검해야 합니다.

  • State 파라미터 사용: 각 요청에 예측 불가능한 임의의 값을 포함시켜 응답 시 검증합니다.
  • Double Submit Cookie 패턴 적용: 쿠키와 요청 파라미터에 동일한 값을 설정하고 서버에서 검증합니다.
  • Referer 헤더 검증: 요청이 발생한 출처를 확인하여 신뢰할 수 없는 출처의 요청을 거부합니다.

예를 들어, 사용자가 웹 사이트 A에 로그인한 상태에서 공격자가 웹 사이트 B를 통해 웹 사이트 A에 대한 요청을 위조하는 경우를 방지할 수 있습니다.

→ 6.2 Clickjacking 방지 점검

Clickjacking은 공격자가 웹 페이지를 iframe 내에 삽입하여 사용자가 의도치 않은 클릭을 유도하는 공격입니다. X-Frame-Options 헤더를 설정하여 방지할 수 있습니다.

  • X-Frame-Options 헤더 설정: DENY, SAMEORIGIN 옵션을 사용하여 iframe 삽입을 제어합니다.
  • Content Security Policy (CSP) 헤더 설정: frame-ancestors 지시어를 사용하여 허용된 출처를 명시합니다.

X-Frame-Options 헤더를 SAMEORIGIN으로 설정하면 동일한 출처의 웹 페이지만 iframe에 포함될 수 있도록 제한합니다.

→ 6.3 토큰 관리 점검

토큰 탈취는 OAuth 2.0 환경에서 가장 심각한 보안 위협 중 하나입니다. 토큰을 안전하게 저장하고 관리하기 위해 다음 사항을 점검해야 합니다.

  • HTTPS 사용: 모든 통신 채널에서 암호화를 적용하여 토큰이 네트워크를 통해 노출되는 것을 방지합니다.
  • 토큰 암호화 저장: 데이터베이스에 토큰을 저장할 때 암호화하여 저장합니다.
  • 짧은 토큰 유효 기간 설정: 토큰의 유효 기간을 최소화하여 토큰 탈취 시 피해를 줄입니다.
  • Refresh Token 로테이션: Refresh Token을 주기적으로 갱신하여 보안성을 강화합니다.

2026년에는 토큰의 유효 기간을 1시간 이내로 설정하고, Refresh Token을 1주일마다 로테이션하는 것이 일반적인 보안 권장 사항으로 자리 잡았습니다.

→ 6.4 일반적인 보안 강화

OAuth 2.0을 사용하는 애플리케이션의 보안을 강화하기 위한 일반적인 조치도 중요합니다.

  • 최신 라이브러리 사용: OAuth 2.0 관련 라이브러리를 최신 버전으로 유지하여 알려진 취약점에 대한 패치를 적용합니다.
  • 입력 유효성 검사: 모든 입력 값에 대한 유효성 검사를 수행하여 XSS (Cross-Site Scripting) 및 SQL Injection 공격을 방지합니다.
  • 정기적인 보안 점검: 애플리케이션의 보안 상태를 정기적으로 점검하고, 발견된 취약점에 대해 신속하게 대응합니다.

예를 들어, OWASP (Open Web Application Security Project)의 가이드라인을 참고하여 웹 애플리케이션의 보안 취약점을 점검할 수 있습니다.

오늘부터 안전한 API 개발 시작하세요

OAuth 2.0 보안 취약점과 CSRF, Clickjacking 방지 전략을 통해 API 보안을 한층 강화할 수 있습니다. 오늘 배운 내용을 바탕으로 더욱 안전하고 신뢰할 수 있는 애플리케이션을 개발하고, 사용자 데이터를 안전하게 보호하는 데 힘써 보세요. 작은 실천이 큰 보안 성과로 이어질 것입니다.

📌 안내사항

  • 본 콘텐츠는 정보 제공 목적으로 작성되었습니다.
  • 법률, 의료, 금융 등 전문적 조언을 대체하지 않습니다.
  • 중요한 결정은 반드시 해당 분야의 전문가와 상담하시기 바랍니다.