본문 바로가기
홍TV 홍TV

포스트-스펙터(Spectre) 시대의 보안: Site Isolation과 COOP/COEP

홍TV 읽는 시간 약 8분
4.5
(300)

들어가며

멀쩡히 잘 쓰던 SharedArrayBuffer나 performance.now의 고정밀 타이머가 어느 날 갑자기 브라우저 콘솔에서 undefined를 뱉거나 정밀도가 뭉개져서 나오는 경험, 프론트엔드를 오래 만지다 보면 한 번쯤 겪게 됩니다. 대부분은 브라우저 버전이 문제인가 싶어 업데이트를 확인하지만, 진짜 원인은 다른 곳에 있는 경우가 많습니다. 바로 COOP와 COEP라는, 이름도 낯선 헤더를 설정하지 않았기 때문입니다. 이 두 헤더는 단순한 CORS 확장이 아니라, Spectre라는 CPU 레벨 취약점이 세상에 알려진 이후 브라우저 업계가 통째로 방향을 튼 결과물입니다. 이번 글에서는 SOP와 CORS로는 설명이 안 되는 이 새로운 계층의 보안 정책, Site Isolation과 COOP, COEP, CORP까지 순서대로 정리해보겠습니다.

Spectre가 브라우저 보안의 전제를 뒤흔든 이유

지금까지 다룬 SOP나 CORS는 모두 소프트웨어 레벨의 규칙이었습니다. 브라우저가 자바스크립트 엔진 안에서 이 스크립트는 저 데이터를 읽을 수 없다고 판단을 내리는 방식이었죠. 그런데 2018년에 공개된 Spectre 취약점은 이 전제 자체를 무너뜨렸습니다. 현대 CPU는 성능을 위해 분기 예측이라는 기법을 쓰는데, 예측이 틀렸을 때 되돌리는 과정에서 캐시에 미세한 흔적이 남는다는 사실이 밝혀졌습니다. 공격자는 이 캐시 접근 시간의 미세한 차이를 정밀하게 측정해서, 원래는 접근할 수 없어야 할 다른 프로세스의 메모리 내용을 한 비트씩 유추해낼 수 있었습니다. 문제는 이 공격이 자바스크립트만으로도 실행 가능하다는 점이었습니다. 즉 브라우저가 아무리 SOP로 스크립트 접근을 잘 막아놓아도, 같은 프로세스 메모리 공간 안에 다른 출처의 데이터가 함께 올라가 있다면 사이드채널을 통해 그 값을 읽어낼 수 있다는 뜻이었습니다. 소프트웨어 규칙으로는 원천적으로 막을 수 없는 하드웨어 레벨의 문제였기 때문에, 브라우저 업계는 아예 물리적으로 메모리 공간 자체를 분리하는 방향으로 대응할 수밖에 없었습니다.

Site Isolation, 프로세스 단위로 선을 긋다

그렇게 나온 것이 Site Isolation입니다. 예전 브라우저는 여러 개의 탭이나 하나의 페이지 안에 있는 여러 iframe을 같은 렌더러 프로세스 안에서 처리하는 경우가 많았습니다. 성능상 유리했기 때문입니다. 하지만 Site Isolation이 적용된 이후로는 서로 다른 사이트는 원칙적으로 서로 다른 프로세스에서 렌더링됩니다. 예를 들어 뉴스 사이트 안에 광고나 결제 iframe이 떠 있다면, 이 iframe은 뉴스 사이트 본체와 물리적으로 다른 프로세스 메모리 공간에서 실행됩니다. Spectre 같은 사이드채널 공격이 성립하려면 같은 프로세스 메모리에 접근할 수 있어야 하는데, 애초에 프로세스가 분리되어 있으면 캐시 타이밍을 아무리 정밀하게 측정해도 훔쳐볼 데이터 자체가 그 프로세스 안에 없는 것입니다. 이 접근 방식의 장점은 자바스크립트 코드를 한 줄도 수정하지 않아도 브라우저 차원에서 기본적인 방어가 이루어진다는 점입니다. 다만 프로세스를 잘게 쪼갤수록 메모리 사용량이 늘어나는 트레이드오프가 있고, 이 비용을 감당하면서도 왜 각 브라우저 업체가 이 기능을 기본으로 켜두었는지를 보면 그만큼 위협을 심각하게 받아들였다는 뜻이기도 합니다.

Spectre 이후 브라우저가 완전히 달라진 이유

COOP와 COEP, 더 강력한 격리를 직접 선언하기

Site Isolation이 브라우저 내부에서 자동으로 해주는 일이라면, COOP와 COEP는 개발자가 명시적으로 강력한 격리를 요청하는 헤더입니다. 이게 왜 필요하냐면, SharedArrayBuffer처럼 여러 스레드가 같은 메모리를 직접 공유하는 고성능 API는 정밀한 타이밍 측정이 가능해서 Spectre 공격의 훌륭한 도구가 될 수 있기 때문입니다. 그래서 브라우저는 이런 위험한 API를 아무 페이지에서나 쓸 수 있게 두지 않고, 그 페이지가 충분히 격리되어 있다는 것을 스스로 증명했을 때만 열어주기로 했습니다.

Cross-Origin-Opener-Policy, 줄여서 COOP는 같은 탭이 아닌 다른 창이나 팝업과 브라우징 컨텍스트를 공유하는 것을 끊어내는 헤더입니다. 이 값을 same-origin으로 설정하면, window.opener를 통해 다른 출처의 창을 참조하거나 서로 자바스크립트로 직접 접근하는 경로가 차단되어 별도의 브라우징 컨텍스트 그룹으로 분리됩니다.

Cross-Origin-Embedder-Policy, 줄여서 COEP는 반대로 내 페이지 안에 다른 출처의 리소스를 끌어오는 쪽을 통제합니다. 이 값을 require-corp로 설정하면, 이미지나 스크립트 같은 리소스를 불러올 때 그 리소스가 나를 명시적으로 허용한다는 표시를 하지 않으면 아예 로드 자체를 실패시켜 버립니다. 정리하면 COOP는 나가는 관계를, COEP는 들어오는 관계를 끊는 셈입니다. 이 두 헤더가 동시에 제대로 설정되어야 브라우저는 이 페이지가 완전히 격리되어 있다고 판단하고, 그제서야 SharedArrayBuffer 같은 API의 사용과 performance.now의 고정밀 타이머 값을 다시 열어줍니다.

SharedArrayBuffer가 undefined로 나오는 진짜 원인

CORP, 내 리소스의 사용처를 서버가 직접 정하다

COEP가 요구하는 명시적 허용 표시가 바로 Cross-Origin-Resource-Policy, CORP입니다. 이 헤더는 CORS와 헷갈리기 쉬운데 역할이 다릅니다. CORS는 자바스크립트가 응답 내용을 읽을 수 있는지를 통제하는 반면, CORP는 애초에 다른 출처에서 이 리소스를 이미지나 스크립트로 불러오는 행위 자체를 허용할지 서버가 결정하는 헤더입니다. same-origin으로 설정하면 같은 출처에서만 불러올 수 있고, cross-origin으로 설정하면 어떤 출처에서든 불러올 수 있습니다. 만약 내 서버가 이미지나 폰트 같은 정적 리소스를 제공하는데 다른 서비스에서 COEP를 require-corp로 걸어두고 이 리소스를 불러오려 한다면, 내 서버가 CORP 헤더로 명시적인 허용 의사를 밝히지 않는 이상 그 리소스는 로드에 실패합니다. 결국 COEP를 도입하려는 개발자는 자신의 페이지에 들어가는 모든 외부 리소스가 CORP를 제대로 설정하고 있는지까지 하나하나 점검해야 하는 셈이라, 실무에서는 이 단계에서 예상치 못한 리소스 로드 실패를 자주 만나게 됩니다.

왜 갑자기 특정 API가 작동하지 않는가에 대한 답

정리하면, 어떤 페이지에서 SharedArrayBuffer를 쓰려고 하는데 undefined가 나오거나 performance.now의 소수점 정밀도가 이상하게 낮게 나온다면 십중팔구는 COOP와 COEP가 제대로 설정되어 있지 않은 상황입니다. 브라우저는 이 페이지가 충분히 격리되었다는 확신이 없으면 위험한 API를 그냥 잠가버리는 쪽을 기본값으로 선택했기 때문입니다. crossOriginIsolated라는 전역 프로퍼티가 true인지 콘솔에서 확인해보는 것이 이 문제를 진단하는 가장 빠른 방법입니다. 이 값이 false라면 두 헤더 중 하나가 빠져 있거나, 페이지 안에 있는 리소스 중 하나가 CORP 조건을 만족하지 못해서 격리가 성립하지 않고 있다는 뜻입니다.

마무리

SOP에서 CORS로, 다시 SameSite와 CSP로 이어지던 브라우저 보안의 흐름은 이제 CPU 레벨의 위협까지 고려하는 단계로 넘어왔습니다. Site Isolation이 브라우저 안에서 조용히 기본 방어선을 쳐주는 동안, COOP와 COEP는 특정 API의 위험성을 정확히 아는 개발자가 스스로 격리를 증명하고 그 대가로 고성능 기능을 돌려받는 구조를 만들었습니다. 이 흐름을 알고 있으면 앞으로 새로운 브라우저 API가 등장할 때마다 왜 이렇게 까다로운 헤더 조건이 붙는지, 그리고 그 조건을 어떻게 충족시켜야 하는지를 훨씬 빠르게 파악할 수 있을 것입니다.

참고

이 글은 Site Isolation, COOP, COEP, CORP와 관련된 공개된 웹 표준 문서 및 개발 자료를 바탕으로 이해를 돕기 위해 정리한 내용입니다.

이 게시물이 얼마나 유용했나요?

별점을 클릭하여 평가하세요!

평균 평점 4.5 / 5. 투표 수: 300

아직 투표가 없습니다! 첫 번째로 평가해보세요.

홍TV

홍TV
함께 보면 좋은 글

댓글 0

첫 댓글을 남겨보세요.

error: Content is protected !!

광고 차단 알림

광고 클릭 제한을 초과하여 광고가 차단되었습니다.

단시간에 반복적인 광고 클릭은 시스템에 의해 감지되며, IP가 수집되어 사이트 관리자가 확인 가능합니다.