[3] HTMLPlugInElement skips content extensions for embed/object loads
Severity: Medium | Component: WebCore HTML plugin elements | 7d28e39
<embed>/<object> 마크업을 사용할 수 있는 모든 페이지에서 항상 재현 가능한 content blocker bypass를 수정하는 패치입니다. 영향 범위는 memory corruption이 아닌 policy 우회(사용자 설치 규칙을 벗어나는 tracker/malware/광고 로드)이므로 Medium으로 평가합니다.
<embed>, <object> 요소를 통해 로드되는 plugin content가 content extension 규칙 검사를 전혀 거치지 않았습니다. 이번 수정에서는 HTMLPlugInElement::canLoadURL에 content extension 검사가 추가되어, updateWidget의 wouldLoadAsPlugIn 지연 처리 이전에 차단 대상 URL을 거부하도록 변경되었습니다.
Source/WebCore/html/HTMLPlugInElement.cpp
+#if ENABLE(CONTENT_EXTENSIONS)
+#include "ContentExtensionsBackend.h"
+#include "ResourceLoadInfo.h"
+#include "UserContentProvider.h"
+#endif
...
bool HTMLPlugInElement::canLoadURL(const URL& completeURL) const
{
+#if ENABLE(CONTENT_EXTENSIONS)
+ if (completeURL.isValid()) {
+ RefPtr page = document().page();
+ RefPtr frame = document().frame();
+ RefPtr documentLoader = frame ? frame->loader().documentLoader() : nullptr;
+ RefPtr userContentProvider = frame ? frame->userContentProvider() : nullptr;
+ if (page && documentLoader && userContentProvider) {
+ auto results = userContentProvider->processContentRuleListsForLoad(*page, completeURL, ContentExtensions::ResourceType::Other, *documentLoader);
+ if (results.shouldBlock())
+ return false;
+ }
+ }
+#endif
return !isProhibitedSelfReference(completeURL);
}
LayoutTests/http/tests/contentextensions/block-embed-element.html
+<embed src="http://127.0.0.1:8000/contentextensions/resources/should-load.html?should-be-blocked" type="text/html" width="100" height="100"></embed>
+<embed src="http://127.0.0.1:8000/media/resources/test.pdf?should-be-blocked" type="application/pdf" width="100" height="100"></embed>
Patch Details
ENABLE(CONTENT_EXTENSIONS)가 활성화된 상태에서 URL이 유효한 경우, canLoadURL은 document의 Page, DocumentLoader, UserContentProvider를 조회합니다. 이후 UserContentProvider::processContentRuleListsForLoad(page, completeURL, ContentExtensions::ResourceType::Other, documentLoader)를 호출하며, 반환된 결과의 shouldBlock()이 true이면 canLoadURL이 false를 반환하여 호출 측에서 plugin 리소스 로드를 건너뜁니다. 회귀 테스트는 .*should-be-blocked URL 필터에 매칭되는 <embed>, <object> 리소스를 로드하여, 표준 'Content blocker prevented frame...' 콘솔 메시지가 발생하는지 확인합니다.
리소스 로드 경로에서 content policy 검사가 누락되어, plugin element 클래스가 다른 element 유형에 균일하게 적용되는 필터를 우회할 수 있는 패턴.
Background
Content Extensions(content blocker라고도 불림)는 WebKit 확장 기능 및 관리 구성에 선언형 규칙 목록 API를 제공합니다. 각 규칙은 trigger(URL 패턴, 리소스 유형, 로드 컨텍스트)와 action(block, block-cookies, css-display-none, make-https)의 쌍으로 이루어집니다. 로드 발생 시 UserContentProvider::processContentRuleListsForLoad가 모든 활성 규칙 목록을 평가하고 집계된 actions를 반환하는데, 호출 측은 results.shouldBlock()을 확인해 로드를 중단할지 결정합니다. HTMLPlugInElement는 <embed>, <object>, 레거시 <applet>의 C++ 베이스 클래스로, canLoadURL은 두 서브클래스 모두가 updateWidget 진입 전에 반드시 거치는 단일 진입점입니다. SubframeLoader에 plugin 또는 subframe widget 생성을 요청하기 이전에 이 함수를 통과하는 셈입니다. 한편 <iframe>, <img>, <script>, XHR/fetch 로드에 대한 content extension 훅은 각각의 loader 경로에 별도로 구현되어 있습니다.
Analysis
HTMLPlugInElement::canLoadURL은 URL에 대해 self-reference 검사만 수행했을 뿐, content extension 엔진은 전혀 거치지 않았습니다. <img>, <script>, <iframe>, XHR 등 다른 리소스 유형에는 이미 규칙 목록 평가 경로가 존재했지만, plugin element 클래스에는 해당 경로가 연결되지 않은 상태였습니다.
Aaaa Aaaaa Aa Aaaaa Aaa a Aa Aaa Aaaaaa Aaaa Aaa Aaaaaaa Aaaaaaaa Aaaa Aaaa Aaaaaaa Aaaaaaaaaaaaaaaaaaa Aa Aaaaaaaa Aaaaaaaaaaaaaaaaaaaa Aaa Aaaaa Aa Aaaa a Aaa Aaa Aaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaa Aa Aaa Aa Aaaaa Aaaa Aaaaaa a Aa Aaaa Aaaaaaaa Aaaaaaa Aaa Aaaa Aa Aaaa Aaa Aaaa Aaaa Aaa Aaa Aaaa a Aaaaaa Aaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaa Aaaaa Aaa Aaaaaaaaaaaaaaaaa Aaa Aa Aaaa Aa Aaa Aaaaaa Aaa Aaaa Aaaaaaaaaaaaaaaaaaaaa Aaa Aa Aa Aaaaaaaaaa Aaaaaaaaaa Aaaa Aaaaa a Aaaa Aaaaaaaa Aaaaaaa Aaaaaaaaa Aaaaaaaaa Aa Aaaa Aaaaa Aaaaaa
a Aaaaaaaaaaaaaa Aa Aaaa Aaa Aaa Aaaa Aa Aa Aa Aaaa Aaa Aaaa Aaa Aaaa Aaaaaaa Aaaaaaa Aa Aaa Aaaaaaaa Aaaa Aaaaaaa Aaaaaaaaa Aaa Aaaaaa Aaaaaaa Aaa Aaa Aa Aaaaaaaaaaa Aaa Aa Aa Aaa Aa Aaaaa Aaaaaa Aa Aaaa Aaaaaaaaaa Aaaaaaaaaaaa a Aa Aaa Aaaa Aaaaaa Aaaaaaa Aaaaaaa Aaaaaaaaa Aaa Aa Aa Aaaa Aaaa Aa Aaa Aaaa Aaa Aaaa a Aaaaaaaaaaaaaa Aaaa Aaaaa Aaaaaa a Aaa Aa Aaa Aaaaa Aaaaa Aa Aaaaaa
🔒How content-policy enforcement is distributed across WebKit's resource-loading classes, and what this commit reveals about coverage gaps in user-installed filters
더 확인하려면 구독해 주세요
Audit directions
a Aaaaaaaaa Aaaaaaaaa Aaa Aaa Aa Aaa Aaa Aaaa Aaaa Aaaaaaa Aaaaaa Aaaa Aaaaaaaaaa Aa Aaaaaaaaaaaaaaaaa Aaa Aaaa Aa Aa Aaaaaaaaaaaaaaa Aaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aa Aaa Aaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaa Aaa Aaa Aaaaaa Aaaaaaaaaaaaaa Aa Aaaaaaaaaaaaaaaaaa Aaaaaaa Aaaaaa a Aaaaaa Aaaaaaaaaaaaaaa Aaa Aaaaa Aaa Aaa Aaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaa Aa a Aaa Aaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aa Aaa Aaaaaa
a Aaaaaaaaaaaaaaaa Aaaa Aa Aa Aaaaa a Aa Aaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaaaa Aaaaaa Aaa Aaaaaaa Aaa Aaa Aaa Aa Aa Aa Aa Aa Aaaa Aaaa Aaaaaa Aaa Aaa Aaaaaa Aaaaaaaaaa Aa Aaa Aaaaaaaaaaaaaaaaaaa Aaaaaaaa Aaa Aaa Aaa Aaaaa Aaaaaa
a Aaaaaaaaa Aaaaa Aaaa Aa Aaaaa Aaaaaaaaaaaa Aa Aaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aa Aa Aaaaaaaaa Aaaa Aaaaaaaaaaa Aaaa Aa Aaaa Aaaaaa Aa Aaaaa Aaaa Aaa Aaaaa Aa Aaaa Aaaa Aaaaa Aaaa
a a Aaa Aaaaaaaa Aa Aaa Aaaaa Aaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaa Aaaaaaa Aaaaaaaaa Aaa Aaaaa Aa Aaaa a Aa Aaa Aa Aaaaaaaaaaa Aaaaaaaa Aaaaaaaaaaaaaa Aaaaa Aaaaaa Aaa Aaaaaaa Aaaaaaaaaaa Aaa Aaaaaa
🔒Several reusable audit patterns identified for finding sibling bypasses in other element and loader classes, with concrete starting points
더 확인하려면 구독해 주세요