Commit dfa9e425 authored by Xiaocheng Hu's avatar Xiaocheng Hu Committed by Commit Bot

Disallow pasting SVG use elements data URI

SVG use elements with data URI may carry arbitrary content. Hence, we
also sanitize it before pasting it into document.

Bug: 1040755
Change-Id: Iad8701174c7c0f13dc5affb9e011d645990ef754
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2119198
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#753349}
parent 96d8c59a
...@@ -67,6 +67,7 @@ ...@@ -67,6 +67,7 @@
#include "third_party/blink/renderer/core/loader/empty_clients.h" #include "third_party/blink/renderer/core/loader/empty_clients.h"
#include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/svg/svg_style_element.h" #include "third_party/blink/renderer/core/svg/svg_style_element.h"
#include "third_party/blink/renderer/core/svg/svg_use_element.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h" #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h" #include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
...@@ -803,6 +804,25 @@ static bool ContainsStyleElements(const DocumentFragment& fragment) { ...@@ -803,6 +804,25 @@ static bool ContainsStyleElements(const DocumentFragment& fragment) {
return false; return false;
} }
// Returns true if any svg <use> element is removed.
static bool StripSVGUseDataURLs(Node& node) {
if (IsA<SVGUseElement>(node)) {
SVGUseElement& use = To<SVGUseElement>(node);
SVGURLReferenceResolver resolver(use.HrefString(), use.GetDocument());
if (resolver.AbsoluteUrl().ProtocolIsData())
node.remove();
return true;
}
bool stripped = false;
for (Node* child = node.firstChild(); child;) {
Node* next = child->nextSibling();
if (StripSVGUseDataURLs(*child))
stripped = true;
child = next;
}
return stripped;
}
DocumentFragment* CreateSanitizedFragmentFromMarkupWithContext( DocumentFragment* CreateSanitizedFragmentFromMarkupWithContext(
Document& document, Document& document,
const String& raw_markup, const String& raw_markup,
...@@ -823,7 +843,13 @@ DocumentFragment* CreateSanitizedFragmentFromMarkupWithContext( ...@@ -823,7 +843,13 @@ DocumentFragment* CreateSanitizedFragmentFromMarkupWithContext(
return nullptr; return nullptr;
} }
if (!ContainsStyleElements(*fragment)) { bool needs_sanitization = false;
if (ContainsStyleElements(*fragment))
needs_sanitization = true;
if (StripSVGUseDataURLs(*fragment))
needs_sanitization = true;
if (!needs_sanitization) {
staging_document->GetPage()->WillBeDestroyed(); staging_document->GetPage()->WillBeDestroyed();
return CreateFragmentFromMarkupWithContext( return CreateFragmentFromMarkupWithContext(
document, raw_markup, fragment_start, fragment_end, base_url, document, raw_markup, fragment_start, fragment_end, base_url,
......
<!DOCTYPE html>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../assert_selection.js"></script>
<script>
// crbug.com/1040755
selection_test(
'<div contenteditable>|</div>',
selection => {
selection.setClipboardData(`
<svg>
<use href="data:application/xml,
<svg id=x>
<a href='javascript:alert(1)'>
<rect width=100 height=100 fill=blue />
</a>
</svg>#x">
</use>
</svg>`);
selection.document.execCommand('paste');
},
'<div contenteditable>|<svg></svg></div>',
'Paste blocks data URI in SVG use elements');
</script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment