요청을 보내고 응답을 받는 두 주체(End-to-End)만 HTTP 요청 및 응답을 읽을 수 있게 암호화 한 것으로 MITM 공격을 방지할 수 있다.
MITM 공격은 해커가 두 주체 사이의 통신을 가로채거나 조작하는 것으로 MITM 공격 종류는 아래와 같다.
💡 MITM 공격 종류
스니핑 : 공격자가 네트워크 트래픽을 통해 몰래 도청, 엿보는 공격 방식
패킷 주입 : 공격자가 네트워크 내의 패킷을 가로채거나 조작하여 자신이 원하는 데이터를 주입하는 공격 방식. DHCP/ARP로 LAN내 컴퓨터 인지 후 패킷 대신 받아 조작 주입
ARP Spoofing/Poisoning : 네트워크에서 ARP 프로토콜을 조작하여 공격자가 피해자의 MAC 주소를 자신의 MAC 주소로 위조하여 트래픽을 가로챔
세션 하이재킹 : 사용자가 웹사이트에 로그인한 세션 탈취하여 공격자가 그 사용자인 척 행세하는 공격 방식
SSL 스트리핑 : HTTPS 연결을 HTTP로 다운그레이드 시켜 암호화되지 않은 데이터를 가로채는 공격 방식
#2. HTTPS 보안 적용 방식
HTTPS는 대칭키 암호화 방식과 비대칭키 암호화 방식의 장점만을 사용한다.
◼︎ 대칭키 암호화 방식
: 하나의 키를 서버와 클라이언트가 공유. 이 키를 통해 데이터를 암호화 및 복호화
: 연산 속도가 매우 빠르지만, 키가 노출되면 매우 위험
◼︎ 비대칭키 암호화 방식
: 공개키, 비공개키 두 개의 키로 구성
: 서버는 클라이언트에게 공개키를 전달하고, 클라이언트는 이 공개키를 사용해 데이터를 암호화. 암호화된 데이터를 서버만이 소유한 비공개키로만 복호화.
: 공개키는 누구나 볼 수 있으며 노출되어도 안전하지만 연산 속도가 느리다는 단점 존재
: 서버는 클라이언트에게 공개키를 그냥 전달하지 않고 CA로부터 인증 받은 후에 전달(클라이언트가 신뢰할 수 있는 서버와 통신하고 있는지 확인하기 위한 절차)
HTTPS가 비대칭키와 대칭키 두 개 모두 활용하는 이유는 다음과 같다.
비대칭키 암호화 - 안전한 키 교환 : 클라이언트와 서버 간 대칭키(세션키)를 안전하게 공유하기 위해 사용
대칭키 암호화 - 빠른 데이터 전송 : 연산 속도 빨라 매번 클라이언트와 서버가 요청/응답 주고 받을 때 성능에 영향 주지 않음
#3. HTTPS 동작 원리
HTTPS는 2개의 비대칭키와 1개의 대칭키를 사용하여 동작한다.
◼︎ 2개의 비대칭키
서버의 비대칭키
서버의 공개키 : 서버는 자신의 공개키를 클라이언트에게 제공. 이때 CA의 비공개키로 암호화한 상태로 제공
서버의 비공개키 : 서버만이 가지고 있는키. 공개키로 암호화된 데이터를 복호화하는데 사용
CA의 비대칭키
CA의 공개키 : 클라이언트는 CA의 공개키를 통해 서버의 신뢰성 확인
CA의 비공개키 : CA의 비공캐키를 이용해 서버의 공개키를 암호화
◼︎ 1개의 대칭키(세션키)
: 실제 데이터 전송 시 사용되는 암호화 키로 클라이언트와 서버가 공유
: 비대칭키 암호화 과정을 통해 안전하게 교환된 후, 빠른 암호화 및 복호화가 필요할 때 사용
즉, 서버와 클라이언트는 비대칭키를 사용해 세션키를 생성하고 이 세션키로 암호화된 통신을 수행한다.
02. CORS : CSRF 부분 방지를 위한 웹 브라우저 정책
#1. CSRF (Cross-Site Request Forgery)
CSRF는 사용자가 의도하지 않은 요청이 다른 사이트로 전송되는 공격 방식이다.
주로 사용자의 권한을 이용해 공격자가 원하지 않는 작업을 수행하게 만든다.
웹 브라우저는 이런 CSRF 공격을 방지하기 위해 CORS, SOP 등의 정책을 도입하였다.
#2. CORS
CORS는 웹브라우저에서 AJAX를 통해 발생할 수 있는 CSRF 공격을 방지하는데 기여하는 정책이다.
💡 SOP(Same-Origin Policy) 웹브라우저 보안 정책
SOP는 웹브라우저의 기본 보안 정책으로, 다른 Origin에서 온 HTTP 요청을 제한한다. 하지만 SOP는 일부 예외를 허용한다.
Cross-Origin 가져오기 (<img/>, <script/>) : 이미지를 불러오거나 스크립트를 로드하는 경우, 서버의 상태를 변경하지 않으므로 허용
Cross-Origin 제출하기(FORM) : 의도된 제출은 서버 상태를 변경할 수 있으나, 개발자가 의도한 행동이므로 허용
Cross-Origin 요청하기(AJAX - POST, DELETE 등) : 서버 상태를 변경할 수 있어 SOP에서 기본적으로 허용하지 않음
💡 SOP를 보완하는 CORS 정책
CORS는 SOP의 한계를 보완하기 위해 만들어졌으며, 특히 AJAX를 통한 Cross-Origin 요청을 조건부로 허용하기 위한 정책이다.
AJAX를 통해 POST, DELETE 등의 요청을 다른 도메인(Cross-Origin)으로 보내는 경우 서버의 상태를 변경할 수 있었다. SOP는 이러한 Cross-Origin 요청을 기본적으로 차단하여 보안을 유지하지만, AJAX를 사용한 API 호출이 SOP에 의해 차단되면 프론트엔드와 백엔드 간의 데이터 통신이 불가능해진다. SOP에 의해 이러한 요청이 차단되면 개발이 불가능해지므로, AJAX 요청을 예외적으로 허용할 수 있는 정책이 필요했고, 이로 인해 등장한 것이 CORS이다.
CORS는 특정 조건 하에서 Cross-Origin 요청을 허용하여, 서버에서 CORS 설정을 통해 허용된 도메인만 AJAX 요청을 할 수 있게 된다.
CORS는 웹 브라우저에서만 적용되는 정책으로, 서버 간 통신에서는 SOP나 CORS 이슈가 발생하지 않는다.
React와 Spring을 함께 사용할 때 CORS 문제가 발생할 수 있으며, 이를 해결하기 위해 React에서 Proxy 설정을 하거나, Next.js를 도입하여 CORS 문제를 방지할 수 있다.
#3. CORS 서버 측 적용 방법
웹 서버는 CORS 헤더 설정을 통해 웹 브라우저의 어떤 요청을 허용할 지 결정한다. 서버 측에서 설정할 수 있는 CORS 관련 헤더는 아래와 같다.
💡 허용된 Origin
브라우저 : 요청 시 Origin 헤더를 포함하여 자신이 어떤 도메인에서 요청을 보내는지 서버에 알림
서버 : 응답 시 Access-Control-Allow-Origin 헤더를 통해 허용된 Origin을 명시
브라우저 : 서버 응답의 Access-Control-Allow-Origin 헤더와 자신이 보낸 Origin 헤더를 비교하여 유효성 검사를 수행
💡 허용된 Method
브라우저 : Access-Control-Request-Method 헤더를 사용해 어떤 HTTP 메서드를 사용하려는지 서버에 알림
서버 : 응답 시 Access-Control-Allow-Methods 헤더를 통해 허용된 HTTP 메서드를 명시
브라우저 : 서버 응답의 Access-Control-Allow-Methods 헤더와 자신이 보낸 Access-Control-Request-Method 헤더를 비교해 유효성 검사를 수행
💡 허용된 Header
브라우저 : Access-Control-Request-Headers 헤더를 사용해 요청에 포함될 추가 헤더를 서버에 알림
서버 : 응답시 Access-Control-Allow-Headers 헤더를 통해 허용된 헤더 목록을 명시
브라우저 : 서버 응답의 Access-Control-Allow-Headers 헤더와 자신이 보낸 Access-Control-Request-Headers 헤더 비교해 유효성 검사를 수행
< 자격증명과 관련된 CORS 설정 >
브라우저가 서버로 자격증명 정보를 함께 전송하려면 추가적인 설정이 필요하다.
이때 자격증명은 쿠키, 인증 헤더, TLS 클라이언트 인증 정보 등이 포함된다.
브라우저 설정 : fetch() API 사용시 credentials: "include" 옵션, XMLHttpRequest 사용시 withCredentials=true 옵션으로 설정 가능.
서버 설정 : Access-Control-Allow-Credentials 헤더를 true로 설정하여 자격증명이 포함된 요청을 허용 가능. 그러나 헤더에 *(모든 도메인 허용)을 사용할 수 없으며, 특정 Origin만 허용해야 함. Spring Security에서는 allowedOrigins("*")을 금지하고 있으며, 대신 allowOriginPatterns("*")를 사용할 것을 권장
#4. CORS 검증을 위한 요청
💡 Simple Request : 서버 상태 조회
서버 상태를 조회하기 위해 GET, HEAD 메서드를 사용하여 처리한다.
브라우저가 서버로 원 요청을 보낸다.
서버는 요청을 처리한 결과와 함께 CORS 헤더를 포함하여 응답한다.
브라우저는 서버로부터 받은 응답의 CORS 헤더를 확인한다.
만약 CORS 헤더가 요청의 Origin과 일치하지 않거나 허용되지 않은 Origin에서 요청한 경우, 브라우저는 서버의 응답 결과를 폐기한다.
💡 Preflight Request : 서버 상태 변경
주로 POST, PATCH, PUT 메서드 또는 GET, HEAD 메서드에 커스텀 헤더가 포함된 경우에 발생한다.
브라우저가 서버에게 Preflight 요청(OPTIONS)을 보낸다.
서버는 Preflight 요청에 대해 CORS 헤더만 포함된 응답을 보낸다.
브라우저는 서버로부터 받은 CORS 헤더를 확인하고, 원래의 요청이 서버에서 허용되는지 판단한다.
만약 CORS 헤더가 요청의 Origin, Method, Headers와 일치하지 않거나 허용되지 않는 경우, 브라우저는 원래의 요청을 보내지 않는다.
웹 보안 : HTTPS와 웹 브라우저에서의 CORS
01. HTTPS
#1. HTTPS
HTTPS는 SSL 또는 TLS 프로토콜을 통해 HTTP 보안을 강화한 것이다.
요청을 보내고 응답을 받는 두 주체(End-to-End)만 HTTP 요청 및 응답을 읽을 수 있게 암호화 한 것으로 MITM 공격을 방지할 수 있다.
MITM 공격은 해커가 두 주체 사이의 통신을 가로채거나 조작하는 것으로 MITM 공격 종류는 아래와 같다.
💡 MITM 공격 종류
#2. HTTPS 보안 적용 방식
HTTPS는 대칭키 암호화 방식과 비대칭키 암호화 방식의 장점만을 사용한다.
◼︎ 대칭키 암호화 방식
: 하나의 키를 서버와 클라이언트가 공유. 이 키를 통해 데이터를 암호화 및 복호화
: 연산 속도가 매우 빠르지만, 키가 노출되면 매우 위험
◼︎ 비대칭키 암호화 방식
: 공개키, 비공개키 두 개의 키로 구성
: 서버는 클라이언트에게 공개키를 전달하고, 클라이언트는 이 공개키를 사용해 데이터를 암호화. 암호화된 데이터를 서버만이 소유한 비공개키로만 복호화.
: 공개키는 누구나 볼 수 있으며 노출되어도 안전하지만 연산 속도가 느리다는 단점 존재
: 서버는 클라이언트에게 공개키를 그냥 전달하지 않고 CA로부터 인증 받은 후에 전달(클라이언트가 신뢰할 수 있는 서버와 통신하고 있는지 확인하기 위한 절차)
HTTPS가 비대칭키와 대칭키 두 개 모두 활용하는 이유는 다음과 같다.
#3. HTTPS 동작 원리
HTTPS는 2개의 비대칭키와 1개의 대칭키를 사용하여 동작한다.
◼︎ 2개의 비대칭키
◼︎ 1개의 대칭키(세션키)
: 실제 데이터 전송 시 사용되는 암호화 키로 클라이언트와 서버가 공유
: 비대칭키 암호화 과정을 통해 안전하게 교환된 후, 빠른 암호화 및 복호화가 필요할 때 사용
즉, 서버와 클라이언트는 비대칭키를 사용해 세션키를 생성하고 이 세션키로 암호화된 통신을 수행한다.
02. CORS : CSRF 부분 방지를 위한 웹 브라우저 정책
#1. CSRF (Cross-Site Request Forgery)
CSRF는 사용자가 의도하지 않은 요청이 다른 사이트로 전송되는 공격 방식이다.
주로 사용자의 권한을 이용해 공격자가 원하지 않는 작업을 수행하게 만든다.
웹 브라우저는 이런 CSRF 공격을 방지하기 위해 CORS, SOP 등의 정책을 도입하였다.
#2. CORS
CORS는 웹브라우저에서 AJAX를 통해 발생할 수 있는 CSRF 공격을 방지하는데 기여하는 정책이다.
💡 SOP(Same-Origin Policy) 웹브라우저 보안 정책
SOP는 웹브라우저의 기본 보안 정책으로, 다른 Origin에서 온 HTTP 요청을 제한한다. 하지만 SOP는 일부 예외를 허용한다.
💡 SOP를 보완하는 CORS 정책
CORS는 SOP의 한계를 보완하기 위해 만들어졌으며, 특히 AJAX를 통한 Cross-Origin 요청을 조건부로 허용하기 위한 정책이다.
AJAX를 통해 POST, DELETE 등의 요청을 다른 도메인(Cross-Origin)으로 보내는 경우 서버의 상태를 변경할 수 있었다. SOP는 이러한 Cross-Origin 요청을 기본적으로 차단하여 보안을 유지하지만, AJAX를 사용한 API 호출이 SOP에 의해 차단되면 프론트엔드와 백엔드 간의 데이터 통신이 불가능해진다. SOP에 의해 이러한 요청이 차단되면 개발이 불가능해지므로, AJAX 요청을 예외적으로 허용할 수 있는 정책이 필요했고, 이로 인해 등장한 것이 CORS이다.
CORS는 특정 조건 하에서 Cross-Origin 요청을 허용하여, 서버에서 CORS 설정을 통해 허용된 도메인만 AJAX 요청을 할 수 있게 된다.
CORS는 웹 브라우저에서만 적용되는 정책으로, 서버 간 통신에서는 SOP나 CORS 이슈가 발생하지 않는다.
React와 Spring을 함께 사용할 때 CORS 문제가 발생할 수 있으며, 이를 해결하기 위해 React에서 Proxy 설정을 하거나, Next.js를 도입하여 CORS 문제를 방지할 수 있다.
#3. CORS 서버 측 적용 방법
웹 서버는 CORS 헤더 설정을 통해 웹 브라우저의 어떤 요청을 허용할 지 결정한다. 서버 측에서 설정할 수 있는 CORS 관련 헤더는 아래와 같다.
💡 허용된 Origin
💡 허용된 Method
💡 허용된 Header
< 자격증명과 관련된 CORS 설정 >
브라우저가 서버로 자격증명 정보를 함께 전송하려면 추가적인 설정이 필요하다.
이때 자격증명은 쿠키, 인증 헤더, TLS 클라이언트 인증 정보 등이 포함된다.
#4. CORS 검증을 위한 요청
💡 Simple Request : 서버 상태 조회
서버 상태를 조회하기 위해 GET, HEAD 메서드를 사용하여 처리한다.
💡 Preflight Request : 서버 상태 변경
주로 POST, PATCH, PUT 메서드 또는 GET, HEAD 메서드에 커스텀 헤더가 포함된 경우에 발생한다.
'ASAC > 웹 기초 프로그래밍' 카테고리의 다른 글