HTTPS는 기본 골격이나 사용 목적 등은 HTTP와 거의 동일하지만, 데이터를 주고 받는 과정에 ‘보안’ 요소가 추가되었다는 것이 가장 큰 차이점이다. HTTPS를 사용하면 서버와 클라이언트 사이의 모든 통신 내용이 암호화된다.
우리가 특정 파일에 암호를 걸 때처럼 어떤 키를 설정해서 잠금을 걸고, 풀 때에도 그것을 입력해서 푸는 것을 생각해보자. 간단하게 생각하면 웹 서버가 키 하나를 정해 페이지를 암호화해서 사용자의 웹 브라우저로 보내고, 웹 브라우저는 그 키를 이용해서 페이지를 복원하면 될 것이다. 그러나 웹 서버는 하나고 사용자는 불특정 다수이기 때문에 간단하지 않다. 그렇다고 키를 사용자들에게 막 줘버리면 아무나 암호화를 풀 수 있게 됨으로써 암호화의 의미가 없게 된다.
HTTPS는 위와 같은 상황에서 페이지를 암호화한 키가 그 페이지를 보는 특정 사용자에게만 알려지도록 한다. HTTPS는 SSL이나 TLS 프로토콜을 통해 세션 데이터를 암호화하며, 기본 TCP/IP 포트는 443이고, SSL 프로토콜 위에서 HTTPS 프로토콜이 동작한다.
암호화 방식
공개키 암호화 방식과 공개키의 느리다는 단점을 보완한 대칭키 암호화 방식을 함께 사용한다. 공개키 방식으로 대칭키를 전달하고, 서로 공유된 대칭키를 가지고 통신하게 된다.
공캐키 방식
A키로 암호화를 하면 B키로 복호화를 할 수 있다.
B키로 암호화를 하면 A키로 복호화를 할 수 있다.
둘 중 하나를 비공개키(Private Key) 혹은 개인키라 부르며, 이는 자신만 가지고 있고 공개되지 않는다.
나머지 하나를 공개키(Public Key)라고 부르며 타인에게 제공한다. 공개키는 유출이 되어도 비공개키를 모르면 복호화 할 수 없기 때문에 안전하다.
대칭키 방식
동일한 키로 암호화, 복호화가 가능하다.
대칭키는 매번 랜덤으로 생성되어 누출되어도 다음에 사용할 때는 다른 키가 사용되기 때문에 안전하다.
공개키보다 빠르게 통신할 수 있다.
이러한 SSL 방식을 적용하려면 인증서를 발급받아 서버에 적용시켜야 한다. 인증서는 사용자가 접속한 서버가 우리가 의도한 서버가 맞는지를 보장하는 역할을 한다. 인증서를 발급하는 기관을 CA(Certificate Authority)라고 부른다. 공인인증기관의 경우 웹 브라우저는 미리 CA 리스트와 함께 각 CA의 공개키를 알고 있다.
동작 과정
HTTPS의 장단점
웹사이트에서 XSS(Cross Site Scripting)공격을 막기 위해 만들어진 정책으로 아무나 인라인 자바스크립트 및 css를 넣지 못하도록 하는 것이다.
CSP에 사용되는 대표적인 헤더들
Content-Security-Policy : W3C에서 지정한 표준헤더, 대부분 이걸 사용
X-Content-Security-Policy : Firefox/IE 구형 브라우저에서 사용되는 헤더
X-WebKit-CSP : Chrome 기반의 구형 브라우저에서 사용되는 헤더
CSP 설정방법
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'; style-src 'self'; ">
도메인 또는 포트가 다른 서버의 자원을 요청하는 메커니즘
교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제
CORS 체제는 브라우저와 서버 간의 안전한 교차 출처 요청 및 데이터 전송을 지원한다.
최신 브라우저는 XMLHttpRequest 또는 Fetch와 같은 API에서 CORS를 사용하여 교차 출처 HTTP 요청의 위험을 완화 한다.
웹 애플리케이션은 리소스가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행한다
브라우저는 보안 상의 이유로, 스크립트에서 시작한 교차 출처 HTTP 요청을 제한한다.
ex) domain-a.com ↔domain-b.com 간의 요청은 CORS 정책 위반으로, 브라우저에서 요청을 제한)
따라서 다른 출처의 리소스를 불러오기 위해서는, 그 출처에서 교차 출처 리소스 공유에 대한 헤더(CORS)를 응답시 반환 해주어야 한다
기본적으로 웹은 다른 출처의 리소스를 요청할 때는 HTTP 프로토콜을 사용하여 요청을 하는데,
이때 브라우저는 요청 헤더 (request header)에 Origin 필드에 요청을 보내는 출처를 담아 전송한다.
서버는 요청에 대한 응답을 하는데, 응답 헤더 (response header)에 Access-Control-Allow-Origin이라는 값에 '이 리소스를 접근하는 것이 허용된 출처'를 내려준다.
이후 응답을 받은 브라우저는 자신이 보냈던 요청의 Origin과 서버가 보내준 응답의 Access-Control-Allow-Origin을 비교해 본 후 이 응답이 유효한 응답인지 아닌지를 결정한다.
이것이 기본적인 CORS 동작의 흐름이다.
하지만 모든 CORS 동작의 방식은 아니다.
Preflight 방식은, 요청을 한번에 보내는 것이 아니라 예비 요청과 본 요청으로 나누어서 서버로 전송한다.
본 요청을 보내기 전 미리 예비로 보내는 요청을 Preflight라고 하며, HTTP 메서드 중 하나인 OPTIONS 메서드를 사용한다.
WHY?
예비 요청을 함으로써 본 요청을 보내기 전 브라우저 스스로가 요청을 보내는 것에 대한 안전성을 확인함에 있다.
서버는 이 예비 요청에 대한 응답으로 현재 자신이 어떤 것들을 허용 하고, 어떤 것들을 금지하고 있는지에 대한 정보를 응답 헤더에 담아서 브라우저에게 다시 보내준다.
단순히 Origin에 대한 정보 뿐만 아니라 자신이 예비 요청 이후에 보낼 본 요청에 대한 다른 정보들도 함께 전송 한다. 어떤 헤더를 포함 할 것인지, 어떤 HTTP 메서드를 사용하여 요청을 보낼 것인지 말이다.
Preflight 요청과는 달리, 예비 요청을 보내지 않고, 서버에게 바로 본 요청을 전송한다.
이 후 서버가 응답 헤더에 Access-Control-Allow-Origin과 같은 값을 보내주면 그때 브라우저가 CORS 정책 위반 여부를 검사하는 방식이다.
동작 조건
인증된 요청을 사용하는 방법이다.
다른 출처 간 통신의 좀 더 보안을 강화하고자 할 때 사용한다. 브라우저가 제공하는 비동기 리소스 요청 API인 XMLHttpRequest 객체나 fetch API는 별도의 옵션 없이 브라우저의 쿠키 정보나 인증과 관련된 헤더를 함부로 요청에 담지 않는다. 이때 요청에 인증과 관련된 정보를 담을 수 있게 해주는 옵션이 바로 credentials 옵션이다.
credentials도 세가지 옵션을 가지고 있다.
다른 출처 사이트로의 요청에 쿠키와 같은 인증정보를 포함시키고자 한다면 ?
→ credentials: 'include' 옵션을 추가
동작 조건
Access-Control-Allow-Origin: * 이면 안되며, 명시적인 URL을 설정하여햐 한다.
ex) Access-Control-Allow-Origin: https://xxx.com
응답 헤더에는 반드시 Access-Control-Allow-Credentials: true가 존재해야한다.
OWASP(Open Web Application Security Project)는 오픈소스 웹 애플리케이션 보안 프로젝트이다.
OWASP처럼 애플리케이션 보안에만 전념하는 여러 커뮤니티 그룹의 조직이 상당히 커지고 있다.
OWASP는 가장 큰 오픈소스 웹 애플리케이션 보안 프로젝트로 주로 웹에 관한 정보노출, 악성 파일 및 스크립트, 보안 취약점 등을 연구하며, 10대 웹 애플리케이션의 취약점(OWASP TOP 10)을 발표한다.
OWASP TOP 10은 웹 애플리케이션에서 빈도가 잦고, 보안상 영향을 크게 줄 수 있는 취약점 10가지를 선정한 목록이다.
OWASP Top 10 목록은 3~4년에 한번씩 정기적으로 업데이트 된다.
아래는 2021년에 업데이트된 OWASP TOP10과 그에 대한 설명이다.
A01 : Broken Access Control (접근 권한 취약점)
엑세스 제어는 사용자가 권한을 벗어나 행동할 수 없도록 정책을 시행한다.
만약 엑세스 제어가 취약하면 사용자는 주어진 권한을 벗어나 모든 데이터를 무단으로 열람, 수정 혹은 삭제 등의 행위로 이어질 수 있다.
A02 : Cryptographic Failures (암호화 오류)
Sensitive Data Exposure(민감 데이터 노출)의 명칭이 2021년 Cryptographic Failures(암호화 오류)로 변경되었다.
적절한 암호화가 이루어지지 않으면 민감 데이터가 노출될 수 있다.
A03: Injection (인젝션)
SQL, NoSQL, OS 명령, ORM(Object Relational Mapping), LDAP, EL(Expression Language) 또는 OGNL(Object Graph Navigation Library) 인젝션 취약점은 신뢰할 수 없는 데이터가 명령어나 쿼리문의 일부분으로써, 인터프리터로 보내질 때 취약점이 발생한다.
A04: Insecure Design (안전하지 않은 설계)
Insecure Design(안전하지 않은 설계)는 누락되거나 비효율적인 제어 설계로 표현되는 다양한 취약점을 나타내는 카테고리 이다.
안전하지 않은 설계와 안전하지 않은 구현에는 차이가 있지만, 안전하지 않은 설계에서 취약점으로 이어지는 구현 결함이 있을 수 있다.
A05: Security Misconfiguration (보안설정오류)
애플리케이션 스택의 적절한 보안 강화가 누락되었거나 클라우드 서비스에 대한 권한이 적절하지 않게 구성되었을 때, 불필요한 기능이 활성화 되거나 설치되었을 때, 기본계정 및 암호화가 변경되지 않았을 때, 지나치게 상세한 오류 메세지를 노출할 때, 최신 보안기능이 비활성화 되거나 안전하지 않게 구성되었을 때 발생한다.
A06: Vulnerable and Outdated Components (취약하고 오래된 요소)
취약하고 오래된 요소는 지원이 종료되었거나 오래된 버전을 사용할 때 발생한다.
이는 애플리케이션 뿐만 아니라, DBMS, API 및 모든 구성요소 들이 포함된다.
A07: Identification and Authentication Failures (식별 및 인증 오류)
Broken Authentication(취약한 인증)으로 알려졌던 해당 취약점은 identification failures(식별 실패)까지 포함하여 더 넓은 범위를 포함할 수 있도록 변경됐다.
사용자의 신원확인, 인증 및 세션관리가 적절히 되지 않을 때 취약점이 발생할 수 있다.
A08: Software and Data Integrity Failures(소프트웨어 및 데이터 무결성 오류)
2021년 새로 등장한 카테고리로 무결성을 확인하지 않고 소프트웨어 업데이트, 중요 데이터 및 CI/CD 파이프라인과 관련된 가정을 하는데 중점을 둔다.
A09: Security Logging and Monitoring Failures (보안 로깅 및 모니터링 실패)
Insufficient Logging & Monitoring(불충분한 로깅 및 모니터링) 명칭이었던 카테고리가 Security Logging and Monitoring Failures (보안 로깅 및 모니터링 실패)로 변경됐다. 로깅 및 모니터링 없이는 공격활동을 인지할 수 없다.
이 카테고리는 진행중인 공격을 감지 및 대응하는데 도움이 된다.
A10: Server-Side Request Forgery (서버 측 요청 위조)
2021년에 새롭게 등장했다. SSRF 결함은 웹 애플리케이션이 사용자가 제공한 URL의 유효성을 검사하지 않고 원격 리소스를 가져올 때마다 발생한다.
이를 통해 공격자는 방화벽, VPN 또는 다른 유형의 네트워크 ACL(액세스 제어 목록)에 의해 보호되는 경우에도 응용 프로그램이 조작된 요청을 예기치 않은 대상으로 보내도록 강제할 수 있다.