안전한 웹 탐색이란, 다양한 종류의 웹사이트를 별 다른 위험 없이 방문하는 것을 의미한다. 안전하다는 것은 어떻게 알 수 있을까?
무결성(Integrity)과 기밀성(Confidentiality)을 보장하는 것은 웹 보안에서 매우 중요한 개념이다.
무결성
: 사이트에 포함된 정보는 변형되거나 손상되지 않아야 한다.
기밀성
: 사이트에 포함된 정보는 외부에서 훔칠 수 없어야 한다.
웹 브라우징은 대부분 애플리케이션을 활용해 이루어지기 때문에, 웹 기반 애플리케이션은 웹 보안을 준수하도록 설계되어야 한다.
대표적인 공격 모델들을 알아보자.
Malicious Website (악성 웹사이트)
: 사용자가 악성 웹에 직접 접속
Malicious External Resource (악성 외부 리소스)
: 정상적인 웹사이트가 불러오는 외부 리소스에 악성 코드가 포함
Network Attacker (네트워크 공격)
: 공격자가 사용자와 서버 사이의 경로(네트워크)를 공격
Malware Attacker (악성코드 공격)
: 사용자의 장치에 악성 코드를 설치
HTTP Protocol은 리소스를 효율적으로 가져오기 위해 정해진 통신 규약이다.
클라이언트와 서버는 HTTP Protocol 양식에 맞는 메시지를 주고받으며 통신을 진행한다.
통신에 사용되는 HTTP 요청 메시지는 다음과 같이 구성되어 있다.
Method : 요청 동작(GET, POST, ...)
Path : 요청하는 자원의 경로
Version : HTTP Protocol의 버전
Header : 여러가지 옵션(정보)들이 설정되어 있는 필드
HTTP 요청에 주로 사용되는 메소드들은 다음과 같다.
GET
: 데이터 읽기
POST
: 데이터 생성 또는 제출
PUT
: 전체 데이터 덮어쓰기
DELETE
: 지정된 리소스 삭제
GET 요청은 데이터를 변경하지 않는 요청이지만, 나머지 3개의 요청은 상태를 갱신하는 요청이기 때문에 보안에 더욱 유의해야 한다.
HTTP 요청 수신측은 상대방이 요청한 데이터를 포함시킨 HTTP 응답을 전송한다.
수신측 브라우저는 HTTP 응답을 파싱하여 데이터를 추출하여 활용(화면 구성, ...)한다.
HTTP 쿠키는 서버가 웹 브라우저에 보내는 데이터 조각으로, 브라우저는 쿠키를 저장하고 동일한 서버에 HTTP 요청을 보낼 때 해당 도메인에 대한 쿠키를 포함시켜 전송한다.
쿠키를 활용하는 대표적인 예시는 다음과 같다.
Session Management
: 로그인 상태, 쇼핑 카트, 게임 점수 등 서버가 기억해야 하는 정보 저장
Personalization
: 사용자 설정, 테마, 기타 환경 설정
Tracking
: 사용자 행동을 기록하고 분석
쿠키는 통신 과정에서 조작될 수 있기 때문에 서버는 쿠키를 전적으로 신뢰할 수 없다.
(Basic Browser Execution Model) 브라우저는 기본적으로 다음과 같은 단계를 거쳐 화면을 구성(Rendering)한다.
1) Loads content
2) Parse HTML and runs javascript
3) Fetches sub resources (img, css, js, ...)
4) Post Fetches, Respond to events (onClick, onLoad, onMouseover, ...)
브라우저는 한 웹 페이지의 Window 내에 서로 다른 출처(Sources) 페이지를 포함하도록 구성할 수 있는데, 이때 주로 frame/iframe
이 활용된다.
Frame
: 페이지 구역을 나누는 가시 영역
iFrame
: 페이지 내부 어딘가에 삽입된 형태
프레임을 활용해서 얻을 수 있는 이점은 다음과 같다.
화면 일부에 다른 출처의 컨텐츠를 독립적으로 시각화
브라우저는 프레임 단위로 격리(Isolation)
프레임이 깨져도, 부모 페이지의 작동에는 아무 문제가 없음
DOM은 웹사이트의 콘텐츠를 읽고 쓰기 위한 객체 지향 인터페이스(Object-Oriented Interface)이다.
자바스크립트는 DOM과 상호작용하며 웹페이지를 읽고 수정한다.
브라우저는 HTML을 구조화된 데이터(DOM)로 변환하여 웹 페이지를 구성한다.
웹사이트는 대부분 다음과 같이 여러 종류의 frame, ifame, Javascript, ...
가 포함된 형태로 구성되어 있다.
웹 페이지는 외부 사이트에서 리소스를 가져오는 경우가 많다. 이는 많은 공격 표면이 생긴다는 의미와 같으며, 웹 보안을 위해 더욱 엄격한 보안 기준을 준수해야 한다.
(Same Origin Policy, SOP) 브라우저는 원칙적으로 페이지가 동일한 출처(Origin)를 가진 경우에만 데이터 상호 작용을 허용한다.
따라서 출처가 다른 (Other origins) 컨텐츠는 서로 다른 프레임에 분리하고, 프레임 간 통신을 제한한다.
출처(Origin)는 다음 세 가지 요소로 정의된다.
scheme
://
domain
:
port
Scheme (프로토콜) : http
Domain (호스트 명) : www.example.com
Port (포트 번호) : 8080
원칙적으로 위 세가지가 모두 동일한 경우에만 동일 출처로 인식한다.
각 프레임 내 컨텐츠는 고유한 출처를 가질 수 있다.
각 컨텐츠는 출처의 클라이언트 리소스(Local Resource)를 가지며, 부모 윈도우라고 하더라도, 다른 출처의 자식 프레임 데이터에는 접근할 수 없다.
이를 Frame Isolation(프레임 격리)라고 한다.
스크립트는 자신의 부모 프레임 혹은 윈도우의 출처(Origin) 권한으로 실행된다.
따라서 외부에서 불러온 스크립트라도, 같은 출처에서 실행되는 스크립트는 모두 동일한 출처 권한으로 간주된다.
외부에서 가져온 스크립트로 페이지 컨텐츠를 조작할 수 있다는 것은 기능면에선 장점, 보안면에선 단점이라고 할 수 있다.
예를 들어, Google Analytics와 같은 외부 스크립트를 로드할 경우 해당 스크립트는 로드된 페이지의 권한으로 실행된다.
그러므로 외부 스크립트를 사용해야 한다면, 반드시 신뢰성이 보장된 스크립트만 활용해야 한다.
HTML 문서의 도메인은 상위 도메인으로 변경이 가능하며, 이것을 도메인 완화(Domain Relaxation)이라고 한다.
도메인 완화는 주로 SOP를 완화하기 위해 활용되며, 공용 최상위 도메인으로의 완화는 불가능하다.
a.domain.com -> domain.com
: 도메인 완화 가능
a.domain.com -> com
: 도메인 완화 불가능
SOP를 완화한다는 것은 그만큼 보안이 느슨해진다는 것을 의미하므로, 주의하여 활용해야 한다.
zakird.github.com -> github.com
으로 설정할 수 있을까?
github.io
와 같은 도메인은 Mozilla의 Public Suffix List(PSL)에 등록되어 있다.
PSL에 등록된 도메인은 Domain Relaxation이 차단되어 있으므로, 위와 같은 도메인 완화 시도는 불가능하다.
XMLHttpRequests(XHR)은 특정 URL로부터 Data를 가져올 수 있도록 하는 기술(Ex, AJAX)이다.
postMessage는 브라우저에서 서로 다른 출처를 가진 문서 간 메시지를 안전하게 주고받기 위한 표준 API이다.
기존 SOP는 보안을 위해 출처를 엄격하게 제안하지만, postMessage는 이를 안전하게 우회하는 방식이다.
BroadcastChannel API란, 동일 출처 내 메시지를 브로드캐스트 방식으로 전송할 수 있도록 지원하는 API이다.
동일한 출처 내에 한 메시지를 브로드캐스트 방식으로 전달하면, 동일 출처에 존재하는 모든 브라우징 컨텍스트가 이 메시지를 수신할 수 있는 것이다.
이는 서로 다른 브라우저 탭, iframe, 웹 워커 간에 동기화된 메시지를 주고받을 수 있도록 한다.
기본적으로 브라우저는 보안을 위해 다른 도메인에서 Resources를 가져오지 못하도록 제한(SOP)한다.
하지만 서버에서 Access-Control-Allow-origin (ACAO) 헤더를 설정하여 외부 도메인에서 리소스에 접근하는 것을 허용할 수 있다.
쿠키는 개인 정보를 포함하고 있기 때문에 개인 정보가 유출 위험이 크다. 따라서 브라우저는 쿠키를 반드시 올바른(의도한) 사이트에만 보내야 한다.
DOM의 SOP는 다음과 같이 Origin을 정의한다.
(scheme, domain, port)
Coockie SOP의 경우 다음과 같이 Origin을 정의한다.
([scheme], domain, path)
이때 경로 구분(Path)은 쿠키가 적용될 URL 범위를 좁히는 것으로, 이는 보안을 위한 것이 아니라 효율성을 위한 것이다.
서버는 자기 자신의 도메인이나 상위 도메인(공용 접미사 제외)에서 Cookie SOP의 허용 범위를 설정할 수 있다.
브라우저는 다음과 같이 URL 범위(Scope)에 맞춰 쿠키를 전송한다.
HTTP 쿠키의 보안에 문제가 생기는 시나리오를 살펴보자.
Network Attacker : 트래픽을 관찰/변조/삭제가 가능
HTTPs Connection : 암호화된 통신(HTTPs)를 활용해 서버와 사용자가 통신
위와 같은 경우, 공격자가 사용자를 http://bank.com
으로 접속을 유도하면, 브라우저는 쿠키 SOP를 [sheme]/bank.com
으로 인식하기 때문에 그대로 쿠키를 전송한다.
이런 경우를 방지하기 위해 쿠키를 설정할 때 Secure
속성을 사용하여 HTTPs
protocol에서만 전송을 허용할 수 있다.
브라우저는 자바 스크립트 코드를 사용해 DOM의 쿠키에 접근할 수 있다.
document.cookie
HttpOnly
를 설정할 경우, 자바 스크립트 코드를 통한 쿠키 접근이 차단된다. 즉, HttpOnly를 설정할 경우 Client-side에서의 쿠키 접근을 차단할 수 있다.