1. 소개
이 문서는 범용 보고를 위한 세 가지 인프라를 제공하며, 이는 다른 명세에서 사용하거나 확장할 수 있습니다:
-
보고서 유형과 보고 엔드포인트를 정의하는 범용 프레임워크, 그리고 HTTP를 통해 엔드포인트로 보고서를 전송하는 문서 형식.
-
문서 또는 워커 내에서 보고 엔드포인트를 구성하고, 해당 문서 또는 워커의 생명주기에 연결된 보고서를 전달할 수 있는 구체적인 메커니즘.
-
문서 또는 워커 내에서 생성된 보고서를 관찰하는 JavaScript 인터페이스.
다른 명세들은 예를 들어 구체적인 보고서 유형을 정의하거나, 문서 기반이 아닌 보고서를 위한 대체 구성 또는 전달 메커니즘을 정의하는 방식으로 이 인프라를 확장하거나 활용할 수 있습니다.
1.1. 보장 사항
이 명세는 웹사이트 활동과 분리되어 실행되는 최선의 보고서 전달 시스템을 제공하는 것을 목표로 합니다. 사용자 에이전트는 개별 웹사이트에서는 알 수 없는 크로스 오리진 활동을 파악할 수 있으므로, 보고서 전달의 우선순위와 일정을 더 잘 조정할 수 있고, 웹사이트 자체가 처음부터 로딩되지 못하게 하는 오류 조건에 따라 보고서를 전달할 수 있습니다.
그러나 보고서의 전달은 어떠한 방식으로도 보장되지 않으며, 보고는 신뢰할 수 있는 통신 채널로 사용되어서는 안 됩니다. 네트워크 환경에 따라 보고서가 목적지에 도달하지 못할 수 있으며, 사용자 에이전트는 어떠한 이유로든 보고서를 거부하고 전달하지 않을 수 있습니다.
1.2. 예시
endpoint-1
"이라는 이름의 보고 엔드포인트 집합을 정의할 수 있습니다:
Reporting-Endpoints: endpoint-1="https://example.com/reports"
그리고 다음 헤더들은 CSP와 HPKP 보고서를 해당 엔드포인트로 보내도록 지시합니다:
Content-Security-Policy: ...; report-to endpoint-1 Public-Key-Pins: ...; report-to=endpoint-1
Reporting-Endpoints: csp-endpoint="https://example.com/csp-reports", hpkp-endpoint="https://example.com/hpkp-reports"
그리고 다음 헤더들은 CSP와 HPKP 보고서를 각각의 엔드포인트로 보내도록 지시합니다:
Content-Security-Policy: ...; report-to csp-endpoint Public-Key-Pins: ...; report-to=hpkp-endpoint
2. 범용 보고 프레임워크
이 섹션에서는 보고서와 엔드포인트의 일반적인 개념, 그리고 보고서를 application/reports+json
형식으로 직렬화하는 방법을 정의합니다.
2.1. 개념
2.1.1. 엔드포인트
엔드포인트는 특정 보고서가 특정 오리진으로 전송될 수 있는 위치입니다.
각 엔드포인트는 ASCII 문자열인 name
을 가집니다.
각 엔드포인트는 요청에 응답하지 못한 연속 횟수를 나타내는 0
이상의 정수 failures
를 가집니다.
2.1.2. 보고서 유형
보고서 유형은 보고서 본문에 포함된 데이터 집합을 지정하는 비어 있지 않은 문자열입니다.
보고서 유형이 정의될 때(이 명세나 다른 명세에서), ReportingObserver
에 표시됨으로 지정할 수 있습니다. 이는 해당 유형의
보고서를 보고 옵저버가 관찰할 수 있음을 의미합니다. 기본적으로 보고서 유형은 ReportingObserver
에 표시되지 않음 상태입니다.
2.1.3. 보고서
보고서는 사용자 에이전트가 지정된 엔드포인트로 전달해야 하는 임의의 데이터 집합입니다.
각 보고서는 본문을 가지며, 이는
null
이거나 JSON 텍스트로 직렬화할 수 있는 객체입니다. 보고서의 본문에 포함되는 필드는 보고서의 유형에 따라 결정됩니다.
각 보고서는 url을 가지며,
이는 일반적으로 보고서가 생성된 Document
또는 Worker
의 주소입니다.
참고: 직렬화된 URL에서 사용자명, 비밀번호, 프래그먼트는 제거됩니다. § 8.1 Capability URLs 참고.
각 보고서는 user agent 값을
가지며,
이는 보고서가 생성된 요청의 User-Agent
헤더 값입니다.
참고: 보고서의 user agent는 보고서를 생성한 페이지에서 브라우저가
보낸 User-Agent
를 나타냅니다. 이는 보고서를 수집기에 업로드할 때 HTTP 헤더로 전송되는 User-Agent
와 다를 수 있습니다.
예를 들어, 브라우저가 "데스크톱 사이트 요청" 기능처럼 기본값이 아닌 User-Agent
문자열을 선택한 경우입니다.
각 보고서는 destination을
가지며,
이는 보고서가 전송될 엔드포인트의 name
을
나타내는 문자열입니다.
각 보고서는 type을 가지며, 이는 보고서 유형입니다.
각 보고서는 timestamp 값을 가지며, 이는 보고서가 생성된 시간을 유닉스 에포크 이후 밀리초 단위로 기록합니다.
각 보고서는 attempts 카운터를 가지며, 이는 사용자 에이전트가 보고서 전달을 시도한 횟수를 나타내는 0 이상의 정수입니다.
2.2. 미디어 타입
보고서를 지정된 엔드포인트로 POST할 때 사용하는 미디어 타입은 application/reports+json
입니다.
2.3. data를 type으로 destination에 큐잉
직렬화 가능한 객체(data), 문자열(type), 또 다른 문자열(destination), 선택적 environment settings object(settings), 선택적
URL
(url)을
받아 보고서를 생성하려면:
-
report를 새 보고서 객체로 만들고, 각 값을 다음과 같이 초기화합니다:
- body
-
data
- user agent
-
현재
navigator.userAgent
값 - destination
-
destination
- type
-
type
- timestamp
-
현재 타임스탬프
- attempts
-
0
-
url이 호출자에 의해 제공되지 않았다면, url을 settings의 creation URL로 설정합니다.
-
report의 url을 url에 대해 URL serializer를 프래그먼트 제외 플래그를 켜고 실행한 결과로 설정합니다.
-
report를 반환합니다.
참고: 보고 옵저버는 동일한 environment settings object에서만 보고서를 관찰할 수 있습니다.
참고: 보고서의 직렬화된 URL에서는 사용자명, 비밀번호, 프래그먼트가 제거됩니다. § 8.1 Capability URLs 참고.
참고: 사용자 에이전트는 어떠한 이유로든 보고서를 거부할 수 있습니다. 이 API는 예를 들어 임의의 양의 데이터 전달을 보장하지 않습니다.
참고: JavaScript 엔진이 없는 비 사용자 에이전트 클라이언트는 보고 옵저버와 상호작용하지 않아야 하며, 따라서 6단계에서 반환해야 합니다.
2.4. 보고서 직렬화
reports 목록을 JSON으로 직렬화하려면,
-
collection을 빈 리스트로 초기화합니다.
-
reports의 각 report에 대해:
-
다음 키/값 쌍으로 data 맵을 만듭니다:
age
-
report의 timestamp와 현재 시간 간의 밀리초 차이
type
-
report의 type
url
-
report의 url
user_agent
-
report의 user agent
body
-
report의 body
참고: 클라이언트의 시계는 신뢰할 수 없으며 스큐가 존재할 수 있습니다. 따라서 절대 타임스탬프 대신
age
속성을 제공합니다. § 9.2 클록 스큐도 참고하세요. -
report의 attempts를 증가시킵니다.
-
data를 collection에 추가합니다.
-
-
collection에 대해 바이트 시퀀스를 반환합니다. 이때 Infra 값을 JSON 바이트로 직렬화를 실행합니다.
3. 문서 중심 보고
이 섹션은 문서(또는 워커 스크립트) 내 동작으로 생성된 보고서에 대한 보고 엔드포인트를 구성하는 메커니즘을 정의합니다. 해당 보고서는 생성된 문서 또는 워커의 생명주기에 연결되어 있습니다.
3.1. 문서 구성
WindowOrWorkerGlobalScope
를
구현하는 각 객체는 endpoints 리스트를 가지며,
이는 엔드포인트들의 리스트이고, 각 엔드포인트는 반드시 고유한
name
을
가져야 합니다. (고유성은 § 3.3 응답에 대한 보고 엔드포인트 처리 알고리즘에서 보장됩니다.)
WindowOrWorkerGlobalScope
를
구현하는 각 객체는 reports 리스트를 가지며, 이는 보고서들의 리스트입니다.
글로벌의
엔드포인트 리스트 초기화를 위해 WindowOrWorkerGlobalScope
(scope)와 response (response)가 주어지면,
scope의 endpoints를 response에 대해 § 3.3 응답에 대한 보고 엔드포인트 처리를 실행한 결과로 설정합니다.
3.2. Reporting-Endpoints
HTTP 응답 헤더 필드
서버는 반환하는 문서 또는 워커 스크립트 리소스에 대해 Reporting-Endpoints
HTTP 응답 헤더 필드를 통해 보고 엔드포인트
집합을 정의할 수 있습니다. 이 메커니즘은 § 3.2 Reporting-Endpoints HTTP 응답 헤더 필드에서 정의되며, 처리 방식은 § 3.3 응답에 대한 보고 엔드포인트 처리에서 설명합니다.
Reporting-Endpoints
HTTP 응답 헤더 필드의 값은 리소스의 보고 구성 생성에
사용됩니다.
Reporting-Endpoints
는 Dictionary Structured Field
[STRUCTURED-FIELDS]입니다. 딕셔너리의 각 항목은 보고서가 전달될 수 있는 엔드포인트를 정의합니다. 각 항목의 값은 반드시 문자열이어야
합니다.
각 엔드포인트는 String Item으로 정의되며 URI 참조로 해석됩니다. 값이 유효한 URI 참조가 아니면 해당 엔드포인트 멤버는 무시해야 합니다.
또한 해당 멤버가 나타내는 URL은 잠재적으로 신뢰할 수 있어야 합니다 [SECURE-CONTEXTS]. 비보안 엔드포인트는 무시됩니다.
엔드포인트에 대해 정의된 파라미터는 없으며, 지정된 파라미터는 무시됩니다.
헤더는 아래 ABNF 문법으로 표현됩니다 [RFC5234]:
Reporting-Endpoints = sf-dictionary
3.3. 응답에 대한 보고 엔드포인트 처리
response (response)가 주어지면, 이 알고리즘은 엔드포인트들의 리스트를 추출하여 반환합니다.
-
response의 HTTPS state가 "
modern
"이 아니고, response의 url의 origin이 신뢰할 수 없음이면, 이 절차를 중단합니다. -
parsed header를 response의 header list에서 "Reporting-Endpoints"와 "dictionary"로 get a structured field value를 실행한 결과로 설정합니다.
-
parsed header가 null이면, 이 절차를 중단합니다.
-
endpoints를 빈 리스트로 설정합니다.
-
parsed header의 각 name → value_and_parameters에 대해:
-
endpoint url string을 튜플 value_and_parameters의 첫 번째 요소로 설정합니다. endpoint url string이 문자열이 아니면, 다음으로 진행합니다.
-
endpoint url을 endpoint url string에 대해 URL 파서를 response의 url을 기준(base URL)으로 실행한 결과로 설정합니다. endpoint url이 실패이면, 다음으로 진행합니다.
-
endpoint를 새로운 엔드포인트로 생성하고, 속성을 다음과 같이 설정합니다:
-
endpoint를 endpoints에 추가합니다.
-
-
endpoints를 반환합니다.
3.4. 보고서 생성
3.4.1. type 및 data로 보고서 생성
사용자 에이전트가 Document
또는 WorkerGlobalScope
객체(context)에 대해,
문자열(type),
문자열(destination),
직렬화 가능한 객체(data)가 주어지면,
아래 절차를 실행해야 합니다:
-
settings를 context의 relevant settings object로 설정합니다.
-
report를 보고서 생성을 data, type, destination, settings으로 실행한 결과로 설정합니다.
-
settings가 주어졌다면,
-
scope를 settings의 global object로 설정합니다.
-
scope가
WindowOrWorkerGlobalScope
를 구현하는 객체라면, § 4.2 scope 및 report로 보고 옵저버 알림을 scope와 report로 실행합니다.
-
-
report를 context의 reports에 추가합니다.
3.5. 보고서 전달
시간이 지나면서 다양한 기능들이 문서와 워커에 보고서 리스트를 큐에 쌓게 됩니다. 사용자 에이전트는 주기적으로 현재 큐에 있는 보고서 리스트를 가져와 연관된 엔드포인트로 전달합니다. 이 문서는 사용자 에이전트가 따라야 할 일정을 정의하지 않으며, 사용자 에이전트가 보고서를 적절한 시기에 전달할 만큼 충분한 컨텍스트 정보를 가지고 있다고 가정합니다. 이는 사용자의 경험에 영향을 주지 않도록 균형을 맞춰야 합니다.
그렇지만, 사용자 에이전트는 큐잉 직후 가능한 빠르게 보고서를 전달해야 하며, 보고서의 데이터는 생성 직후 기간 내에 훨씬 더 유용할 수 있습니다.
3.5.1. 보고서 전송
사용자 에이전트는 WindowOrWorkerGlobalScope
객체(context)에 대해 보고서 리스트(reports)를 아래 절차로 전송합니다:
-
endpoint map을 엔드포인트 객체를 키로 하고 보고서 객체 리스트를 값으로 하는 빈 맵으로 설정합니다.
-
reports의 각 report에 대해:
-
context의 endpoints 리스트 중
name
이 report의 destination과 같은 엔드포인트(endpoint)가 존재한다면:-
report를 endpoint map의 endpoint에 대한 보고서 리스트에 추가합니다.
-
그렇지 않으면 report를 reports에서 제거합니다.
-
-
-
endpoint map의 각 (endpoint, report list) 쌍에 대해:
-
report list의 각 report에 대해:
-
origin map의 각 (origin, per-origin reports) 쌍에 대해, 아래 절차를 비동기적으로 실행합니다:
-
result를 § 3.5.2 보고서를 엔드포인트로 전달 시도를 endpoint, origin, per-origin reports로 실행한 결과로 설정합니다.
-
result가 "
Failure
"이면:-
endpoint의
failures
를 증가시킵니다.
-
-
result가 "
Remove Endpoint
"이면:-
context의 endpoints 리스트에서 endpoint를 제거합니다.
-
-
각 report를 reports에서 제거합니다.
실패한 보고서에 대한 재전송 메커니즘은 명시되어 있지 않습니다. 여기에 추가하거나, 전달 실패를 나타내는 방법을 제공할 필요가 있습니다.
-
참고: 사용자 에이전트는 수집된 보고서 또는 엔드포인트의 일부만 전달을 시도하기로 결정할 수 있습니다(예: 모든 보고서를 한 번에 전송하면 과도한 대역폭이 소모될 경우 등). 보고서는 전달 시도가 완료된 후에만 캐시에서 제거되므로, 건너뛴 보고서는 이후에 전달됩니다.
3.5.2. reports를 endpoint에 전달 시도
엔드포인트
(endpoint), origin
(origin), 보고서 리스트(reports)가 주어지면,
이 알고리즘은 request를 생성하여 endpoint로 전달을 시도합니다. 전달이 성공하면
"Success
"를 반환하고, 엔드포인트가 410 응답으로 스스로를 보고 엔드포인트에서 제거하면 "Remove Endpoint
"를 반환하며,
그 외에는 "Failure
"를 반환합니다.
-
body를 reports에 대해 보고서 리스트를 JSON으로 직렬화를 실행한 결과로 설정합니다.
-
request를 아래 속성으로 새로운 request로 생성합니다 [FETCH]:
method
-
"
POST
" url
-
endpoint의
url
origin
-
origin
header list
-
header list를 새로 생성하고, header 이름은 `
Content-Type
`, 값은 `application/reports+json
`로 설정합니다. client
-
null
window
-
"
no-window
" service-workers mode
-
"
none
" initiator
-
""
destination
-
"
report
" mode
-
"
cors
" unsafe-request
flag-
설정됨
credentials
-
"
same-origin
" body
참고: 보고서는 credentials가
same-origin
으로 설정되어 전송됩니다. 이는 보고 페이지와 동일 오리진의 보고 엔드포인트가 보고서의 성격에 대한 추가 정보를 얻을 수 있게 하며, 예를 들어 특정 사용자의 계정이 지속적으로 오류를 발생시키는지, 또는 다른 페이지에서 특정 행동이 이 페이지의 보고서를 트리거하는지를 파악할 수 있습니다. 이는 보고 엔드포인트가 다른 방법으로도 얻을 수 있는 정보를 누설하지 않습니다. 크로스 오리진 보고 엔드포인트는 credentials를 받지 않습니다. -
응답 대기(response).
-
response의
status
가 OK 상태 (200-299)이면, "Success
" 반환. -
response의
status
가410 Gone
[RFC9110]이면, "Remove Endpoint
" 반환. -
"
Failure
" 반환.
3.6. 보고서에 사용할 URL 스트립
보고서에 사용할 URL 스트립을 위해 URL url이 주어지면, 아래 절차를 수행합니다. 결과는 보고서에 사용할 URL을 나타내는 문자열입니다.-
url의 scheme이 HTTP(S) scheme이 아니면, url의 scheme을 반환합니다.
-
url의 fragment를 빈 문자열로 설정합니다.
-
url의 username을 빈 문자열로 설정합니다.
-
url의 password를 빈 문자열로 설정합니다.
-
url에 대해 URL serializer를 실행한 결과를 반환합니다.
4. 보고 옵저버
보고 옵저버는 자바스크립트에서
일부 보고서 유형을 관찰하며, 자바스크립트에서는 ReportingObserver
객체로 표현됩니다.
WindowOrWorkerGlobalScope
를
구현하는 각 객체는 등록된 보고 옵저버
리스트를 가지며,
이는 순서가 지정된 집합 형태의 보고 옵저버 집합입니다.
보고 옵저버가 등록된 보고 옵저버 리스트에 포함되어 있으면 등록됨으로 간주됩니다.
WindowOrWorkerGlobalScope
를
구현하는 각 객체는 보고 버퍼를 가지며, 이는 해당 WindowOrWorkerGlobalScope
에서
생성된 보고서 리스트입니다.
이 리스트는 처음에는 비어 있으며, 보고서가 생성된 순서대로 저장됩니다.
참고: 보고 버퍼의 목적은 보고 옵저버가 나중에 생성될 때, 그 이전에 생성된 보고서를
buffered
옵션을 통해 관찰할 수 있도록 하기 위함입니다. 예를 들어, 일부 보고서는 페이지 로딩의 초기 단계에서 생성될 수 있는데, 이때 옵저버가 처음 생성될 수 있거나, 보고서를 관찰하고자 하는
자바스크립트 라이브러리가 로드되기 전에 생성될 수 있습니다.
참고: 보고 옵저버는 자바스크립트 엔진이 있는 사용자 에이전트에서만 관련이 있습니다.
4.1.
인터페이스 ReportingObserver
dictionary ReportBody { };dictionary Report {DOMString ;
type DOMString ;
url ReportBody ?; }; [
body Exposed =(Window ,Worker )]interface {
ReportingObserver constructor (ReportingObserverCallback ,
callback optional ReportingObserverOptions = {});
options undefined observe ();undefined disconnect ();ReportList takeRecords (); };callback =
ReportingObserverCallback undefined (sequence <Report >,
reports ReportingObserver );
observer dictionary {
ReportingObserverOptions sequence <DOMString >;
types boolean =
buffered false ; };typedef sequence <Report >;
ReportList
Report
는 보고서의 응용프로그램 노출 표현입니다.
ReportBody
는 구체적인 보고서 유형이 상속해야 하는 추상 dictionary
타입입니다.
각 ReportingObserver
객체는 다음과 같은 연관된 개념을 가집니다:
-
생성 시 설정되는 callback 함수.
-
ReportingObserverOptions
딕셔너리 options. -
Report
객체들의 리스트 보고서 큐 (초기에는 비어 있음).
ReportList
는 Report
들의
시퀀스를 나타내며,
개발자에게 자바스크립트 배열의 모든 편의 메서드를 제공합니다.
ReportingObserver(callback, options)
생성자가 호출되면, 아래 절차를 실행합니다:
-
새
ReportingObserver
객체 observer를 생성합니다. -
observer의 callback을 callback으로 설정합니다.
-
observer의 options을 options로 설정합니다.
-
observer를 반환합니다.
observe()
메서드가 호출되면, 아래 절차를 실행합니다:
-
global을 관련 글로벌 객체로 설정합니다.
-
this를 global의 등록된 보고 옵저버 리스트에 추가합니다.
-
global의 보고 버퍼의 각 report에 대해 작업 큐에 추가하여 § 4.3 보고서를 옵저버에 추가를 report와 this로 실행합니다.
disconnect()
메서드가 호출되면, 아래 절차를 실행합니다:
-
global을 관련 글로벌 객체로 설정합니다.
-
this를 global의 등록된 보고 옵저버 리스트에서 제거합니다.
takeRecords()
메서드가 호출되면, 아래 절차를 실행합니다:
4.2. scope 및 report로 보고 옵저버 알림
이 알고리즘은 지정된 WindowOrWorkerGlobalScope
의
등록된 보고 옵저버들에게 report의 내용을
제공합니다.
-
scope에 등록된 각
ReportingObserver
observer에 대해 § 4.3 보고서를 옵저버에 추가를 report와 observer로 실행합니다. -
report를 scope의 보고 버퍼에 추가합니다.
-
type을 report의 type으로 설정합니다.
-
scope의 보고 버퍼에 type이 type인 보고서가 100개를 초과하면, type이 type인 가장 오래된 항목을 보고 버퍼에서 제거합니다.
4.3. report를 observer에 추가
report report와 ReportingObserver
observer가 주어지면,
report의 type이 observer에서 관찰 가능한 경우에만 observer의 보고서 큐에 report를 추가합니다.
-
report의 type이
ReportingObserver
에 표시됨이 아니면 반환합니다. -
observer의 options에
types
멤버가 비어 있지 않고, report의 type을 포함하지 않으면 반환합니다. -
새
Report
r을 생성하고,type
은 report의 type,url
은 report의 url,body
는 report의 body로 초기화합니다.
-
r을 observer의 보고서 큐에 추가합니다.
-
observer의 보고서 큐의 크기가 1이면:
-
global을 observer의 관련 글로벌 객체로 설정합니다.
-
작업 큐에 추가하여 § 4.4 notify list로 보고 옵저버 호출을 global의 등록된 보고 옵저버 리스트 복사본으로 실행합니다.
-
4.4. notify list로 보고 옵저버 호출
이 알고리즘은 이전에 관찰된 행동의 보고서에 대해 옵저버 콜백 함수를 호출합니다.
5. 구현 고려 사항
5.1. 전달
사용자 에이전트는 개발자에게 가능한 빠르게 피드백을 제공하기 위해 보고서를 최대한 신속히 전달하려고 시도해야 합니다(SHOULD). 그러나 이러한 요구가 사용자의 경험에 영향을 미칠 때는 사용자의 경험이 우선입니다. 이를 고려하여, 사용자 에이전트는 사용자의 활동 및 상황에 따라 보고서 전달을 지연할 수 있습니다(MAY).
예를 들어, 사용자 에이전트는 보고 데이터의 전송 우선순위를 다른 네트워크 트래픽보다 낮게 설정해야 합니다(SHOULD). 사용자가 웹사이트에서 수행하는 명시적 활동이 보고 트래픽보다 우선해야 합니다.
사용자 에이전트는 불필요한 데이터 비용을 방지하기 위해 사용자가 빠르고 저렴한 네트워크에 있을 때까지 보고서 전달을 완전히 보류할 수 있습니다(MAY).
사용자 에이전트는 특정 오리진(예: 사용자가 자주 방문하는 오리진)의 보고서를 다른 오리진보다 우선적으로 전달할 수 있습니다(MAY).
5.2. 가비지 컬렉션
사용자 에이전트는 주기적으로 캐시에 저장된 보고서와 엔드포인트를 점검하여, 더 이상 관련 없는 항목을 폐기해야 합니다(SHOULD). 해당 항목에는 다음이 포함됩니다:
6. 샘플 보고서
이 섹션은 비규범적입니다.
이 예시는 사용자 에이전트가 보고 엔드포인트로 보고서를 전송할 때의 형식을 보여줍니다. 샘플 제출에는 세 개의 보고서가 함께 묶여 하나의 HTTP 요청으로 전송됩니다. (보고서 유형과 본문 자체는 실제 기능을 나타내지 않으며, 이 명세의 범위 밖입니다).
POST / HTTP/1.1 Host: example.com ... Content-Type: application/reports+json [{ "type": "security-violation", "age": 10, "url": "https://example.com/vulnerable-page/", "user_agent": "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0", "body": { "blocked": "https://evil.com/evil.js", "policy": "bad-behavior 'none'", "status": 200, "referrer": "https://evil.com/" } }, { "type": "certificate-issue", "age": 32, "url": "https://www.example.com/", "user_agent": "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0", "body": { "date-time": "2014-04-06T13:00:50Z", "hostname": "www.example.com", "port": 443, "effective-expiration-date": "2014-05-01T12:40:50Z", "served-certificate-chain": [ "-----BEGIN CERTIFICATE-----\n MIIEBDCCAuygAwIBAgIDAjppMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT\n ... HFa9llF7b1cq26KqltyMdMKVvvBulRP/F/A8rLIQjcxz++iPAsbw+zOzlTvjwsto\n WHPbqCRiOwY1nQ2pM714A5AuTHhdUDqB1O6gyHA43LL5Z/qHQF1hwFGPa4NrzQU6\n yuGnBXj8ytqU0CwIPX4WecigUCAkVDNx\n -----END CERTIFICATE-----", ... ] } }, { "type": "cpu-on-fire", "age": 29, "url": "https://example.com/thing.js", "user_agent": "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0", "body": { "temperature": 614.0 } }]
7. 자동화
사용자 에이전트 자동화 및 애플리케이션 테스트 목적을 위해, 이 문서는 확장 명령을 [WebDriver] 명세에 정의합니다.
7.1. 테스트 보고서 생성
테스트 보고서 생성 확장 명령은 테스트 목적을 위해 보고서 생성을 시뮬레이션합니다. 이 보고서는 모든 등록된 보고 옵저버에서 관찰됩니다.
확장 명령은 다음과 같이 정의됩니다:
dictionary {
GenerateTestReportParameters required DOMString ;
message DOMString = "default"; };
group
HTTP Method | URI Template |
---|---|
POST
| /session/{session id}/reporting/generate_test_report
|
remote end steps은 다음과 같습니다:
-
parameters가 JSON 객체가 아니면, WebDriver 오류와 WebDriver 오류 코드 invalid argument를 반환합니다.
-
message가 없으면 WebDriver 오류와 WebDriver 오류 코드 invalid argument를 반환합니다.
-
현재 브라우징 컨텍스트가 더 이상 열려있지 않으면, WebDriver 오류와 WebDriver 오류 코드 no such window를 반환합니다.
-
사용자 프롬프트 처리를 실행하고 결과가 WebDriver 오류라면 해당 값을 반환합니다.
-
group을 parameters의
group
속성 값으로 설정합니다. -
body를 JSON 텍스트로 직렬화할 수 있는 새 객체로 설정하고, 단일 문자열 필드 body_message를 포함합니다.
-
body_message를 message 값으로 설정합니다.
-
settings를 environment settings object로, 현재 브라우징 컨텍스트의 활성 문서에서 가져옵니다.
-
보고서 생성 및 큐잉을 body, "test", group, settings으로 실행합니다.
-
성공과 data null을 반환합니다.
8. 보안 고려 사항
8.1. Capability URL
일부 URL은 그 자체로 가치가 있습니다. 사용자명과 비밀번호 부분에 명시적 자격증명이 포함되어 있을 수 있고, URL 경로를 알기만 해도 리소스에 접근할 수 있는 경우가 있습니다. 또한 URL 프래그먼트에 사용자의 브라우저를 벗어나서는 안 되는 정보가 포함될 수 있습니다. 자세한 내용은 [CAPABILITY-URLS]를 참고하세요.
이러한 URL이 보고 메커니즘을 통해 유출되는 가능성을 완화하기 위해, 본 명세의 알고리즘에서는 보고서에 포함된 URL에서 자격증명 정보와 프래그먼트 데이터를 제거합니다. 하지만 URL 경로에 민감한 정보가 포함된 경우는 여전히 유출될 수 있습니다. 이러한 URL을 사용하는 사이트는 자체 보고 엔드포인트를 운영해야 할 수도 있습니다.
또한 보고서의 본문에도 이러한 URL이 포함될 수 있습니다. 이 API를 확장하는 명세에서 보고서의 본문에 URL이 포함된다면, 마찬가지로 해당 정보도 제거해야 합니다(SHOULD).
9. 프라이버시 고려 사항
9.1. 네트워크 누출
페이지가 로드된 후 보고서가 생성되어 전송되기까지 지연이 있기 때문에, 사용자가 한 네트워크에 있을 때 생성된 보고서가 다른 네트워크에서 전송될 수 있습니다.
이 동작은 보고서를 생성한 문서의 생명주기 동안으로 제한되지만, 해당 문서는 navigator.sendBeacon
과 같은 다른 방법을 통해 새 네트워크에서 트래픽을
생성할 수 있습니다(문서가 닫힌 이후에도).
대응책을 고려해야 합니다. 예를 들어, 네트워크가 변경되면 보고서를 폐기할 수도 있습니다. [WICG/background-sync Issue #107]
9.2. 클록 스큐
각 보고서는 생성된 시점의 타임스탬프가 아니라 age
속성과 함께 전달됩니다. 이는 각 사용자의 로컬 시계가 서버의 시계와 임의의 차이를 가질 수 있기 때문입니다.
보고서가 생성된 시간과 전송된 시간의 차이는 클록 스큐와 무관하게 안정적으로 유지되며, 이 API를 통해 클록 스큐가 노출되는 지문 위험을 방지할 수 있습니다.
9.3. 크로스 오리진 상관관계
여러 오리진이 동일한 보고 엔드포인트를 사용하면, 해당 엔드포인트는 특정 사용자가 어떤 웹사이트와 상호작용했는지 알 수 있습니다. 각 오리진에서 오리진 태그가 붙은 보고서를 받기
때문입니다. 이는 협력적 오리진에서 동일한 정보를 추적할 수 있는 기존 상태보다 더 나쁘지 않으며, <img>
등을 통한 기존의 추적 능력 이상을 제공하지
않습니다.
9.4. 보고 비활성화
보고는 어느 정도 공동체적 문제입니다. 전체적으로 보면 보고서가 전달되는 것이 모두에게 유용해 보입니다. 개발자에게 직접적인 이점이 있으며, 버그를 고치면 사용자가 즐기는 사이트가 더 안정적이고 쾌적해집니다. 예를 들어, 콘텐츠 보안 정책(CSP)은 사이트의 방어에 구멍이 있을 때 개발자에게 경고함으로써 크로스사이트 스크립팅 공격에 대해 집단 면역 효과를 제공합니다. 버그를 고치면 CSP를 지원하지 않는 사용자 에이전트의 사용자까지 도움을 받습니다.
물론, 전달되는 데이터의 성격과 보고 엔드포인트의 악의성에 따라 상황이 달라지지만, 넓은 의미에서 이것이 본 명세의 가치 제안입니다.
그렇다 하더라도, 이러한 일반적인 이점이 사용자가 개별적으로 이러한 시스템을 옵트아웃할 수 있는 능력보다 우선시되어서는 안 됩니다. 보고서를 전송하면 대역폭이 소모되고, 웹사이트가 인밴드로 얻을 수 있는 정보보다 약간 더 많은 정보가 노출될 수 있습니다([NETWORK-ERROR-LOGGING] 등). 사용자 에이전트는 [HTML-DESIGN-PRINCIPLES]의 우선순위 원칙을 지키기 위해 사용자가 적절한 수준으로 보고를 비활성화할 수 있도록 반드시 해야 합니다(MUST).
10. IANA 고려 사항
10.1.
Reporting-Endpoints
헤더
영구 메시지 헤더 필드 등록부는 아래 등록 정보로 업데이트되어야 합니다 [RFC3864]
- 헤더 필드 이름
-
Reporting-Endpoints
- 적용 프로토콜
-
http
- 상태
-
standard
- 작성자/변경 컨트롤러
-
W3C
- 명세 문서
-
이 명세 (§ 3.2 Reporting-Endpoints HTTP 응답 헤더 필드 참고)
10.2.
application/reports+json
미디어 타입
- 타입 이름
-
application
- 서브타입 이름
-
reports+json
- 필수 파라미터
-
N/A
- 선택 파라미터
-
N/A
- 인코딩 고려 사항
-
인코딩 고려 사항은 "application/json" 미디어 타입과 동일합니다. [RFC8259] 참고.
- 보안 고려 사항
-
§ 8 보안 고려 사항 참고.
- 상호운용성 고려 사항
-
이 문서는 메시지의 적합한 형식 및 해석을 명세합니다.
- 게시된 명세
- 이 미디어 타입을 사용하는 애플리케이션
- 프래그먼트 식별자 고려 사항
- 추가 정보
- 프래그먼트 식별자 고려 사항
-
N/A
- 문의 및 추가 정보 담당자
-
이 문서의 편집자.
- 의도된 사용:
-
COMMON
- 사용 제한:
-
N/A
- 작성자
-
이 문서의 편집자.
- 변경 컨트롤러
-
W3C
- 임시 등록?
-
Yes.