← All issues

document.open() security origin aliasing fix

cbbbc03

Source/WebCore/dom/Document.cpp

- if (callerDocument)
- setSecurityOriginPolicy(callerDocument->securityOriginPolicy());
+ // 각 document는 자체 origin을 유지합니다. same-origin 검사는 이 함수 상단의
+ // check로 강제되며, origin 객체를 공유하는 방식으로 처리하지 않습니다.

SecurityOrigin은 WebKit에서 same-origin policy 집행의 기준이 되는 객체로, 문서가 접근할 수 있는 리소스를 결정합니다. SecurityOriginPolicySecurityOrigin을 소유하고 감싸는 래퍼로, 각 문서에 연결됩니다. 일반적으로 모든 문서는 독립적인 SecurityOriginPolicy를 가집니다. document.open()은 문서의 content를 재초기화하지만, origin 소유권을 변경해서는 안 됩니다.

문제는 Document::open()이 caller 문서의 policy 객체를 인자로 setSecurityOriginPolicy()를 호출하여 공유 reference를 생성했다는 점입니다. document.domain 쓰기는 내부 SecurityOrigin을 직접 변형하기 때문에, caller에서의 변경이 명시적인 cross-document 연산 없이도 callee에 조용히 반영되었습니다.

Before:
  CallerDoc ──► SecurityOriginPolicy ◄── CalleeDoc   (shared object)
                      │
               SecurityOrigin
          document.domain = 'x'   ← mutation visible through BOTH handles

After:
  CallerDoc ──► SecurityOriginPolicy     CalleeDoc ──► SecurityOriginPolicy
                      │                                       │
               SecurityOrigin (A)                    SecurityOrigin (B)
          document.domain = 'x'                  (unaffected, independent)

수정은 단 한 줄을 제거하는 것입니다. setSecurityOriginPolicy() 호출이 삭제되었습니다. same-origin 집행은 origin 객체 공유가 아니라 Document::open() 상단의 check에 의존합니다. 이는 HTML 명세 및 Gecko, Blink의 동작과 일치합니다.

이는 same-origin policy 경계 위반에 해당합니다. caller가 자신의 document.domain을 변형하면, 단일 SecurityOrigin 인스턴스를 공유하는 탓에 그 변형이 열었던 문서에 조용히 전파되었습니다. 이 aliasing으로 인해, 이미 deprecated되고 위험한 기능인 document.domain relaxation의 영향 범위가 의도보다 훨씬 넓어졌습니다. 공유된 mutable reference를 통해 문서 경계를 넘는 형태였습니다.

🔒

The fix rests on assumptions about origin correctness and guard coverage — edge cases in both areas are worth auditing.

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