1. 소개
웹은 존재하는 동안 점점 더 강력한 기능을 갖춘 애플리케이션 플랫폼으로 발전해 왔다. 보안 컨텍스트는 전송 보안을 정식화하고, 교차 출처 격리는 사이드 채널 공격을 완화하며, 브라우저와 운영 체제는 접근 범위를 더 제한하고 사용자가 더 이해하기 쉽도록 특정 파일과 장치를 선택하는 방식의 권한 인터페이스를 실험해 왔다. 이러한 발전은 각각 웹 플랫폼의 안전 보장을 개선하거나, 페이지의 동작에 대한 사용자의 기대를 더 정확하게 유도했으며, 웹에 안전하게 도입될 수 있는 새로운 종류의 기능을 열었다.
이러한 발전에도 불구하고, 합리적으로 해결할 수 없는 방식으로 웹의 보안 기본 요소를 위반하거나, 사용자가 사이트에 해당 기능에 대한 접근을 허용할지 여부에 대해 정보에 입각한 결정을 내릴 수 있을 만큼 명확하게 설명할 수 없기 때문에, 여전히 웹에 안전하게 노출될 수 없는 API가 있다. 플랫폼이 특정 사이트에 API를 노출하는 것이 안전하다는 것을 증명할 수 없다면, 신뢰는 외부 증명에서 유래해야 한다.
페이지의 안전성이나 동작에 관한 모든 주장은 페이지의 콘텐츠와 동작을 알아야 한다. 증명은 보증된 코드가 실행 중인 코드와 동일한 경우에만 의미가 있다. 이 때문에, 신뢰 결정을 위임하는 모든 시스템은 실행 중인 코드의 무결성을 검증할 수 있어야 한다. 즉, 위임된 신뢰를 받은 코드와 일치한다는 것을 알아야 한다.
또한 웹의 현재 보안 모델에 맞지 않는 기능은 다른 웹 콘텐츠에 위험을 초래할 가능성이 있다. 이 위험은 양방향이다. 샌드박스를 뚫는 기능은 다른 사이트를 공격하는 데 사용될 수 있고, 강력한 기능에 접근할 수 있다는 사실은 사이트를 악의적인 행위자에게 더 매력적인 표적으로 만든다. 이러한 위험을 완화하기 위해, 이 명세에 설명된 메커니즘을 통해 기능에 대한 접근 권한을 부여받은 모든 콘텐츠는 사용자의 일반적인 브라우징 세션으로부터 격리되어야 한다.
이 명세는 격리된 컨텍스트를 정의한다. 이는 무결성과 격리의 최소 표준을 충족하는 환경이며, 신뢰성 증명을 목적으로 웹 콘텐츠를 감사할 수 있는 수단을 제공하고, 이 콘텐츠를 사용자의 나머지 브라우징 데이터로부터 격리한다.
이 명세는 사용자 에이전트가 제공하는 기능에 중점을 두지만, 격리된 컨텍스트는 위협 모델이 웹의 보안 모델로 충족되지 않는 모든 웹 페이지 기능에 유익할 수 있다. 예를 들어, 일부 종단 간 암호화 채팅 애플리케이션의 위협 모델에는 서버 침해가 포함되며, 이는 오늘날 웹에서 보호되지 않는다. 격리된 컨텍스트가 가능하게 하는 감사 가능성과 증명은 이러한 애플리케이션이 실행 중인 코드의 무결성과 출처에 대해 확신을 가질 수 있게 할 수 있다.
2. 격리된 컨텍스트
격리된 컨텍스트는 기존 명세에 대한 일련의 § 3 몽키 패치를 통해 정의된다.
무결성은 엄격한 [CSP]와 무결성 검증 알고리즘의 조합을 통해 검증된다. 엄격한 CSP는 교차 출처 실행 가능 콘텐츠가 로드될 수 없도록 보장하며, 무결성 검증 알고리즘은 페이지 내에서 로드된 콘텐츠를 검증하기 위한 추상 메커니즘이다. 이 명세는 특정 검증 접근 방식을 의무화하지 않으며, 환경이 격리된 컨텍스트인지 판단하기 위해 그것이 어떻게 사용되는지만 정의한다.
2.1. 어떤 API가 격리된 컨텍스트를 요구해야 하는가?
가능한 한 적어야 한다. 격리된 컨텍스트에만 노출될 수 있는 모든 API는 웹의 설계 원칙 중 적어도 하나를 위반할 가능성이 매우 높다. 가장 일반적으로는 웹 페이지를 방문하는 것이 안전해야 한다는 원칙이다. API를 사용하기 위해 격리된 컨텍스트를 요구하기 전에 다음 질문을 고려하라:
-
이 API가 해결하려는 문제를 해결하는 유일한 방법이 새로운 웹 플랫폼 API인가? 웹 확장과 네이티브 애플리케이션도 나름의 역할이 있다.
-
기능을 사용자에게 명확하게 전달할 수 없다면, 사용자에게 더 이해하기 쉽고 어떤 콘텐츠가 그것에 접근할 수 있는지에 대해 정보에 입각한 결정을 내릴 수 있게 하는 다른 해결 방법이 있는가?
-
평균적인 웹 페이지에 노출되었을 때 더 이상 허용할 수 없는 위험을 초래하지 않도록 API의 범위를 줄일 수 있는가?
대안을 찾을 수 없다면, API가 격리된 컨텍스트 내에서 실행되도록 요구하는 것을 최후의 수단으로 고려할 수 있다.
웹을 이처럼 독특하고 성공적인 플랫폼으로 만드는 요소 중 하나는 게이트키퍼가 없다는 점이다. 누구나 도메인 이름을 구매하고 다른 누구의 승인 없이 자신의 콘텐츠를 호스팅할 수 있으며, 웹 플랫폼의 API 표면에 완전히 접근할 수 있다. 모두가 동등한 위치에 있다. 격리된 컨텍스트가 제공하는 보안 보장은 감사 가능성을 가능하게 하고, 이는 다시 증명을 가능하게 한다. 브라우저 벤더나 제3자가 제공하는 증명을 통해 얻어지는 안전성은 API가 격리된 컨텍스트로 제한되는 주된 이유이다. 증명 서비스를 제공하는 당사자는 웹 플랫폼의 게이트키퍼가 될 가능성이 있으며, 이는 플랫폼이 나아가기에 바람직한 방향이 아니다. 브라우저 벤더는 격리된 컨텍스트에서 허용할 API를 매우 신중하게 선택해야 한다. 가능하다면 API를 보안 컨텍스트에서 사용할 수 있도록 변경하는 것이 강하게 선호되어야 한다.
2.2. UI 처리
이 명세는 무결성과 격리를 달성하는 데 필요한 기술적 요구 사항에 중점을 두지만, 격리된 컨텍스트가 강력한 기능을 활성화하는 데 사용되는 경우 사용자의 기대를 위반하지 않는 것 역시 중요하다.
사용자는 웹 페이지가 안전하고, 장치에 대한 접근이 제한되어 있으며, 이러한 접근을 자신이 제어한다는 것을 배워 왔기 때문에 웹을 신뢰한다. 웹 플랫폼의 모든 API는 웹 페이지를 방문하는 것이 안전해야 한다는 보장을 목표로 하여 신중하게 설계되어 왔다.
브라우저 벤더는 격리된 컨텍스트로 제한된 기능이 웹 페이지가 할 수 있는 일에 대한 사용자의 기대를 위반하는지 여부를 고려해야 한다. 이러한 기대를 위반하면 사이트에 대한 신뢰를 손상시킬 뿐 아니라, 웹 플랫폼 전체에 대한 사용자의 신뢰를 손상시킬 위험이 있다.
이를 완화하기 위해, 사용자 에이전트는 격리된 컨텍스트 내에서 실행 중인 콘텐츠가 일반적인 웹 콘텐츠가 아니라는 점을 사용자에게 전달하기 위한 조치를 취해야 한다. 여기에는 설치 흐름이나 웹 앱 UI 처리가 포함될 수 있다.
3. 몽키 패치
이 명세는 기존 명세에 다음과 같은 몽키 패치를 수행한다:
-
[CSP]에 대한 패치는 공격에 의미 있게 방어할 만큼 견고한 정책의 특성을 정의하고, 교차 출처 콘텐츠가 로드될 수 없도록 강제한다. 이는 [strict-csp] 및 [securer-contexts]와 같은 탐구에서 배운 것을 바탕으로 하며, 개발자를 잘 이해되고 가치 있는 방어책으로 이끈다.
-
[HTML]에 대한 패치는 이러한 CSP 특성이 다른 보안 요구 사항과 함께 주어진 컨텍스트 내에서 평가되는 방식을 정의한다. 이는 개념적으로 보안 컨텍스트 및 교차 출처 격리 기능과 유사하다. 또한 사용자 에이전트가 출처의 리소스 무결성을 검증하는 데 필요한 속성을 정의한다.
-
[WEBIDL]에 대한 패치는
[IsolatedContext]속성과, 주어진 WebIDL 구성 요소의 노출을 제어하기 위해 위 변경 사항에 의존하는 방식을 정의한다.
3.1. 콘텐츠 보안 정책
[CSP]에서는 CSP 목록 내에 포함된 정책들의 결합 강도를 평가하기 위한 알고리즘을 정의할 것이다. 또한 몇 가지 지원 알고리즘도 정의할 것이지만, § 3.1.1 정책이 인젝션 공격을 의미 있게 완화하는가?가 CSP가 HTML에 노출할 핵심 진입점이다.
3.1.1. 정책이 인젝션 공격을 의미 있게 완화하는가?
Meaningful"을 반환하는 경우 인젝션 공격을 의미 있게
완화한다고 한다. 가능한 반환 값은 "Meaningful" 및
"Not meaningful enough"이다.
-
meets object requirements, meets base requirements, meets script requirements, meets style requirements, meets subresource requirements, 그리고 meets trusted type requirements를
false값을 갖는 불리언으로 둔다. -
policies의 각 policy에 대해 반복한다:
-
policy의 처분이 "
enforce"가 아니거나 policy의 소스가 "header"가 아니면, 계속한다. -
policy가 플러그인을 충분히 완화하면, meets object requirements를
true로 설정한다. -
policy가 상대 URL 조작을 충분히 완화하면, meets base requirements를
true로 설정한다. -
policy가 스크립트 실행을 충분히 완화하면, meets script requirements를
true로 설정한다. -
policy가 스타일 평가를 충분히 완화하면, meets style requirements를
true로 설정한다. -
policy가 안전하지 않은 하위 리소스를 충분히 차단하면, meets subresource requirements를
true로 설정한다. -
policy가 DOM 싱크를 충분히 완화하면, meets trusted type requirements를
true로 설정한다.
-
-
meets object requirements, meets base requirements, meets script requirements, meets style requirements, meets subresource requirements, 그리고 meets trusted type requirements가 모두
true이면 "Meaningful"을 반환한다. -
"
Not meaningful enough"를 반환한다.
3.1.2. 타입에 대한 활성 지시문 얻기
3.1.3. 정책이 플러그인을 충분히 완화하는가?
Sufficient"를 반환하는 경우 플러그인을 충분히 완화한다.
가능한 반환 값은 "Sufficient" 및 "Not sufficient"이다.
3.1.4. 정책이 상대 URL 조작을 충분히 완화하는가?
Sufficient"를 반환하는 경우 상대 URL
조작을 충분히 완화한다.
가능한 반환 값은 "Sufficient" 및 "Not sufficient"이다.
3.1.5. 정책이 스크립트 실행을 충분히 완화하는가?
Sufficient"를 반환하는 경우 스크립트 실행을 충분히 완화한다.
가능한 반환 값은 "Sufficient" 및 "Not sufficient"이다.
-
"
script-src"가 주어졌을 때 policy에서 active directive를 얻는다. -
다음이 모두 참이면 "
Sufficient"를 반환한다:-
active directive가 null이 아니다
-
active directive의 모든 소스 표현식이 문자열 "
'none'", "'self'", 또는 "'wasm-unsafe-eval'"에 대한 ASCII 대소문자 구분 없는 일치이다.
-
-
"
Not sufficient"를 반환한다.
3.1.6. 정책이 스타일 평가를 충분히 완화하는가?
Sufficient"를 반환하는 경우 스타일 평가를 충분히 완화한다.
가능한 반환 값은 "Sufficient" 및 "Not sufficient"이다.
-
policy의 지시문 집합에 있는 각 directive에 대해 반복한다:
-
"
style-src"가 주어졌을 때 policy에서 active directive를 얻는다. -
다음이 모두 참이면 "
Sufficient"를 반환한다:-
directive의 이름이 "
style-src"이다. -
active directive의 모든 소스 표현식이 문자열 "
'none'", "'self'", 또는 "'unsafe-inline'"에 대한 ASCII 대소문자 구분 없는 일치이다.
-
-
-
"
Not sufficient"를 반환한다.
3.1.7. 정책이 안전하지 않은 하위 리소스를 충분히 차단하는가?
Sufficient"를 반환하는 경우 안전하지 않은
하위 리소스를 충분히 차단한다.
가능한 반환 값은 "Sufficient" 및 "Not sufficient"이다.
3.1.8. 정책이 DOM 싱크를 충분히 완화하는가?
Sufficient"를 반환하는 경우 DOM 싱크를 충분히 완화한다.
가능한 반환 값은 "Sufficient" 및 "Not sufficient"이다.
-
policy의 지시문 집합에 있는 각 directive에 대해 반복한다:
-
다음이 모두 참이면 "
Sufficient"를 반환한다:-
directive의 이름이 "
require-trusted-types-for"이다. [TRUSTED-TYPES] -
directive의 값이 문자열 "
'script'"에 대한 ASCII 대소문자 구분 없는 일치인 [0]을 포함한다.
-
-
-
"
Not sufficient"를 반환한다.
3.1.9. 예제
다음 CSP는 인젝션 공격을 의미 있게 완화한다:
base-uri 'none'; default-src 'self'; object-src 'none'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src 'self' https: blob: data:; connect-src 'self' https: blob: data:; img-src 'self' https: blob: data:; media-src 'self' https: blob: data:; font-src 'self' blob: data:; require-trusted-types-for 'script';
3.1.10. 정책이 UI Redressing 공격을 의미 있게 완화하는가?
Meaningful"을 반환하는 경우 UI Redressing 공격을 의미 있게
완화한다고 한다 [UISECURITY].
가능한 반환 값은 "Meaningful" 및 "Not meaningful enough"이다.
-
policies의 각 policy에 대해 반복한다:
-
"
Not meaningful enough"를 반환한다.
3.2. HTML
HTML에서는 리소스 무결성 검증에 사용되는 몇 가지 속성과, § 3.1 콘텐츠 보안 정책에서 정의된 알고리즘과 함께 사용되어 환경 설정 객체의 특성을 정의하는 몇 가지 알고리즘을 정의할 것이다. 이러한 특성은 주어진 IDL 구성 요소가 연결된 전역 객체에 노출되는지 여부를 결정할 때 [WEBIDL]에서 검사된다.
3.2.1. 무결성
무결성 검증 알고리즘은 구현 정의 알고리즘으로, 요청과 응답을 받아 불리언을 반환한다.
참고: 일반적인 무결성 검증 알고리즘은 응답 본문이 예상 값으로 해시되는지, 또는 알려진 리소스 번들에서 유래했는지를 검증할 수 있다.
사용자 에이전트는 출처 무결성 검증 맵을 가진다. 이는 맵으로, 튜플 출처를 무결성 검증 알고리즘에 매핑한다.
참고: 사용자 에이전트가 출처 무결성 검증 맵을 어떻게 채우는지는 이 명세의 범위를 벗어난다. 이 명세는 무결성과 격리를 설정하는 데 필요한 속성에 중점을 둔다. Isolated Web Apps는 설치된 Isolated Web Apps 집합을 기반으로 이 맵을 구성하는 하나의 가능한 구현을 제공한다.
3.2.2. 환경 설정 객체 속성
참고: CSP 목록에 대한 의미 있는 인젝션 및 UI Redressing 완화의 정의는 헤더로 전달된 정책에만 의존하므로, 이러한 속성은 환경의 수명 동안 변이되지 않는다.
true를 반환하는 경우
격리된 컨텍스트이다:
-
environment가 인젝션 공격을 의미 있게 완화하지 않으면,
false를 반환한다. -
environment의 교차 출처 격리 기능이 구체적이지 않으면,
false를 반환한다. -
environment가 UI Redressing 공격을 완화하지 않으면,
false를 반환한다. -
origin을 environment의 출처로 둔다.
-
사용자 에이전트의 출처 무결성 검증 맵[origin]이 존재하지 않으면,
false를 반환한다. -
true를 반환한다.
3.3. Fetch
Fetch에서는 응답이 예상된 콘텐츠를 갖는지 검증하기 위해 § 3.2.1 무결성에서 정의된 무결성 검증 알고리즘을 사용할 것이다.
3.3.1. 응답의 무결성 검증
not applicable", "invalid", 또는 "valid"이다.
- client를 request의 클라이언트로 둔다.
- client가
null이면, "not applicable"를 반환한다. - origin을 request의 출처로 둔다.
- 사용자 에이전트의 출처
무결성 검증 맵[origin]이
존재하지 않으면, "
not applicable"를 반환한다. - integrity verification algorithm을 사용자 에이전트의 출처 무결성 검증 맵[origin]으로 둔다.
- response의 본문이
null이면, "invalid"를 반환한다. - request와 response가 주어진 상태에서 integrity verification algorithm을 실행한
결과가
false이면, "invalid"를 반환한다. - "
valid"를 반환한다.
3.3.2. "Main Fetch" 알고리즘에 대한 패치
main fetch 알고리즘은 다음과 같이 확장된다:- request를 fetchParams의 요청으로 둔다.
- response를
null로 둔다. -
request의 무결성 메타데이터가 빈 문자열이 아니면,
다음을 수행한다:
- ...
-
request와 response가 주어진 상태에서 응답의 무결성 검증을 실행한 결과가
"
invalid"이면, fetchParams와 네트워크 오류가 주어진 상태에서 fetch 응답 핸드오버를 실행한다. - 그렇지 않으면, fetchParams와 response가 주어진 상태에서 fetch 응답 핸드오버를 실행한다.
참고: 이상적으로는 무결성 검증을 [SRI]의 무결성 메타데이터 및 그 지원 알고리즘과 통합할 것이다. 이를 위해서는 [SRI] 명세가 무결성 메타데이터 문자열을 처리하는 방식에 대한 상당한 리팩터링이 필요하며, 이는 향후 추진할 가치가 있을 수 있다.
3.4. WebIDL
WebIDL에서는 [IsolatedContext] 속성을 정의하고, 이를 위에서 HTML에 만든
후크에 연결할 것이다:
3.4.1. [IsolatedContext]
[IsolatedContext]
확장 속성이 인터페이스, 부분 인터페이스, 인터페이스 믹스인,
부분 인터페이스 믹스인, 콜백
인터페이스, 네임스페이스, 부분
네임스페이스, 인터페이스
멤버, 인터페이스 믹스인 멤버, 또는 네임스페이스
멤버에 나타나면,
해당 구성 요소가 노출되는 것이
격리된 컨텍스트 내로만
제한됨을 나타낸다.
[IsolatedContext]
확장 속성은 다른 어떤 구성 요소에도 사용되어서는 안 된다.
[IsolatedContext]
확장 속성은 인수를
받지 않아야 한다.
[IsolatedContext]가
오버로드된 연산에 나타나면,
모든 오버로드에 나타나야 한다.
[IsolatedContext]
확장 속성은 다음 중 둘 이상에 지정되어서는 안 된다:
-
인터페이스 믹스인 멤버와 그 인터페이스 믹스인 또는 부분 인터페이스 믹스인;
참고: 이는 포함하는 정의에도
[IsolatedContext]
확장 속성이 주석으로 붙어 있을 때,
멤버에
[IsolatedContext]
확장 속성을 추가해도
멤버의
노출을 더 제한하지 않기 때문이다.
[IsolatedContext]
확장 속성이 없는 인터페이스는
[IsolatedContext]를
지정한
다른 인터페이스로부터 상속해서는 안 된다.
3.4.2. "exposed" 알고리즘에 대한 패치
WebIDL의 exposed 알고리즘은 다음과 같이 조정되며, 유사하게
[CrossOriginIsolated]를
처리한 후 단일 단계를 추가한다(아래 단계 4).
- construct의 노출
집합이
*가 아니고, realm.[[GlobalObject]]가 construct의 노출 집합에 있는 인터페이스를 구현하지 않으면, false를 반환한다. - realm의 설정 객체가 보안 컨텍스트가 아니고, construct가 [
SecureContext]에서 조건부로 노출되면, false를 반환한다. - realm의 설정 객체의 교차 출처 격리
기능이 false이고,
construct가 [
CrossOriginIsolated]에서 조건부로 노출되면, false를 반환한다. -
realm의 설정 객체가 격리된
컨텍스트가 아니고,
construct가 [
IsolatedContext]에서 조건부로 노출되면,false를 반환한다. - true를 반환한다.
3.5. Storage
비저장 목적을 위한 저장소 키 얻기 알고리즘은 환경에 속한 모든 저장소에 이중 키 지정을 요구하도록 확장된다. 여기서 환경의 최상위 출처는 사용자 에이전트가 무결성 검증 알고리즘을 가진 것으로 알고 있는 출처이다.
참고: 이는 본질적으로 클라이언트 측 저장소 파티셔닝의 최소한으로 명세화된 버전이다. 그것이 완전히 명세화되어 필요한 명세에 병합되면, 해당 변경 사항이 이 절을 대체하게 되며, 이 절은 제거될 수 있다.