document.open() security origin aliasing fix
Source/WebCore/dom/Document.cpp
SecurityOrigin은 WebKit에서 same-origin policy 집행의 기준이 되는 객체로, 문서가 접근할 수 있는 리소스를 결정합니다. SecurityOriginPolicy는 SecurityOrigin을 소유하고 감싸는 래퍼로, 각 문서에 연결됩니다. 일반적으로 모든 문서는 독립적인 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의 동작과 일치합니다.
Significance
이는 same-origin policy 경계 위반에 해당합니다. caller가 자신의 document.domain을 변형하면, 단일 SecurityOrigin 인스턴스를 공유하는 탓에 그 변형이 열었던 문서에 조용히 전파되었습니다. 이 aliasing으로 인해, 이미 deprecated되고 위험한 기능인 document.domain relaxation의 영향 범위가 의도보다 훨씬 넓어졌습니다. 공유된 mutable reference를 통해 문서 경계를 넘는 형태였습니다.