개요
1월 3일, Project Zero는 최신 CPU에서 프로세스가 (최악의 경우) 해당 프로세스에 속하지 않는 메모리를 읽는 데 사용할 수 있는 임의의 메모리를 읽는 데 사용할 수 있는 취약점을 공개했습니다. 이러한 취약점의 이름은 스펙터 및 멜트다운으로 지정되었습니다. 웹을 안전하게 유지하기 위해 Chrome은 어떤 일을 하고 있으며, 웹 개발자는 자신의 사이트를 위해 무엇을 해야 할까요?
요약
웹을 탐색하는 사용자는 운영체제와 브라우저를 최신 상태로 유지해야 합니다. 또한 Chrome 사용자는 사이트 격리를 사용 설정할 수 있습니다.
웹 개발자인 경우 Chrome팀의 권장 사항이 있습니다.
- 가능한 경우
SameSite
및HTTPOnly
쿠키 속성을 사용하고document.cookie
에서 읽는 것을 방지하여 쿠키가 렌더기 프로세스의 메모리에 들어가지 못하게 합니다. - MIME 유형이 올바르고 사용자 관련 콘텐츠 또는 민감한 콘텐츠가 있는 URL에
X-Content-Type-Options: nosniff
헤더를 지정하여 사이트 격리를 사용 설정한 사용자가 교차 출처 읽기 차단을 최대한 활용할 수 있도록 하세요. - 사이트 격리를 사용 설정하고 사이트에 문제가 발생하는 경우 Chrome팀에 알립니다.
이 단계가 도움이 된 이유가 궁금하다면 계속 읽어보세요.
위험 요소
이러한 취약점에 대해서는 다양한 설명이 나와 있으므로 다른 문제는 추가하지 않겠습니다. 이러한 취약점이 어떻게 악용될 수 있는지 자세히 알아보려면 Google Cloud팀 동료들이 작성한 블로그 게시물을 살펴보세요.
Meltdown과 스펙터 모두 프로세스가 허용되지 않아야 하는 메모리를 읽을 수 있도록 잠재적으로 허용합니다. 경우에 따라 서로 다른 사이트의 여러 문서가
Chrome에서 하나의 프로세스를 공유할 수 있습니다. 이는 window.open
, <a href="..." target="_blank">
또는 iframe을 사용하여 다른 하나를 열었을 때 발생할 수 있습니다. 웹사이트에 사용자별 데이터가 포함되어 있으면 다른 사이트에서 이러한 새로운 취약점을 이용하여 사용자 데이터를 읽을 가능성이 있습니다.
완화 조치
Chrome 및 V8 엔지니어링팀은 이 위협을 완화하기 위해 다양한 노력을 기울이고 있습니다.
사이트 격리
민감한 정보가 공격자가 제어하는 코드와 프로세스를 공유하는 것을 방지하면 스펙터를 성공적으로 악용했을 때의 영향을 크게 줄일 수 있습니다. Chrome팀은 이를 위해 '사이트 격리'라는 기능을 개발해 왔습니다.
몇 가지 알려진 문제가 있으며 Chrome팀은 최대한 많은 필드 테스트를 수행하려고 하므로 사이트 격리는 아직 기본적으로 사용 설정되지 않았습니다. 웹 개발자는 사이트 격리를 사용 설정하고 사이트가 계속 작동하는지 확인해야 합니다. 지금 선택하려면 chrome://flags#enable-site-per-process
을 사용 설정하세요. 작동하지 않는 사이트를 발견하면 버그를 신고하고 사이트 격리를 사용 설정했다고 언급해 주세요.
크로스 사이트 문서 차단
모든 크로스 사이트 페이지가 별도의 프로세스에 배치되더라도 페이지는 여전히 이미지 및 자바스크립트와 같은 일부 크로스 사이트 하위 리소스를 합법적으로 요청할 수 있습니다. 민감한 정보가 이러한 정보가 유출되는 것을 방지하기 위해 사이트 격리에는 렌더기 프로세스로 전송되는 네트워크 응답을 제한하는 '크로스 사이트 문서 차단' 기능이 포함됩니다.
웹사이트는 서버에 '문서'와 '리소스'라는 두 가지 유형의 데이터를 요청할 수 있습니다. 여기서 문서는 HTML, XML, JSON, 텍스트 파일입니다. 웹사이트는 자체 도메인 또는 허용되는 CORS 헤더가 있는 다른 도메인에서 문서를 수신할 수 있습니다. 리소스에는 이미지, JavaScript, CSS, 글꼴 등이 포함됩니다. 리소스는 모든 사이트에 포함될 수 있습니다.
크로스 사이트 문서 차단 정책은 다음과 같은 경우 프로세스가 다른 출처의 '문서'를 수신하지 못하게 합니다.
- HTML, XML, JSON 또는 text/plain MIME 유형이 있습니다.
X-Content-Type-Options: nosniff
HTTP 응답 헤더가 있거나 빠른 콘텐츠 분석('스니핑')을 통해 유형이 올바른지 확인합니다.- CORS가 문서에 대한 액세스를 명시적으로 허용하지 않음
이 정책에 의해 차단된 문서는 백그라운드에서 요청이 계속 발생하더라도 프로세스에 비어 있는 것으로 표시됩니다.
예를 들어 공격자가 <img src="https://yourbank.com/balance.json">
와 같은 민감한 정보가 포함된 JSON 파일이 포함된 <img>
태그를 만든다고 가정해 보겠습니다.
사이트 격리를 사용하지 않으면 JSON 파일의 콘텐츠가 렌더기 프로세스의 메모리로 전송되고, 이때 렌더러는 유효한 이미지 형식이 아니라는 것을 확인하고 이미지를 렌더링하지 않습니다. 그러나 스펙터를 통해 이제 해당 메모리 청크를 읽을 수 있는 방법이 있습니다. 크로스 사이트 문서 차단은 이 파일의 콘텐츠가 렌더러가 실행 중인 프로세스의 메모리에 들어가지 못하게 합니다. MIME 유형이 크로스 사이트 문서 차단에 의해 차단되기 때문입니다.
사용자 측정항목에 따르면 text/html
또는 text/plain
MIME 유형으로 제공되는 많은 JavaScript 및 CSS 파일이 있습니다. 실수로 문서로 표시된 리소스가 차단되지 않도록 Chrome은 응답에서 스니핑을 시도하여 MIME 유형이 올바른지 확인합니다. 이러한 스니핑은 완벽하지 않으므로, 웹사이트에 올바른 Content-Type
헤더를 설정한다고 확신하는 경우 Chrome팀에서는 모든 응답에 X-Content-Type-Options: nosniff
헤더를 추가하는 것이 좋습니다.
크로스 사이트 문서 차단을 사용해 보려면 위에서 설명한 대로 사이트 격리를 선택합니다.
쿠키 SameSite
개
위의 예시인 <img
src="https://yourbank.com/balance.json">
로 돌아가 보겠습니다. 이는 yourbank.com에서 사용자가 자동으로 로그인하는 쿠키를 저장한 경우에만 작동합니다. 쿠키는 일반적으로 쿠키를 설정하는 웹사이트에 대한 모든 요청에 대해 전송됩니다. 서드 파티에서 <img>
태그를 사용하여 요청하는 경우에도 마찬가지입니다. SameSite 쿠키는 동일한 사이트에서 발생한 요청(이름)에만 쿠키를 연결해야 한다고 지정하는 새로운 속성입니다. 안타깝게도 이 속성 작성 시점에는 Chrome 및 Firefox 58 이상에서만 이 속성을 지원하고 있습니다.
HTTPOnly
및 document.cookie
사이트의 쿠키가 클라이언트 JavaScript가 아닌 서버 측에서만 사용되는 경우, 쿠키의 데이터가 렌더러 프로세스에 입력되지 않도록 할 수 있는 여러 가지 방법이 있습니다. HTTPOnly
쿠키 속성을 설정하면 Chrome 등 지원되는 브라우저에서 클라이언트 측 스크립트를 통해 쿠키에 액세스하지 못하도록 명시적으로 방지할 수 있습니다. HTTPOnly
를 설정할 수 없는 경우 꼭 필요한 경우가 아니면 document.cookie
를 읽지 않음으로써 쿠키 데이터가 렌더링된 프로세스에 노출되지 않도록 제한할 수 있습니다.
rel="noopener"
을(를) 사용하여 외부 링크 열기
target="_blank"
를 사용하여 다른 페이지에 연결하면 열린 페이지가 window
객체에 액세스하고 페이지를 다른 URL로 이동할 수 있으며 사이트 격리가 없으면 페이지와 동일한 프로세스가 됩니다. 페이지를 더 안전하게 보호하려면 새 창에서 열리는 외부 페이지 링크는 항상 rel="noopener"
를 지정해야 합니다.
고해상도 타이머
멜트다운 또는 스펙터를 악용하려면 공격자가 메모리에서 특정 값을 읽는 데 걸리는 시간을 측정해야 합니다. 이를 위해서는 안정적이고 정확한 타이머가 필요합니다.
웹 플랫폼에서 제공하는 한 가지 API는 5마이크로초까지 정확한 performance.now()
입니다. 이를 완화하기 위해 모든 주요 브라우저에서 performance.now()
의 해상도를 낮춰 공격을 마운트하기 어렵게 만들었습니다.
고해상도 타이머를 얻는 또 다른 방법은 SharedArrayBuffer를 사용하는 것입니다. 버퍼는 전용 작업자가 카운터를 늘리는 데 사용합니다. 기본 스레드는 이 카운터를 읽고 이를 타이머로 사용합니다. 당분간 브라우저에서는 다른 완화 조치가 적용될 때까지 SharedArrayBuffer를 사용 중지하기로 결정했습니다.
V8
스펙터를 악용하려면 특별히 제작된 CPU 명령 시퀀스가 필요합니다. V8팀은 알려진 공격 개념 증명에 대한 완화 조치를 구현했으며, 이러한 공격이 트리거되더라도 생성된 코드를 안전하게 보호하는 TurboFan의 최적화 컴파일러를 변경하기 위해 노력하고 있습니다. 그러나 이러한 코드 생성 변경사항으로 인해 성능이 저하될 수 있습니다.
안전한 웹 유지
스펙터와 멜트다운의 발견과 그에 따른 영향에 관해 많은 불확실성이 있었습니다. 이 글을 통해 Chrome팀과 V8팀이 웹 플랫폼을 안전하게 유지하기 위해 어떤 노력을 기울이고 있는지, 그리고 웹 개발자가 기존 보안 기능을 사용하여 어떻게 지원할 수 있는지 알아보셨기를 바랍니다. 궁금한 점이 있으면 언제든지 트위터를 통해 저에게 문의해 주세요.