HTTPS : 웹 통신 사이 회선 보호
요청을 보내고, 응답을 받는 두 주체만 HTTP요청 및 응답을 읽을 수 있게 암호화
- MITM(Man-In-The-Middle)공격 방지
- HTTPS는 대칭키 암호화 방식과 비대칭키 암호화 방식의 장점만을 사용
- 대칭키 암호화
- 클라이언트와 서버가 동일한 키를 사용하여 암호화/복호화를 진행한다
- 키가 노출되면 매우 위험하지만 연산 속도가 빠르다
- 비대칭키 암호화
- 1개의 쌍으로 구성된 개인키와 공개키를 암호화/복호화 하는데 사용한다
- 공개키는 누구나 볼 수 있고 키가 노출되어도 비교적 안전하지만 연산 속도가 느리다
- 비대칭키 1 : Server 공개키(<-CA 비공개키로 암호화, Client에게 전달) + Server 비공개키
- 단일 서버의 비공개키가 뺏긴다면, 해당 서버인것 처럼 모든 요청 받을 수 있음
- 단일 서버의 비공개키 진짜 여부 인증 위해, CA를 통해 한번 더 암호화(인증)
- 웹 브라우저는 CA를 통해 해당 서버의 비공개키가 인증됐는지 확인, 신뢰
- CA 인증서는 인증받은 서버만 들고 있기 때문
- CA : SSL/TLS 인증서를 발급하는 기관, 신뢰할 수 있는 기관
- 목적 : 인증 기관에 의해 인증된 서버인지 = 인능 기관에 의해 암호화된 서버의 공개키인지
- 비대칭키 2 : CA 비공개키 + CA 공개키(CA가 브라우저에 제공)
- 대칭키 : 클라이언트와 서버 서로만 알 수 있는 대칭키로 통신
CORS
CORS는 웹 브라우저에서만의 정책
웹 브라우저에서 자바스크립트 AJAX를 통한 CSRF 방지
- 웹 브라우저 : 네이티브 앱에서는 CORS가 적용되지 않기에 방어되지 않음
- CSRF 방어하기 위해 XSRF Token 사용(임의 난수+세션 활용)
- 자바스크립트 AJAX : 웹 브라우저에서 AJAX가 아닌 FORM을 통한 POST요청에는 CORS정책이 적용되지 않아 여전히 XSRF이슈
웹 브라우저 비동기 지원 AJAX
- FORM(Synchronous) : 보내고 끝(HTML 페이지 반환 = 페이지 리렌더O)
- AJAX(Asynchronous JavaScript and XML) = XHR(XML 객체 반환 = 페이지 리렌더X)
- 비동기 = XHR 객체 활용 시 서버에 데이터를 요청하거나, 데이터를 전송받을 수 있다.
- 즉, 웹 페이지 전체를 다시 로딩하지 않고 일부분만을 갱신할수 있게 된다
- 현재 대부분의 주요 웹 브라우저는 서버에 데이터를 요청하기 위한 XHR객체 활용
웹 브라우저 보안 정책 SOP(Same-Origin Policy)
웹 브라우저에서 HTTP Resource를 갖고오기 위한 모든 HTTP요청은 기본적으로 SOP를 갖는다
- Origin의 의미 : 예시)
https://www.hello.com:8080
- Scheme = https://
- Host = www.hello.com
- Port = 8080
- 하지만 웹 브라우저는 이미지, 아이콘처럼 외부에서 정보를 가져오는 경우가 있다
- SOP는 'Same-Origin' 이름과 달리 부분적으로 Cross-Origin도 허용
- Cross-Origin '가져오기' : 의도된 조회 - 서버 상태 변경 불가
- Cross-Origin '제출하기'(FORM) : 개발자가 설계한 의도된 제출 = 의도된 서버 상태 변경
- Cross-Origin '요청하기(AJAX - 예,POST) : 서버 상태 변경 가능 -> SOP에서 불허
- Cross-Origin에 대한 AJAX는 Cross-Origin 서버 상태를 바꿀 수 있는 보안 위험성 존재
SOP 보완 정책 = CORS(Cross Origin Resource Policy)
- AJAX는 표준 기술이 아님에도 사실상 표준으로써 AJAX를 막게되면 모든 API 호출 불가
- SOP를 보완하며 AJAX를 부분적으로 허용할만한 추가 정책 필요
= AJAX는 CORS에 맞을시에만 조건부 허용
- 브라우저에서 처리하는 것이기에 서버-서버 통신시에는 CORS 이슈는 전혀 발생하지 않는다
CORS 서버 측 적용 방법
서버는 브라우저로부터 어떤 요청만 받을지 3가지 CORS 헤더 설정을 통해 웹 브라우저가 호출가능한 요청을 제약할 수 있다
- 허용된 ORIGIN(예, a.com)
- Origin(브라우저) - 브라우저가 요청할 때 보낸다
- Access-Control-Allow-Origin(서버)
- 허용된 Method(예, GET, HEAD만 허용하고 POST 외 제외)
- Access-Control-Request-Method(브라우저) - 요청 시 보냄
- Access-Control-Allow-Method(서버)
- 허용된 Header
- Access-Control-Request-Headers(브라우저) - 요청 시 보냄
- Access-Control-Allow-Headers
브라우저는 서버에서 설정한 위 3가지 CORS 설정을 알기 위해서 서버에게 호출하여 알아낸다
- Simple Request - 서버 상태 조회 : GET, HEAD
- 허용된 Origin 체크 절차
- 브라우저가 서버에게 원 요청을 보내면
- 서버는 "결과"와 함께 "CORS 헤더"를 같이 보내준다
- 브라우저는 "CORS 헤더"가 요청과 부합하지 않으면, 반환 결과를 폐기한다
- Preflight Request - 서버 상태 변경 : POST, PATCH, PUT & GET, HEAD + 커스텀 헤더
- 허용된 Origin 체크 + 허용된 Method 체크 + 허용된 Header 체크 절차
- 브라우저가 서버에게 임시 요청을 보내면 = Preflight(OPTION)
- 서버는 "CORS 헤더"만 보내준다
- 브라우저는 "CORS 헤더"가 요청과 부합하지 않으면, 원 요청을 보내지 않는다