[1] didSameDocumentNavigationForFrame accepts arbitrary URL, enabling address bar spoofing
renderer가 제공한 문자열을 origin check 없이 표시 URL에 반영하는 UIProcess IPC를 수정한 fix입니다. web content에서 이 경로에 도달하는 것만으로 address bar의 임의 origin을 spoofing할 수 있어 High로 평가합니다.
WebPageProxy::didSameDocumentNavigationForFrameViaJS는 history.pushState/replaceState 방식의 navigation 이후, WebContent process가 전달한 임의의 well-formed URL을 그대로 frame의 새 URL로 사용했습니다. 기존의 MESSAGE_CHECK_URL은 URL의 파싱 가능 여부만 검증할 뿐, same-document navigation이 반드시 same-origin이어야 한다는 조건은 전혀 강제하지 않았습니다.
Source/WebKit/UIProcess/WebPageProxy.cpp
Patch Details
MESSAGE_CHECK_URL 직후에 MESSAGE_CHECK가 하나 추가되었습니다. 이 check는 URL이 file URL이거나, frame URL이 비어 있거나, scheme/host/port가 frame의 현재 URL과 일치해야 한다는 조건을 강제합니다. 조건을 충족하지 않으면 해당 WebContent process가 강제 종료됩니다.
WebContent→UIProcess trust boundary를 넘는 renderer 제공 URL에 대한 origin 동등성 check 누락.
Background
Same-document navigation은 문서를 언로드하지 않고 URL만 변경하는 방식으로, 주로 History API나 fragment 변경을 통해 이루어집니다. 명세상 새 URL은 현재 문서와 반드시 same-origin이어야 합니다. UIProcess는 address bar를 소유하고 per-WebFrameProxy URL을 관리하며, 이 URL이 address bar에 표시됩니다. MESSAGE_CHECK_URL은 URL의 파싱 가능 여부를 검증하고, protocolHostAndPortAreEqual은 origin을 정의하는 scheme/host/port 조합을 비교합니다.
Analysis
Fix 이전에는, 조작되거나 스크립트로 제어되는 WebContent process가 didSameDocumentNavigationForFrameViaJS를 임의의 URL로 호출할 수 있었습니다. UIProcess는 이를 그대로 frame의 현재 URL로 기록합니다. 그 결과 address bar에는 공격자가 선택한 origin이 표시되지만, 실제 문서는 여전히 공격자가 제어하는 상태입니다.
공격자는 제어 중인 임의의 페이지에서 same-document navigation을 유발해 목표 URL(예: https://victim.example/login)을 UIProcess에 전달합니다. renderer 측의 same-origin check가 없거나 우회된 상태이면, UIProcess는 해당 spoofed origin을 그대로 표시하게 됩니다. 이후 공격자는 credential 탈취를 목적으로 spoofed 사이트를 정밀하게 모방한 페이지를 사용자에게 제시할 수 있습니다. memory corruption primitive는 없으며, 이 취약점의 영향은 UI integrity bypass입니다.
이 vulnerability는 URL 표시 integrity를 뒷받침하는 WebContent→UIProcess trust boundary를 약화시킵니다. phishing 방어 UX 전체가 이 trust boundary 위에서 동작합니다.
Audit directions
- renderer 제공 데이터로 security UI 상태를 변경하는 UIProcess handler.
Source/WebKit/UIProcess/WebPageProxy.cpp에서WebPageProxy::did*ForFrame*및did*Navigation*handler 전체를 점검하여, URL이나 origin 인자를frame->url()과 재검증 없이 저장하는 경우를 찾아야 합니다.MESSAGE_CHECK_URL(을 검색하고, 각 호출 지점에 이에 대응하는 semantic check가 함께 있는지 확인해야 합니다. - renderer로부터 신뢰되는 spec 명시 불변 조건.
SameDocument,Fragment,Replace,InSameOrigin등 계약을 이름에 담은 IPC는 UIProcess가 재실행하지 않는 check를 암묵적으로 내포하는 경우가 많습니다. IPC handler를 해당 HTML spec 섹션과 교차 비교해야 합니다. protocolHostAndPortAreEqual사용의 일관성.Source/WebKit/UIProcess/전체를 검색하여 URL을 받지만 이 check를 생략하는 handler를 살펴봐야 합니다. history API 및 fragment navigation 경로를 특히 주의 깊게 점검할 필요가 있습니다.