1. 소개
이 절은 규범적이지 않다.
이는 작성 협업만을 위한 매우 초기 초안임에 유의한다
웹은 상태를 갖지 않는 프로토콜을 기반으로 구축되어 있다. 특정 기능을 위해 상태를 유지하려면, 웹 애플리케이션은 사용자 기기에 데이터를 로컬로 저장한다. 이 저장소는 오랫동안 지속될 수 있으며, 로그인한 사용자 세션의 자격 증명과 같은 보안에 민감한 데이터에 사용된다.
일반적으로 사용자 에이전트는 일반적인 운영 체제에서 사용자 에이전트 자체와 동일한 권한을 가진 소프트웨어에 대해 안전하게 이러한 종류의 데이터를 저장할 방법이 없다. 동시에 이러한 데이터로 인증된 동작은 은행 계좌에서 돈을 이체하는 것과 같은 심각한 결과를 초래할 수 있다. 이 모델에 대한 일반적이고 확장 가능한 위협은 이러한 자격 증명을 유출하고 다른 곳에서 악용을 수행하여 탐지를 회피하는 악성코드이다.
이 문서는 서버가 세션 자격 증명이 기기에서 내보내지지 않았음을 검증할 수 있게 하는 새로운 API인 Device Bound Sessions Credentials(DBSC)를 정의한다. 이러한 자격 증명은 개인 키이므로, 사용자 에이전트는 TPM 또는 유사한 API와 같은 기능을 사용하여, 동일 권한의 악성코드로부터도 유출되지 않도록 보호할 수 있다.
목표는 사용자에게 안전하고 보안성 있는 경험을 제공하면서, 사용자가 이미 익숙한 사용 사례를 제공하는 것이다. 동시에 이 프로토콜로 인해 새로운 개인정보 식별자가 누출되지 않도록 하여 사용자 개인정보가 존중되도록 하고자 한다. 이 API는 기존 서버 측 인증 스택과 쉽게 통합되도록 특별히 주의를 기울이며, 웹 소프트웨어 스택의 큰 부분을 다시 작성하지 않아도 이러한 보호로 나아갈 수 있는 점진적 경로를 제공한다.
2. 보안 고려 사항
DBSC의 목표는 오래 지속되는 쿠키 bearer 토큰에 대한 대안을 제공하여 세션 탈취를 줄이고, 유출로부터 더 잘 보호될 수 있는 개인 키에 기반하여 세션 인증이 이루어지도록 하는 것이다. 이는 악성코드가 로컬에서 동작하도록 강제되어 더 쉽게 탐지하고 완화할 수 있으므로, 사용자의 신원이 악용될 가능성을 낮춰 인터넷을 사용자에게 더 안전하게 만든다.사용자 에이전트 구현은 서로 다른 플랫폼에 존재하는 악성코드 위협의 유형과 존재하는 보호 메커니즘을 고려하여 이러한 개인 키를 유출로부터 보호하는 최선의 방법을 선택할 책임이 있다. 여기에는 TPM 또는 보안 요소 같은 보안 하드웨어, 안전한 키 생성 및 관리를 위한 OS 제공 API, 또는 로컬에서 실행되는 악성코드에 대해 합리적인 보호를 제공하는 프로세스 격리 메커니즘이 포함되지만 이에 한정되지는 않는다.
세션이 유효하고 손상되지 않은 기기에 등록되어 있는 한, 호스트는 암호학적으로 확실하게 세션 키가 다른 기기로의 악의적 유출로부터 보호된다는 것을 알 수 있다.
2.1. 비목표
DBSC는 공격자가 사용자 기기에 상주하는 동안 브라우저 세션에 일시적으로 접근하는 것을 방지하지 않는다. 개인 키는 현대 운영 체제가 허용하는 만큼 안전하게 저장되어 세션 개인 키의 유출을 방지해야 하지만, 서명 기능은 사용자 기기에서 사용자로 실행되는 모든 프로그램에 여전히 사용 가능할 가능성이 높다.또한 세션 등록 시점에 공격자가 사용자 에이전트를 교체하거나 주입하고 있다면, 공격자가 세션을 TPM에 바인딩되지 않은 키 또는 공격자가 영구적으로 제어하는 TPM에 바인딩할 수 있으므로 DBSC는 공격을 방지하지 못한다.
DBSC는 세션이 등록된 특정 기기나 그 기기의 상태에 대해 호스트에게 어떠한 보장도 제공하도록 설계되지 않았다.
3. 개인정보 보호 고려 사항
DBSC 프로토콜의 개인정보 보호 목표는 사용자 추적을 위한 추가 표면을 도입하지 않는 것이다. 이 API를 구현하는 것(브라우저의 경우) 또는 활성화하는 것(웹사이트의 경우)은 유의미한 사용자 개인정보 보호 절충을 수반해서는 안 된다.이를 보장하기 위해 고려한 사항은 다음과 같다:
-
세션/키 자료의 수명: 이는 추가적인 클라이언트 데이터 저장소(즉, 의사 쿠키)를 제공해서는 안 된다. 따라서 브라우저가 다른 사이트 데이터(쿠키 등)를 지울 때 세션과 키를 반드시 지우도록 요구한다.
-
이 API를 구현해도 휴리스틱 기기 핑거프린팅 신호의 엔트로피가 유의미하게 증가해서는 안 된다. 특히 DBSC는 안정적인 기기 식별자를 누출해서는 안 된다.
-
이 API는 성능을 위해 백그라운드 "ping"을 허용할 수 있으므로, 사용자가 연결된 사이트를 떠난 뒤 장기적인 사용자 추적을 가능하게 해서는 안 된다.
-
각 세션은 별도의 새 키를 생성하며, 서로 다른 세션이 동일한 기기에서 온 것임을 감지할 수 없어야 한다.
3.1. 쿠키 고려 사항
사이트가 이 API를 사용하여 동일 출처 정책, 3P 쿠키 정책 등을 우회하는 것은 불가능해야 한다. 현재 및 변화하는 쿠키 동작의 복잡성과 DBSC와 쿠키 사이의 긴밀한 통합으로 인해, 현재 해결책은 각 사용자 에이전트가 쿠키에 사용하는 것과 동일한 정책을 DBSC에도 사용하는 것이다. 사용자 설정, 적용된 정책 또는 사용자 에이전트 구현 세부 사항에 따라 DBSC 쿠키 자격 증명이 네트워크 요청에 적용되지 않는다면, 추가 DBSC 동작도 적용되지 않는다. 이는 DBSC 구현으로 인해 새로운 개인정보 보호 동작이 생기지 않도록 보장한다.3.2. 타이밍 사이드 채널 누출
서드파티 쿠키가 활성화되어 있으면, 공격자는 요청에 걸리는 시간을 측정하여 사용자가 인증되었는지 여부를 판단할 수 있다. 이는 특히 새로 고침이 키 보호를 위한 느린 하위 기능(예: TPM)에 의존하는 경우 상당히 느릴 수 있기 때문이다.이는 세션 구성의 allowed_refresh_initiators 키로 완화되며, DBSC 새로 고침을
트리거할 수 있는 사이트를 엄격하게 제한하는 데 사용할 수 있다. 기존 해결책
(예: X-Frame-Options)으로 이를 대체할 수 없는 이유는 기존 해결책이 요청이 완료된 뒤에만
적용되는 반면, DBSC는 요청이 시작되기 전에 새로 고침 여부를 선택해야 하기 때문이다.
3.3. 연합 세션
많은 사이트는 브라우저 관여 없이 연합 로그인 메커니즘을 사용하며, 흔히 링크 장식(예: OIDC)에 의존한다. DBSC의 쉬운 도입성이라는 목표를 달성하기 위해, 이러한 사이트가 인증 흐름을 완전히 다시 작성하지 않고도 쿠키 탈취로부터 자신을 보호할 수 있기를 원한다. 이상적으로는 Relying Parties(RP)가 Identity Provider(IdP)와 독립적으로 DBSC 세션을 수립할 수 있어야 한다. 안타깝게도 대부분의 IdP는 사용자가 이미 로그인되어 있으면 비밀번호를 요구하지 않는다. 사용자 상호작용이 필요하지 않다면, 악성코드는 사용자 기기에 대한 일시적 접근을 사용해 로그인 흐름을 모방하고 악성코드가 생성하고 유출할 수 있는 새 개인 키로 DBSC 세션을 수립할 수 있다. 이는 DBSC의 보안 목표를 위반한다.
DBSC는 로그인이나 신원에 본질적으로 묶여 있지 않으므로, Identity Provider는 가장 정확한 용어가 아니다. 대신 Session Provider(SP)라는 용어를 사용하지만, 대상 사용 사례에서는 SP와 IdP가 같은 당사자일 것으로 예상한다.
RP의 세션을 보호하려면 RP와 SP 세션을 어떤 방식으로든 연결해야 한다. 이를 수행하는 가장 간단한 방법은
SP와 RP가 동일한 세션 키 쌍을 사용하는 것이다. SP의 세션은 악성코드가 기기를 손상시키기 전에 수립되었다고
가정하므로, 개인 키가 안전하게 저장되어 있다고 신뢰한다. 그러나 사이트 간 키 공유는 복잡한 개인정보 보호
속성을 갖는다. 고엔트로피 식별자 공유의 개인정보 위험을 완화하기 위해, RP가 이미 SP 세션의 공개 키와
세션 식별자를 알고 있어야 한다고 요구한다. RP는 SP URL, 세션 식별자, base64로 인코딩된 JWK thumbprint
([RFC4648] 및 [RFC7638] 참조)를
`Secure-Session-Registration`
헤더에 포함한다. 키가 올바르면 사용자 에이전트는 SP와 동일한 키로 RP에 세션을 생성한다.
또한 RP와 SP가 이미 정보를 공유할 수 없는 경우(예: 핑거프린팅 또는 링크 장식에 대한 보호가 있는 경우), 악의적인 RP와 SP가 협력하여 사용자를 식별하려는 잠재적 위험도 있다. RP는 일치하는 키를 찾을 때까지 많은 공개 키를 추측해 사용자에 대한 고유 식별자를 얻을 수 있다. 이는 협력하는 RP와 SP가 교차 사이트 신원 연결을 위한 의도된 메커니즘 밖에서 사용자의 신원을 사이트 간에 공유할 수 있게 한다. 이를 방지하기 위해 사용자 에이전트는 등록 시도에 대해 상당한 backoff 또는 quota를 포함해야 한다 (이는 TPM에 대한 서비스 거부를 피하기 위해서도 권장된다). DBSC의 보안 속성은 동일한 키 쌍을 가진 두 사용자를 얻기 어렵다는 암호학적 가정에 의존하므로, 사용자가 SP에 특정 DBSC 공개 키를 가지고 있는지 질의하는 것은 1비트보다 훨씬 적은 엔트로피라는 점에 유의한다.
사용자를 성공적으로 드러내는 가치를 추가로 제한하기 위해, SP가 .well-known을 통해
opt-in하도록 요구한다. 브라우저는 해당 목록의 RP 출처 수를 제한해야 한다. 또한 RP가 여러 SP를 사용하고
그런 방식으로 신원을 집계하는 것을 방지해야 한다. 이를 위해 RP도 .well-known에서 자신의 SP를
선언하도록 요구한다. 이 둘을 함께 사용하면, 사용자가 웹을 탐색할 때 많은 사이트 그룹이 협력하여
한 명의 고가치 사용자를 드러내는 일을 방지할 수 있다.
example.com의 소유자가 example.co.uk도 운영한다고 가정하자. 로그인은 항상
example.com에서 발생하며 링크 장식을 통해 example.co.uk로 전파된다.
두 사이트를 모두 DBSC 세션으로 보호하려면 example.com은 기존
`Secure-Session-Registration`
헤더를 계속 사용해야 한다:
Secure-Session-Registration: (ES256);path="/register";challenge="challenge"
DBSC 세션을 example.com.uk로 확장할 때, 사이트는
`Secure-Session-Registration`
헤더에 새 매개변수를 추가해야 한다:
Secure-Session-Registration: (ES256);path="/register";challenge="challenge";provider_key="abc";provider_id="example.com id";provider_url="https://example.com"
example.com과 example.co.uk에 적절한 .well-known 항목이 있다고 가정하면,
이는 example.co.uk가 example.com의 세션과 동일한 키를 사용하여 새
DBSC 세션을 등록하게 한다. 이를 통해 로그인 시 사용자가 example.com에서 다시 인증하지 않아도
DBSC가 example.co.uk를 보호할 수 있다.
4. 검토한 대안
4.1. WebAuthn과 무음 중재
WebAuthn은 사이트에 특정 키 관리 기능을 제공하므로, DBSC와 같은 목표를 충족하도록 확장할 수 있을지도 모른다. 그러나 WebAuthn은 상호작용형 사용자 로그인에 중점을 두기 때문에, DBSC와 같은 기능의 목표와 상반되는 API 속성이 여러 가지 발생하므로 이 접근 방식을 취하지 않는다. 예를 들어 WebAuthn 자격 증명은 특정 세션에 묶여 있지 않다. 이는 오래 지속되도록 의도되어 있으며 사이트 데이터와 함께 지워지지 않는다. 이는 세션 키에 필요한 개인정보 보호 속성과 잘 맞지 않는다. 마찬가지로 WebAuthn 자격 증명은 명시적인 사용자 의도로 사용되도록 설계되어 있다. DBSC가 제공하는 기능을 WebAuthn이 포괄하도록 확장하려면 WebAuthn이 무음으로 사용할 수 있는 다른 종류의 키를 수립해야 한다. 이는 WebAuthn과 DBSC 모두에 추가 복잡성을 도입한다. 대신, WebAuthn은 안전한 로그인을 제공하는 것을 목표로 하고 DBSC는 로그인 후 사용자를 보호하는 보완적 기능이라는 입장을 취한다.
5. 서버 고려 사항
DBSC를 사용하려면 사이트 소유자는 두 개의 새 엔드포인트, 즉 등록 엔드포인트와 새로 고침 엔드포인트를 수립해야 한다.
등록 엔드포인트는 브라우저가
`Secure-Session-Registration`
헤더를 받은 뒤 비동기적으로 접촉된다. 이 엔드포인트는 다음을 수행해야 한다:
-
새 세션 식별자를 포함한 세션 구성을 제공한다.
-
요청의 공개 키를 세션 식별자와 함께 유지하고 연결한다.
새로 고침 엔드포인트는 훨씬 더 민감하다. 이 엔드포인트는 만료된 바인딩 쿠키가 포함된 요청이 만들어질 때마다 접촉되며, 그 응답은 원래 요청을 차단한다. 응답하지 못하거나 바인딩 쿠키를 복원하지 못하면 브라우저 에이전트가 서비스 거부 방지 메커니즘을 시작하거나 세션을 종료할 수도 있다. 둘 다 향후 요청이 바인딩 쿠키 없이 이루어지는 결과를 낳을 수 있다. 이 엔드포인트의 예상 동작은 다음과 같다:
-
식별자로 세션의 공개 키와 최근 challenge를 조회한다.
-
`
Secure-Session-Response` 헤더가 올바른 키로 최근 challenge에 서명했는지 검증한다. 네트워크 지연과 경쟁 조건으로 인해, 새 challenge를 발급한 뒤 오래된 challenge에 대한 서명을 받을 수 있음에 유의한다. -
새 바인딩 쿠키를 발급한다.
-
선택적으로 현재 세션 구성을 업데이트한다.
브라우저는 DBSC를 도입한 사이트의 지연 시간 비용을 최소화하려고 세션을 사전에 새로 고칠 수 있다. 사이트는 바인딩 쿠키가 만료되었을 때에만 새로 고침이 발생한다고 가정해서는 안 된다.
새로 고침 엔드포인트는 교차 사이트 fetch가 허용될 경우 타이밍 사이드 채널을 통해 로그인 상태를 직접
누출할 가능성이 높다. 서버는 유효한
`Sec-Secure-Session-Id`
헤더를 확인하여 들어오는 요청이 사용자 에이전트에 의해 시작된 것이며 교차 사이트 요청이 아님을 보장할 수 있다.
또한 이 엔드포인트에 좁은 CORS 정책을 설정하고, 교차 사이트 출처가 자격 증명이 있는 요청을 하도록
허용하지 않는 것이 권장된다. DBSC의 CORS 통합은 지연된 요청이 자격 증명을 포함할 때 암시적으로
자격 증명을 포함하도록 설계되어 이를 가능하게 한다. 유사한 이유로, 새로 고침 엔드포인트가
X-Frame-Options 또는 Cross-Origin-Resource-Policy 헤더를 통해
임베드되는 것을 거부하는 것도 권장된다.
example.com에 두 엔드포인트가 있다고 가정하자:
-
/authenticated는 모든 요청 출처에 대해Access-Control-Allow-Credentials를 반환한다. -
/refresh는 DBSC 새로 고침 엔드포인트이다.
사이트는 DBSC가 /authenticated에 대한 교차 사이트 요청을 보호하기를 원하며,
이 하나의 엔드포인트에 대한 타이밍 사이드 채널의 위험이 미미하다고 생각한다. 사용자 에이전트가 트리거한
새로 고침 요청에 대해 자격 증명을 암시적으로 허용하지 않는다면, /refresh는
모든 요청 출처에 대해 Access-Control-Allow-Credentials를 반환해야 한다.
그러면 공격자는 /refresh를 직접 fetch하여 로그인 상태를 누출할 수 있다.
DBSC의 /refresh 호출은 자격 증명을 암시적으로 허용하므로, /refresh
엔드포인트는 Access-Control-Allow-Credentials를 절대 반환하지 않도록 거부할 수 있다.
이는 DBSC 새로 고침의 맥락에서 자격 증명이 있는 요청을 여전히 받는다. 다른 사이트는 자격 증명과 함께
엔드포인트를 직접 fetch할 수 없으므로, 로그인 상태의 쉬운 교차 사이트 누출을 방지한다.
DBSC와 함께 연합 로그인을 사용하는 사이트(§ 3.3 연합 세션 참조)는 연합 키를 가진 세션만 허용되도록 해야 한다. 연합 세션의 보안은 Session Provider(SP) 로그인 시점에 기기가 손상되지 않았다는 점에 의존한다. 악성코드는 기기에 대한 일시적 접근을 사용해 Relying Party(RP)에 새 키로 세션을 등록할 수 있기 때문이다. 따라서 RP는 SP로부터 받은 적절한 공개 키로 등록된 세션만 허용해야 한다.
6. 사용자 에이전트 고려 사항
DBSC는 브라우저가 쿠키 새로 고침을 예약할 수 있는 많은 유연성을 제공한다. 이는 DBSC의 지연 시간을 완화하고 TPM 및 서버의 부하를 낮출 수 있다. 사용자 에이전트가 다음과 같은 방식으로 쿠키 새로 고침을 예약할 것을 권장한다:
-
세션에 이미 대기 중인 DBSC 새로 고침이 있으면 다른 새로 고침을 시작하지 않는다. 이는 TPM 부하를 줄이고 더 단순한 서버 구현을 가능하게 한다
-
세션 자격 증명이 곧 만료되고 범위 내 문서가 활성 상태라면, 사용자 에이전트는 예정된 요청의 지연 시간을 제거하기 위해 사전에 새로 고칠 수 있다.
7. 프레임워크
이 문서는 [RFC5234]에 정의되고 [RFC7405]에서 업데이트된 ABNF 문법을 사용하여 구문을 지정하며, Section 7 of [RFC9112]에 정의된#rule
확장 및 같은 문서의
Section 3.2.6에 정의된
quoted-string 규칙도 함께 사용한다.
이 문서는 알고리즘과 설명에서 사용하는 여러 기반 개념에 대해 Infra Standard에 의존한다 [INFRA].
7.1. 세션 저장소
사용자 에이전트는 세션 저장소를 유지한다. 이는 ordered map이며, registrable domain에서 id별 세션 맵으로 매핑한다. 세션은 사용자 에이전트 재시작 후에도 지속되어야 한다.7.2. id별 세션
id별 세션 맵은 특정 registrable domain에 대해 세션 식별자에서 기기 바인딩 세션으로 매핑하는 ordered map이다.7.3. 기기 바인딩 세션
기기 바인딩 세션은 다음 items를 갖는 struct이다:- 세션 식별자
-
registrable domain의 세션에 대한 고유 식별자인 string
- 새로 고침 URL
- 캐시된 challenge
-
이 세션의 다음 challenge로 사용할 string 또는 null
- 세션 범위
- 세션 자격 증명
-
세션에서 사용되는 세션 자격 증명의 list. 이는 JSON 세션 자격 증명에서 파생된다.
- 만료 타임스탬프
-
이 세션이 제거되어야 하는 moment
- 세션 키 쌍
-
세션에서 사용하는 키 쌍. 개인 키는 안전한 방식으로 저장되어야 한다 (§ 2 보안 고려 사항 참조).
- 허용된 새로 고침 개시자
-
어떤 호스트가 DBSC 새로 고침을 시작할 수 있는지 설명하는 strings의 list. 자세한 내용은 § 8.3 요청이 새로 고침을 허용하는지 식별을 참조한다.
7.4. 세션 범위
세션 범위는 다음 items를 갖는 struct이다:7.5. 범위 명세
범위 명세는 다음 items를 갖는 struct이다:- type
-
"include" 또는 "exclude" 중 하나인 string. 이 struct에 정의된 항목이 범위에 추가되는지 제거되는지를 정의한다.
- host
-
이 범위 명세가 적용되기 위해 일치해야 하는 도메인 또는 도메인 패턴을 정의하는 string
- path
-
이 범위 명세의 경로 부분을 정의하는 string
7.6. 세션 자격 증명
세션 자격 증명은 다음 items를 갖는 struct이다:- name
-
자격 증명 쿠키의 이름을 정의하는 string
- attributes
-
자격 증명 쿠키의 다른 속성을 정의하는 string. 사용자 에이전트는 쿠키에 대해 제공하는 것과 동일한 기본값을 여기에도 제공해야 한다.
7.7. 등록 가능 origin 레이블
domain의 등록 가능 origin 레이블은 domain의 registrable domain의 첫 번째 domain label이거나, registrable domain이 null이면 null이다. 예를 들어,co.uk와
de가 모두 public suffixes라면, example.co.uk와
www.example.de의 등록 가능 origin 레이블은
모두 example이다.
8. 알고리즘
8.1. 세션 식별
URL (url)과 세션 식별자 (session identifier)가 주어지면, 이 알고리즘은 기기 바인딩 세션을 반환하거나, 그러한 세션이 없으면 null을 반환한다.
-
domain을 url의 host의 registrable domain으로 둔다.
-
domain sessions을 사용자 에이전트의 세션 저장소[domain]로 두고, 이를 id별 세션 맵으로 간주한다.
-
domain sessions[session identifier]를 null을 기본값으로 하여 with default 반환한다.
8.2. URL이 세션 범위에 있는지 식별
-
scope를 session의 세션 범위로 둔다.
-
scope의 include site가 true이면, URL의 origin이 scope의 origin과 same site가 아니면 "exclude"를 반환한다.
-
scope의 include site가 false이면, URL의 origin이 scope의 origin과 same origin이 아니면 "exclude"를 반환한다.
-
URL이 session의 새로 고침 URL과 일치하면 "exclude"를 반환한다.
-
"include"를 반환한다.
8.3. 요청이 새로 고침을 허용하는지 식별
-
session의 세션 범위의 include site가 true이고, request의 origin이 session의 세션 범위 origin과 same site이면 "allowed"를 반환한다.
-
session의 세션 범위의 include site가 false이고, request의 origin이 session의 세션 범위 origin과 same origin이면 "allowed"를 반환한다.
-
session의 허용된 새로 고침 개시자의 각 initiator pattern에 대해 For each:
-
request의 origin의 host와 initiator pattern에 대해 § 8.4 호스트가 패턴과 일치하는지 식별을 실행한 결과가 true이면 "allowed"를 반환한다.
-
-
"disallowed"를 반환한다.
8.4. 호스트가 패턴과 일치하는지 식별
-
pattern이 '*'와 같으면 true를 반환한다.
-
host string을 직렬화된 host로 둔다.
-
pattern이 '*'로 시작하고 host가 domain이면:
-
pattern이 '*.'로 시작하지 않으면 false를 반환한다.
-
host string이 pattern의 첫 글자를 제외한 나머지로 끝나면 true를 반환한다.
-
-
host string이 pattern과 같으면 true를 반환한다.
8.5. 새로 고침이 필요한 세션 식별
-
domain을 request의 url의 host의 registrable domain으로 둔다.
-
domain sessions을 사용자 에이전트의 세션 저장소[domain]로 두고, 이를 id별 세션 맵으로 간주한다.
-
domain sessions의 각 session에 대해 For each:
-
session의 만료 타임스탬프가 현재보다 이전이면, domain sessions에서 session을 제거하고 continue한다.
-
id를 session의 세션 식별자로 둔다.
-
tuple (domain, id)이 request의 지연된 기기 바인딩 세션 ids에 있으면, continue한다.
-
request의 URL과 session에 대해 § 8.2 URL이 세션 범위에 있는지 식별의 단계를 실행한다. 결과가 "include"가 아니면 continue한다.
-
request와 session에 대해 § 8.3 요청이 새로 고침을 허용하는지 식별의 단계를 실행한다. 결과가 "allowed"가 아니면 continue한다.
-
request와 session의 세션 자격 증명에 대해 § 8.6 세션 자격 증명이 누락되었는지 식별의 단계를 실행한다. 결과가 false이면 continue한다.
-
(domain, id)를 request의 지연된 기기 바인딩 세션 ids에 추가한다.
-
session의 만료 타임스탬프를 미래 타임스탬프로 설정한다. 만료 타임스탬프의 정확한 선택은 사용자 에이전트에 맡긴다. 최대 쿠키 수명에 맞추는 것이 권장된다.
-
session을 반환한다.
-
-
null을 반환한다.
8.6. 세션 자격 증명이 누락되었는지 식별
-
credentials의 각 credential에 대해 For each:
-
credential의 attributes를 가진 쿠키가 request에 첨부되지 않을 경우(section 5.4 of [COOKIES] 참조), continue한다.
-
request의 header list가 다음 조건을 모두 만족하는 cookie를 포함하면 continue한다:
-
cookie의 name이 credential의 name과 일치한다.
-
cookie의 다음 모든 속성이 credential의 attributes에 있는 것과 일치한다: Domain, Path, Secure, HttpOnly, SameSite.
-
-
true를 반환한다.
-
-
false를 반환한다.
8.7. challenge 캐시
response (response)가 주어지면, 이 알고리즘은 기기 바인딩 세션의 캐시된 challenge를 업데이트한다.
-
header name을 "
Secure-Session-Challenge"로 둔다. -
challenge list를 response의 header list에서 header name과 "list"를 사용해 get a structured field value를 실행한 결과로 둔다.
-
challenge list가 null이면 반환한다.
-
challenge list의 각 (challenge, params)에 대해 For each:
-
session id를 null로 둔다.
-
params["id"]가 존재하고 sf-string이면, session id를 params["id"]로 설정한다.
-
session id가 null이면 continue한다.
-
session을 response의 URL과 session id가 주어졌을 때 § 8.1 세션 식별을 실행한 결과로 둔다.
-
session이 null이면 continue한다.
-
session의 세션 자격 증명의 각 credential에 대해 For each:
-
credential의 attributes를 가진 쿠키를 response로 설정할 수 없으면(section 5.3 of [COOKIES] 참조), continue한다.
-
다음에 이 기기 바인딩 세션에서 DBSC proof를 보낼 때 사용할 수 있도록, challenge를 session의 캐시된 challenge로 저장한다.
-
Break한다.
-
8.8. 요청 보내기
사용자 에이전트는 바인딩 자격 증명이 누락될 때마다 이 단계를 수행하지만, 언제든지 수행할 수 있다. 바인딩 자격 증명이 만료되기 전에 사전에 요청을 보내면 DBSC의 지연 시간 비용을 최소화할 수 있다.
-
사용자 에이전트는 사용자나 사이트에 대한 서비스 거부를 방지하기 위해 이 요청을 건너뛸 수 있다. 예를 들어 이 세션이 과도한 TPM 작업을 요청하거나(사용자에게 해를 끼침), 새로 고침 엔드포인트가 최근 도달할 수 없었던 경우(사이트에 대한 서비스 거부 위험) 이러한 일이 발생할 수 있다. 사용자 에이전트가 이를 선택하면, 사이트에 이를 알리기 위해 originating request, 적절한 토큰(§ 9.5 `Secure-Session-Skipped` HTTP 헤더 필드의 옵션 참조), session id로 § 8.12 디버그 헤더 추가의 단계를 수행해야 한다.
-
terminate the session을 다음 단계가 있는 알고리즘으로 둔다:
-
session id가 null이면 반환한다.
-
destination의 host의 registrable domain과 식별자 session id를 가진 세션이 있다면, 사용자 에이전트의 세션 저장소에서 제거한다.
-
-
originating request의 URL의 origin이 destination의 origin과 same site가 아니면 반환한다.
-
signed challenge를 null로 둔다. challenge 또는 authorization이 non-null이면, DBSC proof를 생성하고, key pair로 서명한 뒤, 그 결과를 signed challenge에 저장한다.
-
HTTP fetch에서 사용할 request를 생성한다.
-
request의 method를 "POST"로 설정한다.
-
request의 URL을 destination으로 설정한다.
-
request의 redirect mode를 "follow"로 설정한다.
-
signed challenge가 non-null이면, ("Secure-Session-Response", signed challenge) 헤더를 request의 header list에 append한다.
-
session id가 non-null이면, ("Sec-Secure-Session-Id", session id) 헤더를 request의 header list에 append한다.
-
authorization이 non-null이면, ("Authorization", authorization) 헤더를 request의 header list에 append한다.
-
response를 request에 대해 HTTP fetch를 실행한 결과로 둔다.
-
response가 network error이거나, response의 status가 407 또는 429이면 반환한다.
-
response의 status가 300 이상 400 미만이면 반환한다.
-
response의 status가 403이면:
-
session id가 null이면 반환한다.
-
session을 destination과 session id에 대해 § 8.1 세션 식별의 단계를 실행한 결과로 둔다.
-
session이 null이면 반환한다.
-
그렇지 않으면, 원래 입력을 사용하되 challenge를 session의 캐시된 challenge로 대체하여 이 알고리즘을 다시 시작한다.
-
-
response의 status가 400 이상 500 미만이면, terminate the session하고 반환한다.
-
response의 status가 500 이상이면 반환한다. 사용자 에이전트는 새로 고침 엔드포인트의 일시적 장애로 인한 피해를 제한하기 위해, 이 세션의 후속 새로 고침 요청에 대해 backoff 메커니즘을 트리거하도록 선택할 수 있다.
-
session id가 non-null이고 response의 body가 비어 있으면 반환한다.
-
response, destination, session id, key pair에 대해 § 8.9 세션 생성을 호출한다.
8.9. 세션 생성
-
terminate the session을 다음 단계가 있는 알고리즘으로 둔다:
-
session id가 null이면 반환한다.
-
destination의 host의 registrable domain과 식별자 session id를 가진 세션이 있다면, 사용자 에이전트의 세션 저장소에서 제거한다.
-
-
JSON session을 response의 body를 JSON 세션 지시로 파싱한 결과로 둔다. 파싱이 실패하면 terminate the session하고 반환한다. 여기에는 모든 필수 키가 존재하는지 검증하는 것도 포함된다.
-
JSON session의 continue가 false이면, terminate the session하고 반환한다.
-
session identifier를 JSON session의 session_identifier로 둔다.
-
JSON scope를 JSON session의 scope로 둔다.
-
origin을 JSON scope의 origin이 있으면 그 값에서, 없으면 destination의 origin에서 구성한 origin으로 둔다.
-
JSON session의 refresh_url에 값이 없으면, refresh URL을 destination으로 둔다.
-
그렇지 않으면, refresh URL을 destination을 JSON session의 refresh_url 값으로 resolve한 결과로 둔다.
-
다음 검증을 수행한다. 하나라도 실패하면 terminate the session하고 반환한다.
-
destination domain을 destination의 host의 registrable domain으로 둔다.
-
JSON scope의 include_site가 true이면, 다음 검증을 수행한다. 하나라도 실패하면 terminate the session하고 반환한다.
-
origin의 host는 destination domain과 같아야 한다.
-
destination domain이 destination의 host와 같으면, 이 단계 안의 나머지 모든 검증을 건너뛴다.
-
session id가 non-null이면, 이 단계 안의 나머지 모든 검증을 건너뛴다.
-
그렇지 않으면, well known URL을 destination의 사본으로 두되, host를 destination domain으로 바꾸고, path를 "/.well-known/device-bound-sessions"로 바꾼 것으로 둔다.
-
well known response를 well known URL을 fetch한 결과로 둔다.
-
well known response의 status는 200이어야 한다.
-
well known response의 body는 JSON으로 인코딩된 dictionary여야 한다.
-
well known response의 body는 "registering_origins" 키를 포함해야 한다.
-
"registering_origins" 키의 값은 destination의 origin을 포함해야 한다.
-
-
session을 새 세션으로 둔다.
-
session의 세션 식별자를 session identifier로 설정한다.
-
session의 새로 고침 URL을 refresh URL로 설정한다.
-
session의 세션 범위를 origin이 origin이고, include site가 JSON scope의 include_site 값인 새 범위로 설정한다.
-
JSON scope의 scope_specification에 있는 각 JSON scope rule에 대해 For each:
-
JSON session의 credentials에 있는 각 JSON session credential에 대해 For each:
-
session credential을 새 세션 자격 증명으로 둔다.
-
JSON session credential의 type이 "cookie"가 아니면, terminate the session하고 반환한다.
-
session credential의 name을 JSON session credential의 name으로 설정한다.
-
session credential의 attributes를 JSON session credential의 attributes로 설정한다.
-
session credential을 session의 세션 자격 증명에 append한다.
-
-
session의 세션 키 쌍을 key pair로 설정한다.
-
session의 허용된 새로 고침 개시자를 JSON session의 allowed_refresh_initiators로 설정한다.
-
session의 만료 타임스탬프를 미래 타임스탬프로 설정한다. 만료 타임스탬프의 정확한 선택은 사용자 에이전트에 맡긴다. 최대 쿠키 수명에 맞추는 것이 권장된다.
-
session의 세션 자격 증명에 있는 각 credential에 대해 For each:
-
credential의 attributes를 가진 쿠키를 response로 설정할 수 없으면(section 5.3 of [COOKIES] 참조), continue한다.
-
기존 세션을 제거하기 위해 terminate the session을 호출한다.
-
사용자 에이전트의 세션 저장소[destination domain][session identifier]를 session으로 설정한다.
-
Break한다.
-
8.10. 세션 등록 처리
-
header name을 "
Secure-Session-Registration"로 둔다. -
registration list를 response의 header list에서 header name과 "list"를 사용해 get a structured field value를 실행한 결과로 둔다.
-
registration list가 null이면 반환한다.
-
registration list의 각 (registration entry, params)에 대해 For each:
-
registration entry가 sf-inner-list가 아니면, continue한다.
-
path를 params["path"]로 둔다.
-
challenge를 null로 두고, authorization을 null로 둔다.
-
params["challenge"] 또는 params["authorization"] 중 하나가 존재하지만 sf-string type이 아니면, continue한다.
-
params["challenge"]가 존재하면 challenge를 params["challenge"]로 설정한다.
-
params["authorization"]이 존재하면 authorization을 params["authorization"]으로 설정한다.
-
endpoint를 response의 URL을 기준으로 path를 resolve한 결과로 둔다.
-
key pair를 registration entry, params, endpoint에 대해 § 8.11 세션 키 쌍 생성을 실행한 결과로 둔다.
-
key pair가 null이면 반환한다.
-
request, key pair, endpoint, 세션 식별자 null, challenge, authorization으로 § 8.8 요청 보내기를 호출한다.
-
8.11. 세션 키 쌍 생성
Secure-Session-Registration`
헤더의 registration entry와 params, 그리고 등록 엔드포인트의
URL
(registration URL)을 받는다.
세션에서 사용할 키 쌍을 반환하거나, 가능한 키가 없으면 null을 반환한다.
-
algorithm list를 빈 list로 둔다.
-
registration entry의 각 algorithm에 대해 For each:
-
algorithm이 `
Secure-Session-Registration` 에서 지원되는 crypto algorithm을 나타내며 이 클라이언트에서 지원되면, algorithm을 algorithm list에 추가한다.
-
algorithm list가 비어 있으면 null을 반환한다.
-
params["provider_key"], params["provider_id"], 또는 params["provider_url"] 중 하나라도 존재하면:
-
세 키 중 하나라도 없으면 null을 반환한다.
-
permission을 "device-bound-session-key-sharing"에 대해 request permission to use를 수행한 결과로 둔다.
-
permission이
"denied"이면, null을 반환한다. -
provider URL을 params["provider_url"]에서 구성한 URL로 둔다.
-
provider origin을 provider URL의 origin으로 둔다.
-
provider origin이 opaque이면 null을 반환한다.
-
provider domain을 provider URL의 host의 registrable domain으로 둔다.
-
provider identifier를 params["provider_id"]로 둔다.
-
provider session을 사용자 에이전트의 세션 저장소[provider domain][provider identifier]에 있는 세션으로 둔다.
-
provider session이 null이면 null을 반환한다.
-
provider session의 세션 범위 origin이 provider origin과 same origin이 아니면 null을 반환한다.
-
provider session의 세션 키 쌍의 JWK thumbprint([RFC7638] 참조)가 base64로 인코딩되었을 때([RFC4648] 참조) params["provider_key"]와 일치하지 않으면 null을 반환한다.
-
provider well known URL을 provider URL의 사본으로 두되, path를 "/.well-known/device-bound-sessions"로 바꾼 것으로 둔다.
-
provider well known response를 provider well known URL을 fetch한 결과로 둔다. 다음 중 하나라도 성립하면 null을 반환한다:
-
provider well known response의 status가 200이 아니다.
-
provider well known response의 body가 JSON으로 인코딩된 dictionary가 아니다.
-
provider well known response의 body가 "provider_origin" 키를 포함한다.
-
provider well known response의 body가 "relying_origins" 키를 포함하지 않는다.
-
"relying_origins" 키의 값이 registration URL의 origin을 포함하지 않는다.
-
-
사용자 에이전트는 남용을 방지하기 위해 "relying_origins"의 등록 가능 origin 레이블 수에 상한을 두어야 한다.
-
relying well known URL을 registration URL의 사본으로 두되, path를 "/.well-known/device-bound-sessions"로 바꾼 것으로 둔다.
-
relying well known response를 relying well known URL을 fetch한 결과로 둔다. 다음 중 하나라도 성립하면 null을 반환한다:
-
provider session의 세션 키 쌍을 반환한다.
-
-
algorithm list에 대해 생성된 새 키 쌍을 반환한다.
8.12. 디버그 헤더 추가
-
value를 token 값을 가진 sf-token으로 둔다.
-
value의 sf-parameter "session_identifier"를 session id로 설정한다.
-
skipped header value를 request의 header list에 대해, header name "Secure-Session-Skipped", type "list"로 get a structured field value의 단계를 실행한 결과로 둔다.
-
skipped header value가 null이면, 이를 빈 sf-list로 설정한다.
-
value를 skipped header value에 append한다.
-
request의 header list에 ("Secure-Session-Skipped", skipped header value)를 주어 set a structured field value의 단계를 실행한다.
9. DBSC 형식
9.1.
`Secure-Session-Registration`
HTTP 헤더 필드
Secure-Session-Registration 헤더 필드는 서버가 클라이언트에서 새
기기 바인딩 세션을
시작하기 위해 response에서 사용할 수 있다.
`Secure-Session-Registration`
은 List Structured Header [RFC9651]이다. 그 ABNF는 다음과 같다:
SecureSessionRegistration = sf-list
목록의 각 item은 inner list여야 하며, inner list의 각 item은 지원되는 알고리즘(ES256, RS256)을 나타내는 sf-token이어야 한다. 현재는 이 두 값만 지원된다.
다음 sf-parameter가 정의된다:
-
키가 "path"이고 값이 sf-string인 sf-parameter. 등록 엔드포인트로 가는 경로를 전달한다. 이는 현재 URL을 기준으로 한 상대 경로일 수도 있고, 완전한 URL일 수도 있다. 이 매개변수가 없는 항목은 § 8.10 세션 등록 처리에서 무시된다.
-
키가 "challenge"이고 값이 sf-string인 sf-parameter. 세션 등록에 사용할 challenge를 전달한다.
-
키가 "authorization"이고 값이 sf-string인 sf-parameter. 이 sf-parameter는 등록 JWT로 복사된다.
-
키가 "provider_key"이고 값이 sf-string인 sf-parameter. 이 세션이 주어진 공개 키를 가진 세션과 키를 공유해야 함을 전달한다.
-
키가 "provider_id"이고 값이 sf-string인 sf-parameter. 이 세션이 주어진 세션 식별자를 가진 세션과 키를 공유해야 함을 전달한다.
-
키가 "provider_url"이고 값이 sf-string인 sf-parameter. 이 세션이 해당 사이트의 세션과 키를 공유해야 함을 전달한다.
Secure-Session-Registration`
의 몇 가지 예:
HTTP/1.1 200 OK Secure-Session-Registration: (ES256);path="reg";challenge="cv";authorization="ac"
HTTP/1.1 200 OK Secure-Session-Registration: (ES256 RS256);path="reg";challenge="cv"
HTTP/1.1 200 OK Secure-Session-Registration: (ES256);path="reg1";challenge="cv1";authorization="a" Secure-Session-Registration: (RS256);path="reg2";challenge="cv2";authorization="b"
HTTP/1.1 200 OK Secure-Session-Registration: (ES256);path="reg1";challenge="cv1";authorization="a", (RS256);path="reg2";challenge="cv2";authorization="b"
HTTP/1.1 200 OK Secure-Session-Registration: (ES256);path="reg1";challenge="cv1";provider_key="abc";provider_id="idp_id";provider_url="https://id_origin.example.com"
9.2.
`Secure-Session-Challenge`
HTTP 헤더 필드
Secure-Session-Challenge 헤더 필드는 서버가 클라이언트에 challenge를 보내기 위해
response에서 사용할 수 있다. 서버는 해당 challenge가 향후
`Secure-Session-Response`
헤더 내부의 DBSC proof에서 사용되기를
기대하거나, status가 403인 경우 쿠키 새로 고침 중에 새로 서명된
DBSC proof를 즉시 요청한다.
`Secure-Session-Challenge`
는 structured header이다. 그 값은 string이어야 한다.
그 ABNF는 다음과 같다:
SecureSessionChallenge = sf-string항목의 의미는 § 9.2.1 `Secure-Session-Challenge` structured header serialization에서 정의된다.
처리 단계는 § 8.7 challenge 캐시에 정의된다.
9.2.1. `Secure-Session-Challenge`
structured header 직렬화
`Secure-Session-Challenge`
는 Structured Field로 표현된다.[RFC9651]
이 표현에서 challenge는 string으로 표현된다.
Challenges는 "id"라는 이름의 sf-parameter를 가져야 하며, 그 값은
세션 식별자를 나타내는 string이어야 한다.
다른 모든
sf-parameter는 무시해야 한다.
Secure-Session-Challenge`
의 몇 가지 예:
HTTP/1.1 403 Forbidden Secure-Session-Challenge: "new challenge";id="my session"
HTTP/1.1 200 OK Secure-Session-Challenge: "new challenge";id="my session"
HTTP/1.1 200 OK Secure-Session-Challenge: "new challenge";id="my session 1" Secure-Session-Challenge: "another challenge";id="my session 2"
HTTP/1.1 200 OK Secure-Session-Challenge: "c1";id="session 1", "c2";id="session 2"
9.3.
`Secure-Session-Response`
HTTP 헤더 필드
Secure-Session-Response 헤더 필드는 사용자 에이전트가 세션 키 쌍의 개인 키를
클라이언트가 여전히 소유하고 있음을 증명하기 위해 DBSC proof를
서버에 보내는 데
request에서 사용할 수 있다.
Secure-Session-Response는 structured
header이다. 그 값은 string이어야 한다. 그 ABNF는 다음과 같다:
SecureSessionResponse = sf-string
이 string은 DBSC proof JWT만 포함해야 한다. 모든 sf-parameter는 무시해야 한다.
POST example.com/refresh Secure-Session-Response: "eyJhbGciOiJFUzI1NiIsInR5cCI6ImRic2Mrand0In0.eyJhdWQiOiJodHRwczovL2V4YW1wbGUuY29tL3JlZyIsImp0aSI6ImN2IiwiaWF0IjoiMTcyNTU3OTA1NSIsImp3ayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6IjZfR0Iydm9RMHFyb01oNk9sREZDRlNfU0pyaVFpMVBUdnZCT2hHWjNiSEkiLCJ5IjoiSWVnT0pVTHlFN1N4SF9DZDFLQ0VSN2xXQnZHRkhRLWgweHlqelVqRUlXRSJ9LCJhdXRob3JpemF0aW9uIjoiYWMifQ.6Fb_vVBDmfNghQiBmIGe8o7tBfYPbPCywhQruP0vIhxgmcJmuNTaMHeVn_M8ZnOm1_bzIitbZqCWEn-1Qzmtyw"
9.4.
`Sec-Secure-Session-Id`
HTTP 헤더 필드
Sec-Secure-Session-Id 헤더 필드는 사용자 에이전트가 현재 세션 식별자를 string 인수로 하여
현재 세션이 새로 고쳐지도록 요청하기 위해
request에서 사용할 수 있다.
`Sec-Secure-Session-Id`
는 structured header이다.
그 값은 string이어야 한다. 그 ABNF는 다음과 같다:
SecSecureSessionId = sf-string
이 string은 세션 식별자만 포함해야 한다. 모든 매개변수는 무시해야 한다.
9.5.
`Secure-Session-Skipped`
HTTP 헤더 필드
Secure-Session-Skipped 헤더 필드는 요청이 사용자 에이전트 정책으로 인해 의도적으로
바인딩 자격 증명을 누락하고 있음을 나타내기 위해
request에서 사용할 수 있다.
`Secure-Session-Skipped`
는 List Structured Header [RFC9651]이다. 그 ABNF는
다음과 같다:
SecureSessionSkipped = sf-list
목록의 각 item은 쿠키 새로 고침을 건너뛴 대략적인 이유를 나타내는 sf-token이어야 한다. 지원되는 유일한 값은 "unreachable", "server_error", "quota_exceeded"이다. 이러한 토큰은 다음 상황에서 사용해야 한다:
-
"server_error"는 서버의 응답(예: 500 status code)으로 인해 세션 새로 고침이 실패했음을 나타낸다.
-
"unreachable"은 서버에 도달할 수 없어 세션 새로 고침이 실패했음을 나타낸다.
-
"quota_exceeded"는 사용자 에이전트가 새로 고치지 않기로 선택하는 모든 경우 (예: 최근의 과도한 TPM 작업)를 포괄한다.
하나의 sf-parameter가 정의된다:
-
키가 "session_identifier"이고 값이 sf-string인 sf-parameter. 건너뛴 세션의 식별자를 전달한다.
GET example.com/requires_bound_cookie Secure-Session-Skipped: unreachable;session_identifier=123, quota_exceeded;session_identifier=456
9.6. JSON 세션 지시 형식
서버는 세션 등록 중 및 선택적으로 세션 새로 고침 중에 JSON 세션 지시를 보낸다. 응답이 세션 지시를 포함한다면, 이는 JSON 형식이어야 한다.JSON 객체의 루트에는 다음 키가 존재할 수 있다:
- session_identifier
-
세션 식별자를 나타내는 string. 등록 중에는 새로 생성된 세션의 식별자이다. continue 키의 값이 false인 경우를 제외하고 이 키는 존재해야 한다. 새로 고침 중에는 현재 세션의 식별자여야 한다. § 8.9 세션 생성을 참조한다.
- refresh_url
-
향후 새로 고침 요청에 사용할 URL을 나타내는 string. 이는 완전한 URL일 수도 있고, 이러한 지시를 제공하는 request를 기준으로 상대적일 수도 있다. 이 키는 OPTIONAL이며, 존재하지 않으면 향후 새로 고침 요청에 해당 request url이 사용된다.
- continue
-
세션이 계속 적용되어야 하는지 나타내는 boolean. 등록 및 새로 고침 엔드포인트는 세션을 종료하기 위해 이를 false로 설정할 수 있다. 이 키는 OPTIONAL이며, 존재하지 않으면 기본값은 true이다.
- scope
-
세션이 포괄하는 리소스를 설명하는 JSON 세션 범위. continue 키의 값이 false인 경우를 제외하고 이 키는 존재해야 한다.
- credentials
-
이 세션이 보호하는 쿠키를 설명하는 JSON 세션 자격 증명의 list. continue 키의 값이 false인 경우를 제외하고 이 키는 존재해야 한다.
- allowed_refresh_initiators
-
어떤 호스트가 DBSC 새로 고침을 시작할 수 있는지 설명하는 strings의 list. 자세한 내용은 § 8.3 요청이 새로 고침을 허용하는지 식별을 참조한다. 이 키는 OPTIONAL이며, 존재하지 않으면 기본값은 빈 list이다.
{ "session_identifier" : "session_id" , "refresh_url" : "/RefreshEndpoint" , "continue" : false , "scope" : { // Origin-scoped by default (i.e. https://example.com) "origin" : "https://example.com" , // Specifies to include https://*.example.com except excluded subdomains. // This can only be true if the origin's host is the root eTLD+1. "include_site" : true , "scope_specification" : [ { "type" : "include" , "domain" : "trusted.example.com" , "path" : "/only_trusted_path" }, { "type" : "exclude" , "domain" : "untrusted.example.com" , "path" : "/" }, { "type" : "exclude" , "domain" : "*.example.com" , "path" : "/static" } ] }, "credentials" : [{ "type" : "cookie" , // This specifies the exact cookie that this config applies to. Attributes // match the cookie attributes in RFC 6265bis and are parsed similarly to // a normal Set-Cookie line, using the same default values. // These SHOULD be equivalent to the Set-Cookie line accompanying this // response. "name" : "auth_cookie" , "attributes" : "Domain=example.com; Path=/; Secure; HttpOnly; SameSite=None" // Attributes Max-Age and Expires are ignored }], "allowed_refresh_initiators" : [ "example.com" , "*.example.com" , "site-embedding-example.com" ] }
9.7. JSON 세션 범위 지시 형식
서버는 등록 중 및 선택적으로 세션 새로 고침 중에 JSON 세션 지시 안에서 JSON 세션 범위를 보낸다.JSON 객체의 루트에는 다음 키가 존재할 수 있다:
- origin
-
세션이 적용되는 origin 또는 site를 나타내는 string. 이 키는 OPTIONAL이며, 존재하지 않으면 지시를 제공하는 URL의 origin이 사용된다. 등록 중에는 등록 URL이고 새로 고침 중에는 새로 고침 URL이다.
- include_site
-
세션이 origin-scoped(false)인지 site-scoped(true)인지를 나타내는 boolean. 이 키는 존재해야 한다. 이는 "scope_specification" 안의 모든 JSON 세션 범위 규칙보다 우선한다는 점에 유의한다 (§ 8.2 URL이 세션 범위에 있는지 식별 참조).
- scope_specification
-
기본 범위(전체 origin 또는 site)에 대한 수정을 설명하는 JSON 세션 범위 규칙의 list. 이 키는 OPTIONAL이며, 존재하지 않으면 빈 list가 사용된다.
9.8. JSON 세션 범위 규칙 형식
서버는 등록 중 및 선택적으로 세션 새로 고침 중에 JSON 세션 범위 안에서 JSON 세션 범위 규칙 객체의 list를 보낸다.각 JSON 세션 범위 규칙의 루트에는 다음 키가 존재할 수 있다:
- type
-
규칙이 대상을 포함하는지 제외하는지를 나타내는 string. 이 키는 존재해야 하며, 값은 "include" 또는 "exclude"여야 한다.
- domain
-
규칙과 일치해야 하는 도메인을 나타내는 string. 이는 wildcard를 포함할 수 있다 (§ 8.2 URL이 세션 범위에 있는지 식별 참조). 이 키는 OPTIONAL이며, 존재하지 않으면 모든 도메인과 일치하는 '*'가 된다.
- path
-
규칙과 일치해야 하는 path-prefixes를 나타내는 string. 이 키는 OPTIONAL이며, 존재하지 않으면 모든 경로와 일치하는 '/'가 된다. 자세한 의미는 § 8.2 URL이 세션 범위에 있는지 식별을 참조한다.
9.9. JSON 세션 자격 증명 형식
서버는 등록 중 및 선택적으로 세션 새로 고침 중에 JSON 세션 지시 안에서 JSON 세션 자격 증명 객체의 list를 보낸다.JSON 객체의 루트에는 다음 키가 존재할 수 있다:
- type
-
이 세션이 보호하는 자격 증명의 종류를 나타내는 string. 이 키는 존재해야 하며, 값은 "cookie"여야 한다.
- name
-
바인딩된 쿠키의 이름을 나타내는 string.
- attributes
-
보호되는 쿠키의 예상 속성을 포함하는 string. 이것이 어떻게 사용되는지에 대한 자세한 내용은 § 8.6 세션 자격 증명이 누락되었는지 식별을 참조한다.
9.10. DBSC Proof JWT 구문
DBSC proof는 클라이언트가 선택한 개인 키로 서명된(JSON Web Signature (JWS) 사용) JWT이다.DBSC proof의 헤더는 최소한 다음 sf-parameter를 포함해야 한다:
- typ
-
string. 이는 "dbsc+jwt"여야 한다.
- alg
-
이 JWT에 서명하는 데 사용된 알고리즘을 정의하는 string. 이는 [IANA.JOSE.ALGS]의 "RS256" 또는 "ES256"이어야 한다.
DBSC proof의 payload는 최소한 다음 claims를 포함해야 한다:
- aud
-
string. 이는 이 JWT가 원래 전송된 URL이어야 한다. 예: "https://example.com/refresh.html".
- jti
-
string. 이는 등록 헤더에서 보낸 challenge 값의 복사본이다.
- iat
-
JWT가 발급된 시간을 식별하는 double. 이는 JWT의 나이를 결정하는 데 사용할 수 있다. 그 값은 [RFC7519]에 설명된 NumericDate 값을 포함하는 number여야 한다.
- key
-
[RFC7517]에 지정된 JWK를 정의하는 dictionary.
또한 다음 claim은
`Secure-Session-Registration`
헤더 필드에 존재하는 경우 반드시 존재해야 한다:
- authorization
-
string. 이는 `
Secure-Session-Registration` 헤더 필드에 설정되어 있는 경우 해당 string의 직접 복사본이다. 이 string은 헤더에 포함하는 것이 OPTIONAL이지만, 존재한다면 클라이언트는 이를 DBSC proof의 claim에 추가해야 한다는 점에 유의한다.
DBSC proof가 새로 고침 요청을 위한 것이라면, 다음 claim은 반드시 존재해야 한다:
// Header { "alg" : "ES256" , "typ" : "dbsc+jwt" } // Payload { "aud" : "https://example.com/reg" , "jti" : "cv" , "iat" : 1725579055.0 , "key" : { "kty" : "EC" , "crv" : "P-256" , "x" : "6_GB2voQ0qroMh6OlDFCFS_SJriQi1PTvvBOhGZ3bHI" , "y" : "IegOJULyE7SxH_Cd1KCER7lWBvGFHQ-h0xyjzUjEIWE" }, "authorization" : "ac" }
다음과 같은 서버의 response header를 가진 http://example.com/page.html에 대한 응답을 기반으로 한다:
HTTP/1.1 200 OK Secure-Session-Registration: (ES256);path="reg";challenge="cv";authorization="ac"
10. 다른 명세에 대한 변경 사항
10.1. Fetch 명세에 대한 변경 사항
이 명세는 HTTP-network-or-cache fetch 알고리즘의 업데이트를 요구한다. request는 다음으로 구성된 tuples의 list인 지연된 기기 바인딩 세션 ids를 가진다:
-
domain(registrable domain).
-
session identifier(string).
8.21단계에서 쿠키를 계산한 뒤, § 8.5 새로 고침이 필요한 세션 식별을 실행한다. 그 결과 session이 non-null이면:
-
httpRequest, 반환된 session의 세션 키 쌍, 새로 고침 URL, 세션 식별자, 캐시된 challenge, 빈 authorization으로 § 8.8 요청 보내기를 실행한다.
-
원래 입력으로 HTTP-network-or-cache fetch를 다시 시작한다.
이 명세는 또한 새 헤더를 처리하기 위한 두 개의 새 호출을 요구한다. 현재 HTTP-network fetch의 14단계 이후에 다음 단계를 실행한다:
-
§ 8.10 세션 등록 처리와 § 8.7 challenge 캐시를 실행한다.
10.2. Clear Site Data 명세에 대한 변경 사항
이 명세는 Clear Site Data 명세 section 4.2.5 Clear DOM-accessible storage for origin가 origin과 일치하는 범위의 모든 기기 바인딩 세션을 지우도록 요구한다. 또한 section 4.2.4를 업데이트하여 등록된 도메인과 일치하는 사이트의 기기 바인딩 세션을 지우도록 요구한다.
11. IANA 고려 사항
영구 message header field registry는 다음 등록으로 업데이트되어야 한다: [RFC3864]
11.1. Secure-Session-Challenge
- 헤더 필드 이름
- Secure-Session-Challenge
- 적용 가능한 프로토콜
- http
- 상태
- draft
- 작성자/변경 관리자
- W3C
- 명세 문서
- 이 명세(§ 9.2 `Secure-Session-Challenge` HTTP 헤더 필드 참조)
11.2. Sec-Secure-Session-Id
- 헤더 필드 이름
- Sec-Secure-Session-Id
- 적용 가능한 프로토콜
- http
- 상태
- draft
- 작성자/변경 관리자
- W3C
- 명세 문서
- 이 명세(§ 9.4 `Sec-Secure-Session-Id` HTTP 헤더 필드 참조)
11.3. Secure-Session-Registration
- 헤더 필드 이름
- Secure-Session-Registration
- 적용 가능한 프로토콜
- http
- 상태
- draft
- 작성자/변경 관리자
- W3C
- 명세 문서
- 이 명세(§ 9.1 `Secure-Session-Registration` HTTP 헤더 필드 참조)
11.4. Secure-Session-Response
- 헤더 필드 이름
- Secure-Session-Response
- 적용 가능한 프로토콜
- http
- 상태
- draft
- 작성자/변경 관리자
- W3C
- 명세 문서
- 이 명세(§ 9.3 `Secure-Session-Response` HTTP 헤더 필드 참조)
11.5. Secure-Session-Skipped
- 헤더 필드 이름
- Secure-Session-Skipped
- 적용 가능한 프로토콜
- http
- 상태
- draft
- 작성자/변경 관리자
- W3C
- 명세 문서
- 이 명세(§ 9.5 `Secure-Session-Skipped` HTTP 헤더 필드 참조)
11.6. device-bound-sessions Well Known
Well-Known URI registry는 /.well-known/device-bound-sessions를 포함하도록 업데이트되어야 한다.
이 엔드포인트는 JSON으로 인코딩된 dictionary를 제공해야 한다. 세 가지 키가 정의된다:
-
"registering_origins"는 strings의 list이다. 이는 전체 사이트에 대한 세션을 등록할 수 있는 origins를 포함한다.
-
"relying_origins"는 strings의 list이다. 이는 이 사이트의 세션과 키를 공유할 때 Relying Party(RP)가 될 수 있는 origins를 포함한다.
-
"provider_origin"은 optional string이다. 이 origin이 Relying Party로 사용될 때 Session Provider의 origin을 포함한다.
https://example.com/.well-known/device-bound-sessions가 다음을 제공한다고 하자
{ "registering_origins" : [ "https://subdomain.example.com" , "https://subdomain.example.com:8000" , ], "relying_origins" : [ "https://example.co.uk" , "https://example-partner.com" , ], }
그러면 등록 요청은 다음 중 하나가 true인 경우에만 site-scoped session을 정의할 수 있다:
-
등록 엔드포인트의 host가
example.com이다 -
등록 엔드포인트의 origin이
https://subdomain.example.com이다 -
등록 엔드포인트의 origin이
https://subdomain.example.com:8000이다
또한 https://example.co.uk와 https://example-partner.com은
https://example.com의 세션과 키를 공유할 수 있으므로, 해당 사이트들이 연합 로그인과 DBSC 보호를
모두 달성할 수 있다. 이를 위해 두 사이트는 각각의
.well-known 파일에서 다음 항목을 제공해야 한다:
{ "provider_origin" : "https://example.com/" }