The Curious Case
of Copy and Paste

Michał Bentkowski

securitum.pl

The Curious Case of Copy and Paste

Michał Bentkowski

securitum.pl

  • Security tester
  • Training instructor
  • Researcher
  • From 2016 to 2019 in Google Bug Bounty Hall of Fame TOP 10
  • Loving browser security
  • @SecurityMB
  • Pentests (web applications, mobile, network)
  • Trainings
  • Sekurak.pl

Assume you copy something from one page.

Then paste it in another.

Could anything go wrong?

DEMO #1

Let's talk about rich editors (WYSIWYG editors).

DEMO #2

Browsers attempt to sanitize pasted content.

I've found at least one bug in the clipboard sanitizers of all major browsers.

crbug.com/1011950

The issue exploited:

  • Elements merging
  • Foreign content shenanigans
.<math>.<xss style=display:block>.<style>.<a title="</style><img src onerror=alert(1)>">.

Q: Is Cross-Site Scripting the only risk when pasting untrusted content?

A: NO!

DEMO

Q: So browsers fixed all copy&paste issues. Are we safe now?

A: NO, again!

With JavaScript, editors can process pasted data, and bypass the browser's sanitizer.

With JavaScript, editors can process pasted data, and bypass the browser's sanitizer.

document.onpaste = ev => {
  ev.preventDefault();
  let html = ev.clipboardData.getData('text/html');
}

With JavaScript, editors can process pasted data, and bypass the browser's sanitizer.

document.onpaste = ev => {
  ev.preventDefault();
  let html = ev.clipboardData.getData('text/html');
  div.innerHTML = html; // 😱
}

Virtually every single WYSIWYG editor processes pasted data.

  • Sanitize content
  • Make the HTML more consistent
  • Delete unexpected markup
  • Handle markup from known editors

First example: TinyMCE

TinyMCE employs its own HTML parser.

The parser failed to recognize certain features of HTML5.

Assume that we have an HTML comment, started with "<!--". How do we end it?

-->

--!>

<!-- --!> <img src=1 onerror=alert(1)> -->

According to TinyMCE, everything is in a comment. The markup is thus harmless.

The browser parses it differently, leading to script execution.

Another popular editor is CKEditor.

<!--{cke_protected}--!><img src onerror=alert("cke_protected")>  -->

Root cause very similar to TinyMCE.

Third example: Froala

Froala processed the HTML as string (it is almost always a bad idea!)

a<u title='<noscript>"><img src onerror=alert(1)></noscript>'>b
a<u title='[FROALA.EDITOR.NOSCRIPT 0]'>b
a<u title="[FROALA.EDITOR.NOSCRIPT 0]">b
a<u title="<noscript>"><img src onerror=alert(1)></noscript>">b

That's all!

... but wait! What happened in Jira?!

Thanks!

Michał Bentkowski

@SecurityMB

https://securitum.pl

https://xss.academy

Made with Slides.com