1. 소개
이 섹션은 규범적이지 않다.
1.1. 추천 읽을거리
-
[Spectre] 취약점.
-
Cross-Origin-Opener-Policy (COOP)와 Cross-Origin-Embedder-Policy (COEP)가 어떻게, 왜 crossOriginIsolated 기능을 부여하는지. [WhyCoopCoep]를 참고하라.
2. 문제
이 섹션은 규범적이지 않다.
COEP 배포는 서드 파티 iframe 때문에 일부 개발자에게 어렵다. 일반적인 시나리오는 다음과 같다.
-
최종 사용자는 성능 좋은 웹 사이트를 필요로 한다.
-
일부 개발자는 최상위 문서에서 멀티스레딩/
SharedArrayBuffer를 사용해 성능 좋은 웹 사이트를 얻는다. -
[Spectre] 공격을 완화하기 위해 Chrome, Firefox, Safari 같은 브라우저 벤더는
SharedArrayBuffer사용을 crossOriginIsolated 기능 뒤에 둔다. 이는 COEP와 COOP를 모두 배포해야 함을 요구한다. -
COEP 요구 사항은 재귀적이다. 서드 파티 iframe은 COEP 부모 안에 임베드될 수 있으려면 COEP를 배포해야 한다.
-
서드 파티가 COEP를 배포하기를 기다리는 일은 개발자에게 고통스럽다. 이는 대부분의 경우 그들이 통제할 수 없는 일이다.
성능 외에도 crossOriginIsolated 기능 뒤에 있는 추가 기능이 있다. 고해상도 타이머, getViewportMedia 등이다.
COEP 배포는 단일 개발자가 아니라 여러 개발자가 관련된 경우 어렵다. 예를 들어 Google Ads는 서드 파티 콘텐츠를 포함하며, 모든 광고 제작자가 로드 가능하도록 옵트인하는 작업을 하도록 보장할 수 있을 것 같지는 않다.
3. 설명서
이 섹션은 규범적이지 않다.
[COEP-require-corp]는 현재 크로스 오리진 리소스가 더 높은 위험이 있는 환경에서 로드되는 데 명시적으로 옵트인하도록 보장하여 데이터 유출 공격에 대응한다. 이렇게 하면 서버는 취약한 리소스가 고위험 환경에서 로드되도록 옵트인하지 않게 함으로써 해당 리소스를 보호할 수 있다.
명시적인 옵트인을 요구하지 않고도 우발적인 크로스 프로세스 유출에 대해 충분히 견고한 보호를 제공하는 접근 방식을 찾을 수 있다면 이상적일 것이다.
[COEP-credentialless]는 단순 하위 리소스에 대해 문제를 해결했다. 응답의 옵트인을 요구하는 대신, 리소스를 자격 증명 없이 요청한다. 이렇게 하면 공개 리소스만 공격자에게 유출될 가능성이 있다. 공개 리소스는 공격자에게 추가적인 가치를 제공하지 않는다.
자격 증명 없는 iframe은 유사하지만 <iframe>을 위한 것이다.
iframe은 다루기가 더 어렵다. 리소스를 탐색 요청으로 가져올 뿐만 아니라 새 컨텍스트도 만든다.
새 컨텍스트는 스스로 데이터를 가져올 수 있다. 또한 저장소 API의 데이터에 접근할 수도 있다. [WebStorage], [IndexedDB], [web-sql], BroadcastChannel, SharedWorker, ServiceWorker 등이다.
자격 증명 없는 iframe은 새로운 일시적 컨텍스트를 사용해 iframe 안에서 문서를 로드하는 플래그다. 이를 통해 임베드된 웹 사이트의 "공개" 버전만 공격자에게 유출될 수 있도록 보장한다.
3.1. 자격 증명 없는 iframe이란 무엇인가?
문서는 iframe 태그에 credentialless 속성을 추가해 자격 증명 없는 iframe을 만들 수 있다.
< iframe credentialless src = ”https://example.com” ></ iframe >
이 속성은 iframe에 저장된다. 또한 내부에 로드된 새 Window에 저장되고 상속된다. 예:

자격 증명 없음 플래그 상속.
이 속성은 <iframe>에서 프로그래밍 방식으로 변경할 수 있다. 이는 내부에 로드되는 새 Window에 적용된다. 즉 추가 탐색 이후에만
효과가 발생한다는 뜻이다.
자격 증명 없음 플래그의 상태는 읽기 전용 상수 속성을 통해 Window에 노출된다.
window. credentialless
이는 자격 증명 없는 iframe 바로 안에 로드된 Window 또는 그보다 더 깊은 곳에 로드된 Window에 대해 true다.
3.2. 자격 증명 없는 iframe과 자격 증명
자격 증명 없는 iframe은 해당 오리진의 기존 자격 증명과 공유 저장소를 사용할 수 없다. 이들은 빈 상태를 부여받는다. 샌드박스 처리된 프레임과 달리 저장소 API를 사용하고 쿠키를 등록할 수 있다. 그러나 이러한 자격 증명과 저장소는 페이지의 자격 증명 없는 iframe 안에 있는 문서끼리만 공유될 수 있다 (오리진 제한을 충족하는 경우). 사용자가 다른 최상위 문서로 이동하면 더 이상 접근할 수 없다. 본질적으로 자격 증명 없는 iframe은 현재 최상위 문서의 자격 증명 없는 iframe으로 파티션된 임시 storage shelf를 부여받는다.
이를 달성하기 위해 자격 증명 없는 iframe이 공유 저장소에 접근하는 데 사용하는 storage key를 수정하는 데 의존한다. 클라이언트 측 저장소 파티셔닝 작업(storage APIs, network state, Cookie State 전반에 걸쳐 전개됨)의 일부로, 환경의 storage key는 현재 명세에 설명된 단순 오리진이 더 이상 아니다. 대신 오리진과 최상위 사이트 URL의 조합이 된다. 자격 증명 없는 iframe에서는 파티션 키의 최상위 사이트 URL을 최상위 문서마다 한 번 결정되는 nonce 값으로 대체한다. 그 결과 같은 최상위 문서의 자손인 모든 자격 증명 없는 iframe이 nonce를 공유한다. 사용자가 다른 문서로 이동할 때마다 nonce가 달라지므로, 자격 증명 없는 iframe은 서로 다른 페이지 간이나 교차 문서 탐색 간에 저장소를 공유하지 않는다.

저장소와 자격 증명은 일반적인 사이트/오리진 접근 검사를 따르면서 자격 증명 없는 iframe 사이에서만 공유된다.

*자격 증명 없는 iframe이 만든 저장소와 자격 증명은 최상위 프레임이 다른 최상위 문서로 이동한 뒤에는 더 이상 접근할 수 없다. 자격 증명 없는 iframe의 Storage key가 달라지기 때문이다. 이는 탐색 뒤 최상위 문서가 해제될 때, 자격 증명 없는 iframe이 사용한 저장소가 더 이상 사용되지 않으므로 브라우저가 이를 정리할 수 있음을 의미한다.
뒤로-앞으로 캐시는 최상위 문서와 그 자격 증명 없는 iframe을 더 오래 살아 있게 유지할 수 있다. 이들에게 할당된 nonce는 복원될 때 계속 사용된다.
자격 증명 없는 iframe이 연 팝업은 자격 증명 없음 상태가 아니다. 그러나 자격 증명 없는 iframe이 연 팝업은 rel = noopener가 설정된 상태로 열리도록 강제한다. 이는 OAuth 팝업 흐름이 자격 증명 없는 iframe에서 사용되는 것을 방지하기 위해 수행된다. 이 제한을 강제하는 이유에 대한 논의는 위협 모델 부분을 참고하라.
3.3. 자격 증명 없는 iframe이 COEP와 상호작용하는 방식
우리의 제안은 자격 증명 없는 iframe이 COEP 헤더를 보내 임베드에 옵트인하지 않았더라도 COEP 페이지에 임베드하기에 충분히 안전하다는 것이다. 따라서 자격 증명 없는 iframe의 문서로 탐색할 때, 부모가 unsafe-none의 COEP를 갖지 않더라도 문서에 COEP 및 CORP 헤더가 있는지 검사하지 않는다.
이는 또한 자격 증명 없는 iframe 안의 문서가 COEP를 배포하지 않아도 cross-origin isolated 페이지에 임베드될 수 있음을 의미한다.
3.4. 자격 증명 없는 iframe과 자동 완성/비밀번호 관리자
자동 완성 또는 비밀번호 관리자 기능을 구현하는 브라우저는 자격 증명 없는 iframe에서 해당 기능을 사용할 수 없도록 해야 한다. 자격 증명 없는 iframe의 목표는 iframe 기능에 중요한 저장소를 보존하되 사용자가 자격 증명 없는 iframe에 로그인하는 것을 피하는 것이다. 자동 완성과 비밀번호 관리자는 로그인을 더 쉽게 만들므로, 사용자가 실수로 로그인하는 일을 방지하기 위해 피해야 한다. 또한 이를 통해 자격 증명 없는 iframe은 피싱 페이지와 유사한 위협 모델을 가질 수 있다(아래 이 설명서의 Threat model 부분 참고).
3.5. COEP:credentialless와의 비교
COEP:credentialless와 iframe credentialless는 같은 목표를 공유하는 두 제안이다.
개발자가 COEP를 배포하도록 돕는 것이다. 둘 모두 공개 리소스는 공격자에게 가치가 없다는 생각에 기반한다.
공개 데이터는 서버의 명시적인 옵트인 없이도 프로세스에 안전하게 들어올 수 있다. 같은 프로세스의 공격자가
Spectre를 사용해 데이터를 다시 읽을 수는 있지만, 이익은 얻지 못한다.
비교는 그 이상으로 확장되지 않는다. 두 기능의 구현은 매우 다르다. 하나는 문서로 로드되는 단순 하위
리소스를 위한 것이고, 다른 하나는 <iframe> 안에 서로 다른 문서를 로드하기 위한 것이다.
credentialless라는 이름은 매우 다른 의미를 갖는다.
-
COEP:credentialless: 자격 증명(예: 쿠키) 없이no-cors요청을 로드한다는 뜻이다. -
Iframe credentialless: 주로 문서를 새롭고 수명이 짧은 Cookie/Network/Storage 상태 컨텍스트와 연결한다는 뜻이다.
4. 고려한 대안
이 섹션은 규범적이지 않다.
4.1. 샌드박스 처리된 iframe
allow-same-origin 플래그가 없는 샌드박스 처리된 iframe은 저장소 API나 하위 리소스 요청에 대한 쿠키에 접근할 수 없다. 그러나 sandbox iframe의 문서는 여전히 자격 증명과 함께 요청될 수 있으며, 이는 위협 모델에 맞지 않는다. 샌드박스 처리된 iframe을 변경하여 문서도 자격 증명 없이 요청되도록 할 수 있다.
그렇다면 왜 새 sandbox 플래그가 있는 샌드박스 처리된 iframe을 사용하는 대신 새 속성 도입을 제안하는가?
첫째, 기본 리소스가 항상 자격 증명 없이 요청되도록 샌드박스 처리된 iframe의 동작을 변경하면, 새 개념을 도입하는 것과 달리 기존 웹 사이트가 깨질 수 있다.
둘째, iframe 내부 콘텐츠에 가해지는 중단을 최소화하고자 한다. 샌드박스 처리된 iframe을 사용하면 iframe은 쿠키나 저장소 API를 전혀 사용할 수 없고, 문서의 다른 프레임에도 접근할 수 없다. 우리는 이것이 crossOriginIsolation에 옵트인하기 위한 credentialless 솔루션의 배포 가능성을 제한할 것을 우려한다. 개발자에게 가능한 한 배포하기 쉬운 솔루션을 제공하려 하므로, iframe에 가능한 한 적은 제한만 부과하는 새 솔루션을 도입하는 편이 더 낫다고 본다.
이러한 제한을 sandbox 플래그로 성문화하려 할 수도 있다. 예를 들어 allow-partitioned-storage 같은 것이다. 이는 특히 새 sandbox 플래그가 기본적으로 꺼져 있기 때문에 Firefox와 Safari가 제공한 storage access sandbox 플래그와 조화시키기 어려울 것이다.
이는 다시 COEP 배포를 위해 샌드박스 처리된 iframe에 의존할 때의 또 다른 문제다. 모든 플래그가 기본적으로 꺼져 있으므로, 새 플래그는 샌드박스 처리된 iframe의 동작에 영향을 줄 수 있다. 게다가 쿠키/저장소 접근을 제외한 모든 기능을 얻으려면 allow-same-origin을 제외한 모든 플래그를 추가해야 하므로 구문이 다소 복잡하다.
4.2. 불투명 오리진
우리가 제안하는 자격 증명 없는 iframe 모델은 저장소 키에 nonce를 사용하는 파티션된 저장소(설명서 참고)에 의존한다. 우리는 샌드박스 처리된 iframe과 유사하게 자격 증명 없는 iframe에 불투명 오리진을 부여하는 것도 고려했다. 이렇게 하면 자격 증명 없는 iframe의 오리진이 불투명한 것으로 변경되었기 때문에 기존 자격 증명과 공유 저장소에 접근할 수 없게 된다.
이 솔루션은 호환성 문제에 부딪힌다.
-
자격 증명 없는 iframe이 같은 오리진에서 온 경우 서로 접근할 수 있게 하려면, 각 자격 증명 없는 iframe 하위 트리에 대해 원래 오리진에서 불투명 오리진으로의 매핑을 유지해야 하는데, 이는 복잡하다.
-
불투명 오리진을 가진 프레임이 저장소 API에 접근하려 할 때 무슨 일이 일어나는지 표준화해야 할 가능성이 높다. 불투명 오리진을 가진 샌드박스 처리된 iframe은 저장소 API에 전혀 접근할 수 없기 때문이다.
-
이것이 오리진과 관련된 다른 검사(예: X-Frame-Options, 여러 CSP 검사 등)와 어떻게 상호작용할지 명확하지 않으며, 추가적인 파손으로 이어질 수 있다.
4.3.
COEP:credentialless가 <iframe>에 영향을 미치게 하기
원래 COEP:credentialless의 범위는 오늘날처럼 단순 하위 리소스뿐만 아니라 <iframe>도
포함하도록 의도되었다. 후자는 성격이 매우 다르다. 요청의 자격 증명뿐만 아니라 문서가 나중에 수행하는
모든 저장소 API 사용도 관련되기 때문이다. 그래서 여기로 미뤄졌다.
어려운 점은 대부분의 경우 웹 사이트가 다음의 혼합을 포함한다는 것이다.
-
자격 증명이 중요한 크로스 오리진
<iframe>. URL은 부모에게 알려져 있으므로, 부모는 자식 웹 사이트에 COEP 및 CORP 헤더를 보내도록 업데이트해 달라고 합리적으로 요청할 수 있다. 자식이 임베드에 옵트인하기를 기다릴 수 있다. -
광고 같은 크로스 오리진
<iframe>. 자격 증명은 실제로 중요하지 않으며, 부모가 로드되는 웹 사이트를 실제로 통제하지 않는다.
따라서 부모가 iframe별로 결정을 내릴 수 있는 것이 중요하다. 이 결정은 자식이 직접 내릴 수 없다는 점에 유의하라. 이는 탐색 요청의 자격 증명에 영향을 미치기 때문이다. 그때는 너무 늦다.
COEP:credentialless를 사용하면 사이트 작성자는 request.mode를 조정하고
cors와 no-cors 중에서 결정함으로써 리소스별로 자격 증명을 보낼지 정할 수 있다.
하나는 하위 리소스가 임베드에 옵트인해야 하고, 다른 하나는 자격 증명을 생략한다.
<iframe> 요소에도 유사한 메커니즘이 필요하다. 그 결과 credentialless 속성이
되었다.
5. 테스트
상태: https://wpt.fyi/results/html/credentialless-iframe/
6. 명세
6.1. HTML과의 통합
참고: 이는 다음 HTML 명세 변경에 대응한다.
whatwg/html/pull/7695.
병합되면 이 섹션은 폐기된다.
6.1.1. Iframe 속성
the iframe element 섹션에서 HTML iframe credentialless 속성을 정의한다.
이는 Javascript HTMLIFrameElement 인터페이스에 노출된다.
partial interface HTMLIFrameElement {attribute boolean credentialless ; };
IDL 속성 credentialless는
같은 이름의 각 콘텐츠 속성을 반영해야 한다.
6.1.2. Window 속성
읽기 전용 상수 credentialless 속성을
Window
객체에 추가한다.
partial interface Window {readonly attribute boolean credentialless ; };
6.1.3. 새 브라우징 컨텍스트 만들기
creating a new browsing context 섹션에서: 5단계를 추가한다.
-
browsingContext가 주어졌을 때 initial window credentialless 플래그를 결정한 결과를 credentialless라고 하자.
그런 다음 나중에 새 Window를 만들 때 이를 사용한다.
-
전역 객체에 대해 새 Window 객체를 만든다. 이때
credentialless는 credentialless로 설정한다.
6.1.4. 브라우징 컨텍스트 탐색
navigation params struct에 credentialless 매개변수를 추가한다.
- credentialless
- 새 Window에 부과할
credentialless플래그
navigate 알고리즘에서 18단계를 추가한다.
-
browsingContext가 주어졌을 때 navigation’s credentialless flag를 계산한 결과를 credentialless라고 하자.
그런 다음 같은 알고리즘의 나중 부분에서 이 변수를 사용해 navigation params를 구성한다.
또한 이는 process a navigate fetch 알고리즘의 새 인수로도 전달되며, 이 알고리즘도 새 navigation params를 만드는 데 사용된다.
그런 다음 initialize the document object 알고리즘에서:
browsing context 안에 새 Window를 만들 때 credentialless 값을 전달한다.
-
전역 객체에 대해 새 Window 객체를 만든다. 이때
credentialless는 navigationParams의 credentialless로 설정한다.
그 결과 navigation params에 있는 것과 다른 credentialless 플래그가 유지되는 경우라면, Window 객체를 재사용해서는 안 된다.
예: 이는 다음 경우에 유용하다.
const iframe= document. body. createElement( "iframe" ); iframe. credentialless= true ; document. body. appendChild( iframe); iframe. credentialless= false ; iframe. src= "https://example.test" ; // Window for about:blank and for https://example.test must be different.
-
browsingContext가 still on its initial about:blank Document이고, navigationParams의 history handling이 "replace"이며, browsingContext의 active document의 origin이 navigationParams의 origin과 same origin-domain이고, 또한 browsingContext의 active window의
credentialless플래그가 navigationParams의 credentialless 플래그와 일치하면, 아무것도 하지 않는다.참고: 이는 initial about:blank Document와 막 만들어지려는 새 Document가 같은 Window 객체를 공유한다는 뜻이다.
6.1.5. noopener로 팝업 열기
window open steps에서 5단계를 추가한다.
-
entry global object의
credentialless플래그가 true이면 noopener를 true로 설정한다.
6.1.6. 일반 섹션
Loading web pages 섹션 안에 "Credentialless iframe" 하위 섹션을 추가한다. 위치는 Sandboxing one과 Sandboxing one 및 Cross-origin opener policies 사이이다.
iframe
요소는 변경 가능한 credentialless 플래그 속성을 갖는다. Window는
상수 credentialless
플래그를 갖는다.
credentialless
Window는 Window이며,
그 credentialless
플래그가 true인 것이다.
-
embedder를 browsing context의 container로 설정한다.
-
embedder가 요소가 아니면 false를 반환한다.
-
그렇지 않으면 parentWindow를 embedder의 node document의 relevant global object로 설정한다.
-
다음의 합집합을 반환한다.
-
parentWindow의
credentialless -
embedder의 iframe의 credentialless
-
일반 섹션에 여러 참고를 추가하여 다른 알고리즘 곳곳에 흩어진 변경 사항을 모은다.
참고: 새 Window의 credentialless
플래그는 새 browsing context에 대한 initial window
credentialless flag 알고리즘 또는
기존 browsing context 안에서 탐색이 시작될 때 실행되는
navigation’s
credentialless flag 알고리즘에서 계산된다.
참고: credentialless Window에서 열린
팝업은 항상 noopener가 설정된다.
참고: 최상위 credentialless Window는 존재하지 않는다.
6.1.7. COEP 임베더 검사
COEP 임베딩 검사는 완화될 수 있다.
check a navigation response’s adherence to its embedder policy에 새 매개변수 credentialless 매개변수를 추가하고 navigationParams의 credentialless를 전달한다.
check a navigation response’s adherence to its embedder policy를 수행하려면, 주어진 response response, browsing context target, embedder policy responsePolicy, 그리고 불리언 credentialless에 대해:
-
target이 child browsing context가 아니면 true를 반환한다.
-
parentPolicy를 target의 container document의 policy container의 embedder policy로 하자.
-
parentPolicy의 report-only value가 compatible with cross-origin isolation이고 responsePolicy의 value가 그렇지 않으며, 또한 credentialless가 false이면, response, "
navigation", parentPolicy의 report only reporting endpoint, "reporting", 그리고 target의 container document의 relevant settings object로 queue a cross-origin embedder policy inheritance violation을 수행한다. -
parentPolicy의 value가 compatible with cross-origin isolation이 아니거나 responsePolicy의 value가 compatible with cross-origin isolation이거나, 또는 credentialless가 true이면, true를 반환한다.
-
response, "
navigation", parentPolicy의 reporting endpoint, "enforce", 그리고 target의 container document의 relevant settings object로 Queue a cross-origin embedder policy inheritance violation을 수행한다. -
false를 반환한다.
6.1.8. 자동 완성
"Credentialless iframe" 섹션에서 웹 브라우저가 자동 채우기 기능을 구성해야 하는 방식을 정의한다.
Autofill and credentialless iframe: 사용자 에이전트는 사용자가 양식을 채우는 것을 돕는 기능을 갖는 경우가 있다. 예를 들어 사용자의 주소, 비밀번호, 결제 정보를 미리 채우는 기능이다. 사용자 에이전트는 데이터가 사용자와 웹 사이트 양쪽에 모두 특정적인 경우 이러한 기능을 비활성화해야 한다.
6.1.9. 환경의 파티션 nonce
"Credentialless iframe" 섹션에서 page credentialless nonce를 정의한다.
각 최상위 Window는
연관된 page credentialless
nonce를 갖는다. 이는 변경 불가능한 nonce("number used once")이다.
partition nonce 속성을 environment 객체에 추가한다.
- partition nonce
-
식별자 또는 null. 이는 환경을 추가로 구별하고 격리하는 데 사용된다. 무엇보다도 credentialless Window에 대해 null이 아니다.
6.1.9.1. 탐색용
process a navigate fetch에서 단계를 추가한다.
-
credentialless가 true이면 partitionNonce를 browsingContext의 top-level browsing context의 page credentialless nonce로 하고, 그렇지 않으면 null로 한다.
partitionNonce는 나중에 Environment를 만드는 데 사용된다. 13.3.4단계를 수정한다.
6.1.9.2. Window용
initialize the document object에서 6.9단계를 추가한다.
그런 다음 이를 6.10단계에서 Environment를 만들도록 연결한다.
6.10 creationURL, realm execution context, navigationParams의 reserved environment, topLevelCreationURL, topLevelOrigin, 그리고 partitionNonce로 Set up a window environment settings object를 수행한다.
partitionNonce는 다음과 같은 방식으로 set up a window environment settings object에 전달된다.
이는 6단계에서 사용된다.
-
settings object의 creation URL을 creationURL로, settings object의 top-level creation URL을 topLevelCreationURL로, settings object의 top-level origin을 topLevelOrigin으로, 그리고 settings object의 partition nonce를 partitionNonce로 설정한다.
6.1.9.3. Worker용
script settings for workers 알고리즘에서 8단계를 추가한다.
-
settings object의 partition nonce를 outside settings의 partition nonce로 설정한다.
6.1.9.4. Worklet용
set up a worklet environment settings object 알고리즘에서 7단계를 수정한다.
-
settingsObject의 id를 새 고유 불투명 문자열로, creation URL을 inheritedAPIBaseURL로, top-level creation URL을 null로, top-level origin을 outsideSettings의 top-level origin으로, partition nonce를 outsideSettings의 partition nonce로, target browsing context를 null로, 그리고 active service worker를 null로 설정한다.
6.2. Fetch와의 통합
참고: 이는 다음 HTML 명세 변경에 대응한다.
whatwg/fetch/pull/1416.
병합되면 이 섹션은 폐기된다.
6.2.1. partition-nonce 연결하기
environment의 partition nonce를 network partition key에 추가한다.
다음 변경을 진행한다.
network partition key는 다음으로 구성된 튜플이다.
-
site.
-
null 또는 implementation-defined 값.
-
null 또는 nonce.
determine the network partition key, given an environment environment를 수행하려면 다음 단계를 실행한다.
-
topLevelOrigin을 environment의 top-level origin으로 하자.
-
topLevelOrigin이 null이면 topLevelOrigin을 environment의 top-level creation URL의 origin으로 설정한다.
-
Assert: topLevelOrigin은 origin이다.
-
topLevelSite를 topLevelOrigin이 주어졌을 때 obtaining a site의 결과로 하자.
-
secondKey를 null 또는 implementation-defined 값으로 하자.
두 번째 키는 세부 사항이 아직 발전 중이므로 의도적으로 다소 모호하다. issue #1035를 참고하라.
-
nonce를 environment의 partition nonce로 하자.
-
(topLevelSite, secondKey, nonce)를 반환한다.
6.3. CHIPS와의 통합
이 섹션은 [CHIPS] 위의 monkey-patch를 정의한다. 이는 그 자체로 [COOKIES] 위의 monkey-patch다.
-
"Partitioned" 쿠키 속성이 없더라도 "partition-key"는 정의되며 (top-level-site, partition-nonce)를 포함한다.
-
__Host- 접두사는 필요하지 않다.
-
environment는 "partition-key"가 정의된 쿠키에만 접근할 수 있다.
[CHIPS] 섹션을 수정한다: https://github.com/WICG/CHIPS/blob/main/README.md#algorithm
아래는 브라우저가 쿠키 줄을 파싱하는 데 사용할 수 있는 알고리즘이다. 이 알고리즘은 RFC6265bis의 5.3절에 추가될 수 있다.
-
"partition-key"를 null로 하자.
-
environment의 partition nonce가 정의되어 있거나, attribute-name이 문자열
"Partitioned"와 대소문자 구분 없이 일치하면 다음을 수행한다.-
site를 environment의 top-level origin의 site로 하자.
-
site가 First-Party Set에 있으면 site를 "https://"와 해당 사이트 집합의 "owner domain"을 연결한 것으로 설정한다.
-
nonce를 environment의 partition nonce로 하자.
-
partition-key를 tuple (site, nonce)로 설정한다.
-
-
attribute-name이 "PartitionKey"이고 attribute-value가 partition-key인 속성을 cookie-attribute-list에 추가한다.
아래는 Partitioned 쿠키를 저장하는 알고리즘이다. 이 단계들은 사용자 에이전트가 쿠키의
__Host- 접두사를 처리한 뒤 RFC6265bis의
5.4절에 추가될 수 있다.
-
cookie-attribute-list가 attribute-name이 "PartitionKey"인 속성을 포함하고, attribute-value가 null 또는 non-null nonce가 있는 tuple (site, nonce)이면, 다음 단계를 건너뛰고 쿠키를 cookie store에 삽입한다.
-
cookie-name이 문자열 "__Host-"와 대소문자를 구분해 일치하는 것으로 시작하지 않으면, 다음 단계를 중단하고 쿠키를 완전히 무시한다.
-
쿠키 줄이 [
SamePartyattribute](https://github.com/cfredric/sameparty)도 포함하면(SameParty속성이 cookie-attribute-list에 로드되는 정확한 의미론은 TBD), 다음 단계를 중단하고 쿠키를 완전히 무시한다. -
쿠키의 partition-key를 attribute-name이 "PartitionKey"인 attribute-list의 요소의 attribute-value로 설정한다.
아래는 Partitioned 쿠키를 요청에 첨부하기 위한 알고리즘이다. 이 단계들은 첫 번째 단계
이후 RFC6265bis의
5.5절에 설명된 알고리즘에 추가될 수 있다.
cookie-list의 각 쿠키에 대해 다음을 수행한다.
-
environment를 요청을 시작한 environment로 하자.
-
쿠키의 partition-key가 null이고, 또한 environment의 partition nonce가 null이면, 이 단계의 다음 부분을 건너뛴다.
-
request-top-site를 environment의 top-level origin의 site로 하자.
-
request-partition-nonce를 environment의 partition nonce로 하자.
-
request-top-site가 First-Party Set에 있으면 request-top-site를 "https://"와 request-top-site의 집합의 "owner domain"을 연결한 것으로 설정한다.
-
request-partition-key를 튜플 (request-top-site, request-partition-nonce)로 하자.
-
쿠키의 partition-key가 request-partition-key와 정확히 일치하지 않으면, cookie-list에서 해당 쿠키를 제거한다.
6.4. storage-partitioning과의 통합
[StoragePartition] (link) 작업 항목에서, 대부분의 저장소 API는 추가 키인 최상위 사이트로 키 지정될 것이다.
자격 증명 없는 iframe을 구현하려면 또 다른 키가 추가되어야 하며, 이는 environment의 partition nonce로 정의되어야 한다.
- nonce
- environment의 partition nonce
6.5. storage와의 통합
참고: 이는 다음 [STORAGE] 명세 변경에 대응한다.
whatwg/storage/pull/139.
병합되면 이
섹션은 폐기된다.
6.5.1. storage-key
environment의 partition nonce를 storage key의 추가 키로 더한다.
storage key는 다음으로 구성된 tuple이다.
obtain a storage key for non-storage purposes를 수행하려면, 주어진 environment environment에 대해 다음 단계를 실행한다.
-
origin을 environment가 environment settings object이면 environment의 origin environment의 origin으로, 그렇지 않으면 environment의 creation URL의 origin으로 하자.
-
nonce를 environment의 partition nonce로 하자.
-
origin 및 nonce로 구성된 tuple을 반환한다.
7. 보안 고려 사항
7.1. 위협 모델
자격 증명 없는 iframe은 crossOriginIsolated 컨텍스트에 임베드될 수 있으므로, Out-of-Process-Iframes가 없는 브라우저에서는 임베더가 [Spectre] 공격을 수행하여 HTML을 포함한 자격 증명 없는 iframe의 모든 리소스를 읽을 수 있음을 고려해야 한다. 피해자는 자격 증명 없는 iframe 안에 로드된 문서이고, 다른 문서들은 공격자다.
이 위협에 대한 우리의 접근 방식은 공격 발생을 막는 것이 아니라, 개인화된 데이터가 로드되는 것을 피하여 공격자가 공개적으로 사용 가능한 데이터에만 접근하도록 하는 것이다.
이를 위해 다양한 가능한 공격을 고려한다.
7.2. 기존 자격 증명의 사용
가장 위험한 공격은 또한 가장 직접적이다. 공격자는 사용자가 이미 자격 증명을 가진 리소스로 자격 증명 없는 iframe을 임베드한다. 그런 다음 공격자는 iframe 안의 개인화된 리소스를 읽으며, 이는 공개 데이터가 아니다.
완화:
자격 증명 없는 iframe은 해당 오리진이 저장한 기존 자격 증명에 접근할 수 없다. 여기에는 쿠키가 포함된다. 또한 오리진 공유 저장소의 모든 데이터도 포함된다. 이는 자격 증명을 사용해 가져온 것일 수 있으므로 개인화되어 있을 수 있기 때문이다. 자격 증명 없는 iframe은 공격자가 기존 자격 증명을 사용해 리소스를 로드하는 것을 방지하기 위해 빈 상태에서 시작한다.
7.3. 새 자격 증명의 사용
이 공격에서 공격자는 자격 증명 없는 iframe을 임베드한다. 위에서 설명했듯이 자격 증명 없는 iframe은 자격 증명 및 공유 저장소와 관련해서 빈 상태에서 시작한다. 그러나 자격 증명 없는 iframe은 새 자격 증명을 등록하고 이를 사용해 개인화된 리소스를 요청할 수 있다. 그러면 공격자는 이를 읽을 수 있다. 실제로 이 시나리오는 둘로 나눌 수 있다. 첫 번째는 iframe 사이트가 작동하는 데 필요한 상태를 저장하는 자격 증명의 사용이지만, 특정 사용자에 특화된 것은 아닌 경우다. 이 경우는 공개적으로 접근 가능한 데이터이므로 문제가 되지 않는다. 두 번째는 사용자가 자격 증명 없는 iframe에 로그인한 뒤 얻어지는 사용자별 개인화 상태다.
마지막으로, 그러한 자격 증명이 얼마나 오래 지속되어야 하고 자격 증명 없는 iframe 간에 어떻게 공유되어야 하는지의 문제가 있다. 예를 들어, 사용자가 동일한 오리진 A의 자격 증명 없는 iframe A에 로그인하는 합법적인 페이지를 방문한다고 상상할 수 있다. 그런 다음 동일한 오리진 A의 자격 증명 없는 iframe을 가진 공격자 페이지를 방문한다. 사용자가 여전히 A에 로그인되어 있다면, 공격자 페이지는 개인화된 하위 리소스에서 데이터를 훔칠 수 있다.
완화:
사용자가 iframe에 직접 자격 증명을 입력해 로그인하는 경우, 사용자는 주소 표시줄에 다른 URL이 표시된 페이지 안의 iframe에 로그인하는 것이다. 이는 공격이 발생하기 위해 필요한 사용자 행동과 결과 모두에서 피싱 공격과 유사하다. 이 경우 추가 완화를 요구해서는 안 된다.
사용자가 팝업 기반 OAuth 흐름(또는 곧 제공될 WebID API)을 사용하는 경우, 사용자의 관점에서 상황을 이해하기 더 어렵다. 이를 방지하기 위해 iframe이 팝업을 여는 기능(예: 모든 팝업은 no-opener가 설정되어 열린다)과 WebID API가 출시될 때 이에 접근하는 기능을 제한한다.
자격 증명의 수명과 공유 측면에서, 자격 증명은 자격 증명 없는 iframe의 수명에 묶인다. 따라서 페이지가 자격 증명 없는 iframe을 만들면, 자격 증명 없는 iframe의 하위 트리에 있는 문서들은 자격 증명과 공유 저장소의 깨끗한 상태를 얻는다. 하위 트리의 문서들은 자격 증명을 만들 수 있다. 이들은 같은 오리진 정책을 준수하는 한 서로 공유할 수 있으며, 오직 서로끼리만 공유할 수 있다. 따라서 두 페이지가 같은 오리진을 가진 두 자격 증명 없는 iframe으로 동시에 열려 있다면, 자격 증명 없는 iframe은 서로의 자격 증명을 공유할 수 없다. 자격 증명 없는 iframe이 파괴되면, 그 하위 트리에서 만들어진 자격 증명은 더 이상 접근 가능하지 않아야 한다. 이를 통해 자격 증명 없는 iframe의 기능을 최대한 보존하면서도, 실수로 데이터가 유출될 위험을 최소화한다.
7.4. 네트워크 위치를 기반으로 한 개인화된 리소스
이는 이전 공격의 변형으로, 사용자가 네트워크 위치 때문에 접근할 수 있는 비공개 하위 리소스를 가진 iframe을 임베드하는 경우다. 예를 들어 사용자의 사설 네트워크에서 발견되는 리소스나, 사용자 IP 주소를 기반으로 개인화된 리소스다.
완화:
사설 네트워크 사례는 Private Network Access 제한을 배포하여 처리할 계획이다. Private Network Access restrictions가 도입한 CORS preflight 동안, 서버는 Sec-Fetch-COEP 헤더를 확인하여 자신의 리소스가 자격 증명 없는 iframe 컨텍스트에서 렌더링될지 확인할 수 있다. 로컬 네트워크 문서 중 HTTPS를 활성화한 문서만 잠재적으로 노출될 수 있음에 유의하라 (COI가 있는 페이지에서 HTTP 리소스가 로드되는 것은 MIX가 막아야 하기 때문이다). 이는 강력한 완화는 아니지만, 일반적인 IoT 기기 같은 것에는 중요할 것이다. IP 주소를 기반으로 개인화된 리소스의 다른 사례는 이미 보안상 실수에 가깝다고 볼 수 있다. 우리는 더 많은 요청에서 자격 증명을 사용하지 않는 이점과 비교할 때 그 증가된 위험은 괜찮다고 생각한다.
7.5. 사용자 입력 캡처
이 공격에서 공격자는 사용자 입력을 받을 수 있는 자격 증명 없는 iframe을 임베드한다. 그런 다음 사용자 입력을 읽는다.
완화:
이는 자격 증명 없는 iframe의 범위에 속하지 않는다. 공격자는 이미 공개적으로 사용 가능한 리소스를 사용해 가짜 페이지를 구성하고 사용자를 속여 데이터를 입력하게 하는 피싱 공격을 할 수 있다. 이 공격은 동등하다. 사용자에게 보이는 탐색 표시줄의 URL은 여전히 공격자의 것이기 때문이다.
7.6. 사이드 채널을 사용해 자신을 개인화하는 자격 증명 없는 iframe
자격 증명 없는 iframe은 자격 증명이 없음에도 개인화의 한 형태를 얻으려고 사이드 채널(예: broadcast channels, postMessage)을 사용할 수 있다. 그러면 개인화된 리소스는 임베더가 읽을 수 있다.
완화:
위에 강조된 메커니즘이 리소스를 개인화하는 일반적인 방법인지 여부에 따라, 이는 범위 밖일 수 있다. 우리가 방어하려는 것은, 의심하지 않는 웹 사이트가 임베드되어 그 임베더에게 공격받고 사용자 데이터를 도난당하는 경우다. 자격 증명 없는 iframe이 자신을 개인화하기 위해 자격 증명 없는 iframe의 제약을 벗어나려고 한다면, 그 iframe은 자신이 로드된 컨텍스트와 위험을 이해하고 이를 수락한다고 주장할 수 있다. 우리의 보안 모델이 자격 증명 없는 iframe 밖에서 충분히 안전하다면, 개인화는 어쨌든 iframe과 같은 오리진인 리소스에만 영향을 미친다. 프레임 문서로의 크로스 오리진 리소스는 여전히 개인화되지 않으므로, 보안 관점에서는 COEP:credentialless와 동등해진다.
8. 개인정보 보호 고려 사항
이 API가 제기하는 주요 개인정보 보호 위협은 [Spectre] 같은 사이드 채널 공격을 통한 데이터 유출 위험이다. 위의 위협 모델에서 자세히 설명했듯이, 우리는 이 API가 [Spectre] 공격에 대해 의미 있는 방어를 제공한다고 믿으며, 따라서 개인정보 보호 위험을 제기하지 않는다고 본다.
9. 자체 검토 설문지
[SecurityPrivacyQuestionnaire] (link)를 참고하라.
9.1. 이 기능은 웹 사이트 또는 다른 당사자에게 어떤 정보를 노출할 수 있으며, 그러한 노출은 어떤 목적을 위해 필요한가?
window.credentialless 메서드는 문서가 자격 증명 없는 iframe 안에 로드되었는지 여부를
노출하여, 문서가 기존 자격 증명 또는 저장된 리소스의 가용성에 따라 동작을 변경할 수 있게 한다.
9.2. 명세의 기능은 의도한 사용을 가능하게 하는 데 필요한 최소한의 정보만 노출하는가?
그렇다. 노출되는 유일한 것은 문서가 자격 증명 없는 iframe 안에 임베드되어 있는지 여부다.
9.3. 명세의 기능은 개인정보, 개인 식별 정보(PII) 또는 그로부터 파생된 정보를 어떻게 처리하는가?
이 기능은 PII를 처리하지 않는다.
9.4. 명세의 기능은 민감한 정보를 어떻게 처리하는가?
이 기능은 민감한 정보를 처리하지 않는다.
9.5. 명세의 기능은 브라우징 세션 전반에 지속되는 오리진용 새 상태를 도입하는가?
아니다. 이 기능은 오리진용 새 상태를 도입하지 않는다.
9.6. 명세의 기능은 오리진에 기반 플랫폼에 관한 정보를 노출하는가?
아니다. 이 기능은 기반 플랫폼과 무관하게 동일하게 동작한다.
9.7. 이 명세는 오리진이 기반 플랫폼으로 데이터를 보낼 수 있게 하는가?
아니다. 이 기능은 오리진이 기반 플랫폼으로 보낼 수 있는 데이터를 변경하지 않는다.
9.8. 이 명세의 기능은 오리진이 사용자 기기의 센서에 접근할 수 있게 하는가?
아니다. 이 기능은 센서 접근에 영향이 없다.
9.9. 이 명세의 기능은 새로운 스크립트 실행/로드 메커니즘을 가능하게 하는가?
아니다. 이 기능은 새로운 스크립트 실행/로드를 가능하게 하지 않는다.
9.10. 이 명세의 기능은 오리진이 다른 기기에 접근할 수 있게 하는가?
아니다. 이 기능은 한 기기에 엄격히 제한된다.
9.11. 이 명세의 기능은 오리진이 사용자 에이전트의 네이티브 UI를 어느 정도 제어할 수 있게 하는가?
아니다. 이 기능은 UI에 영향이 없다.
9.12. 이 명세의 기능은 어떤 임시 식별자를 웹에 만들거나 노출하는가?
임시 식별자는 만들어지지 않는다.
9.13. 이 명세는 퍼스트 파티 컨텍스트와 서드 파티 컨텍스트에서의 동작을 어떻게 구분하는가?
자격 증명 없는 iframe을 임베드할 수 있는 능력에서 퍼스트 파티와 서드 파티 사이에 구분은 없다. 이는 COEP의 재귀적 성질 때문이다. 프레임에서 COEP를 배포하려면 모든 자식 프레임이 먼저 COEP를 배포해야 한다. 이는 COEP 배포를 돕기 위한 메커니즘이므로, 서드 파티 iframe이 자신의 서드 파티 콘텐츠를 자격 증명 없는 iframe으로 임베드할 수 있게 함으로써 자신의 COEP 배포를 쉽게 할 수 있는 선택지를 제공하고자 한다.
9.14. 이 명세의 기능은 브라우저의 Private Browsing 또는 Incognito 모드 컨텍스트에서 어떻게 동작하는가?
일반 모드와 차이가 없다.
9.15. 이 명세에는 "Security Considerations"와 "Privacy Considerations" 섹션이 모두 있는가?
그렇다:
9.16. 명세의 기능은 오리진이 기본 보안 보호를 낮출 수 있게 하는가?
이 기능은 secure context 및 same-origin policy에 영향을 주지 않는다. 현재 COOP와 COEP를 활성화해야 하는 조건 뒤에 있는 기능을 사용할 수 있게 하기는 한다. 그러나 이를 안전하게 만들기 위해 문서에 제한을 부과한다.
9.17. 기능은 "fully active"가 아닌 문서를 어떻게 처리하는가?
자격 증명 없는 iframe은 iframe 안의 문서에만 영향을 준다. back/forward cache 기능은 메인 프레임 탐색에 대해서만 구현된다는 일반적인 가정이 있다. 이 가정하에서는 특별히 할 일이 없다.
서브 프레임 수준에서 back/forward cache를 구현하는 가상의 웹 브라우저는 "credentialless" 속성이 변경된 iframe 안의 문서를 복원할 때 무슨 일이 일어나는지 반드시 고려해야 한다. 예를 들어, back/forward cache가 해당 문서를 복원하지 못하게 할 수 있다.