Changeset 253486 in webkit
- Timestamp:
- Dec 13, 2019 10:39:40 AM (4 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r253483 r253486 1 2019-12-13 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [Clipboard API] Sanitize HTML and image data written using clipboard.write 4 https://bugs.webkit.org/show_bug.cgi?id=205188 5 <rdar://problem/57612968> 6 7 Reviewed by Darin Adler. 8 9 * editing/async-clipboard/sanitize-when-reading-markup-expected.txt: Added. 10 * editing/async-clipboard/sanitize-when-reading-markup.html: Added. 11 12 Add a test to verify that markup is sanitized when copying and pasting across different security origins. 13 14 * editing/async-clipboard/sanitize-when-writing-image-expected.txt: Added. 15 * editing/async-clipboard/sanitize-when-writing-image.html: Added. 16 17 Add a test to verify that "image/png" data is sanitized, and one or more written image data that cannot be 18 decoded results in the promise being rejected. 19 20 * platform/mac-wk1/TestExpectations: 21 * platform/win/TestExpectations: 22 1 23 2019-12-13 Chris Dumez <cdumez@apple.com> 2 24 -
trunk/LayoutTests/platform/mac-wk1/TestExpectations
r253434 r253486 73 73 editing/async-clipboard/clipboard-read-text-from-platform.html [ Skip ] 74 74 editing/async-clipboard/clipboard-read-text-same-origin.html [ Skip ] 75 editing/async-clipboard/sanitize-when-reading-markup.html [ Skip ] 75 76 76 77 imported/w3c/web-platform-tests/websockets/Close-1000-reason.any.html [ Pass Failure ] -
trunk/LayoutTests/platform/win/TestExpectations
r253239 r253486 1201 1201 webkit.org/b/203100 editing/async-clipboard/clipboard-read-text-same-origin.html [ Skip ] 1202 1202 webkit.org/b/203100 editing/async-clipboard/clipboard-read-text.html [ Skip ] 1203 webkit.org/b/203100 editing/async-clipboard/sanitize-when-writing-image.html [ Skip ] 1204 webkit.org/b/203100 editing/async-clipboard/sanitize-when-reading-markup.html [ Skip ] 1203 1205 1204 1206 webkit.org/b/140783 [ Release ] editing/pasteboard/copy-standalone-image.html [ Failure ImageOnlyFailure ] -
trunk/Source/WebCore/ChangeLog
r253483 r253486 1 2019-12-13 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [Clipboard API] Sanitize HTML and image data written using clipboard.write 4 https://bugs.webkit.org/show_bug.cgi?id=205188 5 <rdar://problem/57612968> 6 7 Reviewed by Darin Adler. 8 9 Sanitizes HTML ("text/html") and image ("image/png") content when writing to the platform pasteboard using the 10 clipboard API. See below for more details. 11 12 Tests: editing/async-clipboard/sanitize-when-reading-markup.html 13 editing/async-clipboard/sanitize-when-writing-image.html 14 ClipboardTests.WriteSanitizedMarkup 15 16 * Modules/async-clipboard/ClipboardItemBindingsDataSource.cpp: 17 (WebCore::ClipboardItemBindingsDataSource::ClipboardItemTypeLoader::sanitizeDataIfNeeded): 18 19 Add a new helper method to sanitize `m_data` after loading finishes, but before invoking the completion handler 20 to notify the data source about the clipboard data. Currently, we support writing "text/plain", "text/uri-list", 21 "text/html" and "image/png"; we sanitize HTML by stripping away hidden content such as comments, script, and 22 event listeners, and sanitize image data by painting it into a new graphics context and re-encoding the rendered 23 contents as an image. 24 25 (WebCore::ClipboardItemBindingsDataSource::ClipboardItemTypeLoader::invokeCompletionHandler): 26 * Modules/async-clipboard/ClipboardItemBindingsDataSource.h: 27 * platform/PlatformPasteboard.h: 28 * platform/cocoa/PasteboardCocoa.mm: 29 (WebCore::cocoaTypeToImageType): 30 * platform/ios/PlatformPasteboardIOS.mm: 31 (WebCore::PlatformPasteboard::platformPasteboardTypeForSafeTypeForDOMToReadAndWrite): 32 33 Adjust these helpers to map "image/png" to the platform PNG type on iOS ("public.png"). The extra 34 IncludeImageTypes argument was added to avoid considering "image/png" a web-safe type for writing and reading 35 when exercising DataTransfer APIs, which currently don't support reading the "image/png" MIME type. In the 36 future, we should consider adding support for image sanitization when using DataTransfer.setData or 37 DataTransferItemList.add, and then remove this flag. 38 39 (WebCore::createItemProviderRegistrationList): 40 * platform/mac/LegacyNSPasteboardTypes.h: 41 42 Add an entry for legacyPNGPasteboardType on macOS, and replace one use of it in PasteboardCocoa.mm. 43 44 (WebCore::legacyPNGPasteboardType): 45 * platform/mac/PlatformPasteboardMac.mm: 46 (WebCore::PlatformPasteboard::write): 47 (WebCore::PlatformPasteboard::platformPasteboardTypeForSafeTypeForDOMToReadAndWrite): 48 49 Likewise, map "image/png" to legacyPNGPasteboardType() on macOS, which was added above. 50 51 (WebCore::createPasteboardItem): 52 1 53 2019-12-13 Chris Dumez <cdumez@apple.com> 2 54 -
trunk/Source/WebCore/Modules/async-clipboard/ClipboardItemBindingsDataSource.cpp
r252658 r253486 27 27 #include "ClipboardItemBindingsDataSource.h" 28 28 29 #include "BitmapImage.h" 29 30 #include "Blob.h" 30 31 #include "Clipboard.h" … … 33 34 #include "FileReaderLoader.h" 34 35 #include "Frame.h" 36 #include "GraphicsContext.h" 37 #include "ImageBuffer.h" 35 38 #include "JSBlob.h" 36 39 #include "JSDOMPromise.h" … … 253 256 } 254 257 258 void ClipboardItemBindingsDataSource::ClipboardItemTypeLoader::sanitizeDataIfNeeded() 259 { 260 if (m_type == "text/html"_s) { 261 String markupToSanitize; 262 if (WTF::holds_alternative<Ref<SharedBuffer>>(m_data)) { 263 auto& buffer = WTF::get<Ref<SharedBuffer>>(m_data); 264 markupToSanitize = String::fromUTF8(buffer->data(), buffer->size()); 265 } else if (WTF::holds_alternative<String>(m_data)) 266 markupToSanitize = WTF::get<String>(m_data); 267 268 if (markupToSanitize.isEmpty()) 269 return; 270 271 m_data = { sanitizeMarkup(markupToSanitize) }; 272 } 273 274 if (m_type == "image/png"_s) { 275 RefPtr<SharedBuffer> bufferToSanitize; 276 if (WTF::holds_alternative<Ref<SharedBuffer>>(m_data)) 277 bufferToSanitize = WTF::get<Ref<SharedBuffer>>(m_data).ptr(); 278 else if (WTF::holds_alternative<String>(m_data)) 279 bufferToSanitize = utf8Buffer(WTF::get<String>(m_data)); 280 281 if (!bufferToSanitize || bufferToSanitize->isEmpty()) 282 return; 283 284 auto bitmapImage = BitmapImage::create(); 285 bitmapImage->setData(WTFMove(bufferToSanitize), true); 286 auto imageBuffer = ImageBuffer::create(bitmapImage->size(), Unaccelerated); 287 if (!imageBuffer) { 288 m_data = { nullString() }; 289 return; 290 } 291 292 imageBuffer->context().drawImage(bitmapImage.get(), FloatPoint::zero()); 293 m_data = { SharedBuffer::create(imageBuffer->toData("image/png"_s)) }; 294 } 295 } 296 255 297 void ClipboardItemBindingsDataSource::ClipboardItemTypeLoader::invokeCompletionHandler() 256 298 { 257 if (auto completion = WTFMove(m_completionHandler)) 299 if (auto completion = WTFMove(m_completionHandler)) { 300 sanitizeDataIfNeeded(); 258 301 completion(); 302 } 259 303 } 260 304 -
trunk/Source/WebCore/Modules/async-clipboard/ClipboardItemBindingsDataSource.h
r252658 r253486 74 74 ClipboardItemTypeLoader(const String& type, CompletionHandler<void()>&&); 75 75 76 void sanitizeDataIfNeeded(); 76 77 void invokeCompletionHandler(); 77 78 -
trunk/Source/WebCore/platform/PlatformPasteboard.h
r251421 r253486 67 67 WEBCORE_EXPORT static String uniqueName(); 68 68 69 WEBCORE_EXPORT static String platformPasteboardTypeForSafeTypeForDOMToReadAndWrite(const String& domType); 69 enum class IncludeImageTypes : bool { No, Yes }; 70 static String platformPasteboardTypeForSafeTypeForDOMToReadAndWrite(const String& domType, IncludeImageTypes = IncludeImageTypes::No); 70 71 71 72 WEBCORE_EXPORT void getTypes(Vector<String>& types); -
trunk/Source/WebCore/platform/cocoa/PasteboardCocoa.mm
r251421 r253486 69 69 return ImageType::TIFF; 70 70 #if PLATFORM(MAC) 71 if (cocoaType == "Apple PNG pasteboard type") // NSPNGPboardType71 if (cocoaType == String(legacyPNGPasteboardType())) // NSPNGPboardType 72 72 return ImageType::PNG; 73 73 #endif -
trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm
r252450 r253486 323 323 } 324 324 325 String PlatformPasteboard::platformPasteboardTypeForSafeTypeForDOMToReadAndWrite(const String& domType )325 String PlatformPasteboard::platformPasteboardTypeForSafeTypeForDOMToReadAndWrite(const String& domType, IncludeImageTypes includeImageTypes) 326 326 { 327 327 if (domType == "text/plain") … … 333 333 if (domType == "text/uri-list") 334 334 return kUTTypeURL; 335 336 if (includeImageTypes == IncludeImageTypes::Yes && domType == "image/png") 337 return kUTTypePNG; 335 338 336 339 return { }; … … 604 607 605 608 NSString *stringValue = value; 606 auto cocoaType = PlatformPasteboard::platformPasteboardTypeForSafeTypeForDOMToReadAndWrite(type ).createCFString();609 auto cocoaType = PlatformPasteboard::platformPasteboardTypeForSafeTypeForDOMToReadAndWrite(type, PlatformPasteboard::IncludeImageTypes::Yes).createCFString(); 607 610 if (UTTypeConformsTo(cocoaType.get(), kUTTypeURL)) 608 611 [representationsToRegister addRepresentingObject:[NSURL URLWithString:stringValue]]; -
trunk/Source/WebCore/platform/mac/LegacyNSPasteboardTypes.h
r235935 r253486 87 87 } 88 88 89 inline NSString *legacyPNGPasteboardType() 90 { 91 return @"Apple PNG pasteboard type"; 92 } 93 89 94 } // namespace WebCore 90 95 -
trunk/Source/WebCore/platform/mac/PlatformPasteboardMac.mm
r252627 r253486 227 227 NSMutableArray *types = [NSMutableArray array]; 228 228 data.forEachType([&] (auto& type) { 229 NSString *platformType = platformPasteboardTypeForSafeTypeForDOMToReadAndWrite(type );229 NSString *platformType = platformPasteboardTypeForSafeTypeForDOMToReadAndWrite(type, IncludeImageTypes::Yes); 230 230 if (platformType.length) 231 231 [types addObject:platformType]; … … 238 238 [m_pasteboard declareTypes:types owner:nil]; 239 239 240 data.forEachPlatformString([&] (auto& type, auto& data) { 241 auto platformType = platformPasteboardTypeForSafeTypeForDOMToReadAndWrite(type); 242 ASSERT(!platformType.isEmpty()); 243 if (!platformType.isEmpty()) 244 [m_pasteboard setString:data forType:platformType]; 240 data.forEachPlatformStringOrBuffer([&] (auto& type, auto& stringOrBuffer) { 241 auto platformType = platformPasteboardTypeForSafeTypeForDOMToReadAndWrite(type, IncludeImageTypes::Yes); 242 if (platformType.isEmpty()) 243 return; 244 245 if (WTF::holds_alternative<Ref<SharedBuffer>>(stringOrBuffer)) { 246 if (auto platformData = WTF::get<Ref<SharedBuffer>>(stringOrBuffer)->createNSData()) 247 [m_pasteboard setData:platformData.get() forType:platformType]; 248 } else if (WTF::holds_alternative<String>(stringOrBuffer)) { 249 auto string = WTF::get<String>(stringOrBuffer); 250 if (!!string) 251 [m_pasteboard setString:string forType:platformType]; 252 } 245 253 }); 246 254 … … 258 266 } 259 267 260 String PlatformPasteboard::platformPasteboardTypeForSafeTypeForDOMToReadAndWrite(const String& domType )268 String PlatformPasteboard::platformPasteboardTypeForSafeTypeForDOMToReadAndWrite(const String& domType, IncludeImageTypes includeImageTypes) 261 269 { 262 270 if (domType == "text/plain") … … 268 276 if (domType == "text/uri-list") 269 277 return legacyURLPasteboardType(); 278 279 if (includeImageTypes == IncludeImageTypes::Yes && domType == "image/png") 280 return legacyPNGPasteboardType(); 270 281 271 282 return { }; … … 475 486 return; 476 487 477 if (WTF::holds_alternative<String>(stringOrBuffer)) {478 [item setString:WTF::get<String>(stringOrBuffer) forType:platformType];479 return;480 }481 482 488 if (WTF::holds_alternative<Ref<SharedBuffer>>(stringOrBuffer)) { 483 489 if (auto platformData = WTF::get<Ref<SharedBuffer>>(stringOrBuffer)->createNSData()) 484 490 [item setData:platformData.get() forType:platformType]; 491 } else if (WTF::holds_alternative<String>(stringOrBuffer)) { 492 auto string = WTF::get<String>(stringOrBuffer); 493 if (!!string) 494 [item setString:string forType:platformType]; 485 495 } 486 496 }); -
trunk/Tools/ChangeLog
r253484 r253486 1 2019-12-13 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [Clipboard API] Sanitize HTML and image data written using clipboard.write 4 https://bugs.webkit.org/show_bug.cgi?id=205188 5 <rdar://problem/57612968> 6 7 Reviewed by Darin Adler. 8 9 Adds an API test to verify that the markup written to the platform pasteboard on macOS and iOS is sanitized, and 10 does not contain hidden content, such as script elements. 11 12 * TestWebKitAPI/Tests/WebKitCocoa/ClipboardTests.mm: 13 (-[TestWKWebView writeString:toClipboardWithType:]): 14 (readMarkupFromPasteboard): 15 * TestWebKitAPI/Tests/WebKitCocoa/clipboard.html: 16 1 17 2019-12-13 Kate Cheney <katherine_cheney@apple.com> 2 18 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ClipboardTests.mm
r251479 r253486 30 30 #import "UIKitSPI.h" 31 31 #import <CoreServices/CoreServices.h> 32 #import <WebCore/LegacyNSPasteboardTypes.h> 32 33 #import <WebKit/WKPreferencesPrivate.h> 33 34 #import <WebKit/_WKExperimentalFeature.h> … … 48 49 }]; 49 50 [self evaluateJavaScript:@"readClipboard()" completionHandler:nil]; 51 TestWebKitAPI::Util::run(&done); 52 } 53 54 - (void)writeString:(NSString *)string toClipboardWithType:(NSString *)type 55 { 56 __block bool done = false; 57 [self performAfterReceivingMessage:@"wroteStringToClipboard" action:^{ 58 done = true; 59 }]; 60 [self evaluateJavaScript:[NSString stringWithFormat:@"writeStringToClipboard(`%@`, `%@`)", type, string] completionHandler:nil]; 50 61 TestWebKitAPI::Util::run(&done); 51 62 } … … 119 130 } 120 131 132 static NSString *readMarkupFromPasteboard() 133 { 134 #if PLATFORM(MAC) 135 NSData *rawData = [NSPasteboard.generalPasteboard dataForType:WebCore::legacyHTMLPasteboardType()]; 136 #elif PLATFORM(IOS) 137 NSData *rawData = [UIPasteboard.generalPasteboard dataForPasteboardType:(__bridge NSString *)kUTTypeHTML]; 138 #endif 139 return [[[NSString alloc] initWithData:rawData encoding:NSUTF8StringEncoding] autorelease]; 140 } 141 121 142 TEST(ClipboardTests, ReadMultipleItems) 122 143 { … … 134 155 EXPECT_WK_STREQ("https://webkit.org/", [webView stringByEvaluatingJavaScript:@"clipboardData[3]['text/html'].querySelector('a').href"]); 135 156 } 157 158 TEST(ClipboardTests, WriteSanitizedMarkup) 159 { 160 auto webView = createWebViewForClipboardTests(); 161 [webView writeString:@"<script>/* super secret */</script>This is a test." toClipboardWithType:@"text/html"]; 162 163 NSString *writtenMarkup = readMarkupFromPasteboard(); 164 EXPECT_TRUE([writtenMarkup containsString:@"This is a test."]); 165 EXPECT_FALSE([writtenMarkup containsString:@"super secret"]); 166 EXPECT_FALSE([writtenMarkup containsString:@"<script>"]); 167 } -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/clipboard.html
r251377 r253486 29 29 exception = null; 30 30 31 async function writeStringToClipboard(type, string) { 32 try { 33 const itemData = {}; 34 itemData[type] = string; 35 await navigator.clipboard.write([new ClipboardItem(itemData)]); 36 } catch (e) { 37 exception = e; 38 } finally { 39 webkit.messageHandlers.testHandler.postMessage("wroteStringToClipboard"); 40 } 41 } 42 31 43 async function readClipboard() { 32 44 try {
Note: See TracChangeset
for help on using the changeset viewer.