← All issues

[5] [Navigation API] intercept() wrongly succeeds for cross-subdomain navigations

Severity: Medium | Component: WebCore Navigation API | b537a57

Medium으로 평가된 이유는 다음과 같습니다. 어떤 subdomain이든 형제 subdomain으로의 top-level navigation을 intercept할 수 있는 same-origin-policy 약화가 발생하고, 분석가의 신뢰도는 0.95입니다. 영향 범위는 web-platform 신뢰 위반에 한정되며, memory-safety primitive는 포함되지 않습니다.

Source/WebCore/page/Navigation.cpp

const URL& documentURL = document.url();
Ref documentOrigin = document.securityOrigin();
auto targetOrigin = SecurityOrigin::create(targetURL);
- bool isSameSite = documentOrigin->isSameSiteAs(targetOrigin);
- bool isSameOrigin = documentOrigin->isSameOriginAs(targetOrigin);
 
- // For cross-window navigation with document.domain, we need to check same-origin rather than same-site
- // to account for document.domain modifications that make cross-origin windows same-origin-domain
- if (!isSameSite && !isSameOrigin)
+ if (!documentOrigin->isSameOriginAs(targetOrigin))
+ return false;
+
+ if (documentURL.user() != targetURL.user() || documentURL.password() != targetURL.password())
return false;

documentCanHaveURLRewritten은 이전에 isSameSiteAsisSameOriginAs가 모두 false일 때만 false를 반환했습니다. 이는 spec이 요구하는 것보다 훨씬 약한 조건입니다. 이번 fix에서는 복합 조건을 두 개의 독립적인 검사로 교체했습니다. 하나는 엄격한 isSameOriginAs(scheme/host/port 동등성)이고, 나머지 하나는 URL::user()/URL::password() 비교입니다. NavigationAPI.mm에 추가된 두 개의 regression test는 cross-subdomain navigation(page1.example.compage2.example.com)과 userinfo가 다른 navigation을 다룹니다. 두 경우 모두 event.intercept()가 이제 SecurityError를 던지는지 검증합니다.

Spec이 요구하는 origin-equality 검사에서 same-origin 대신 same-site를 사용한 same-origin policy 완화.

Navigation API의 NavigateEvent.canIntercept boolean은 event.intercept() 호출 허용 여부를 결정합니다. canIntercept가 false인 상태에서 intercept()를 호출하면 SecurityError가 발생합니다. HTML spec에 따르면, canIntercept는 document의 URL이 목적지 URL로 "rewrite될 수 있는" 경우에만 true입니다. 이 조건은 scheme, username, password, host, port가 모두 동일할 것을 요구합니다. SecurityOrigin::isSameOriginAs는 (scheme, host, port)를 비교하는 반면, SecurityOrigin::isSameSiteAs는 registrable domain(eTLD+1)을 비교합니다. 따라서 isSameSiteAs는 공통 public suffix + 1 레이블 하위의 임의 subdomain 쌍에 대해 true를 반환합니다.

패치 이전 구현은 if (!isSameSite && !isSameOrigin) return false; 형태였습니다. De Morgan 법칙으로 풀면 "same-site이거나 same-origin이면 통과"를 의미하는 구조입니다. document.domain에 관한 오래된 inline 주석을 보면, 작성자의 원래 의도는 document.domain aliasing을 처리하기 위해 isSameOriginAs를 우선하는 것이었습니다. 다만 boolean 구조가 결과적으로 eTLD+1 전체로 과도하게 완화되었습니다.

🔒

An origin-comparison primitive in a high-level Web API was implemented with the wrong predicate — the trust-boundary implications and concrete attack scenarios are explored.

더 확인하려면 구독해 주세요

🔒

Several reusable audit patterns identified for finding the same class of mistake elsewhere in WebKit's web-platform security predicates.

더 확인하려면 구독해 주세요