cure53 / DOMPurify

DOMPurify - a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG. DOMPurify works with a secure default, but offers a lot of configurability and hooks. Demo:
https://cure53.de/purify
Other
13.67k stars 698 forks source link

row of numbers are converted to a-tag on ipadOS #856

Closed meier-andersen closed 1 year ago

meier-andersen commented 1 year ago

Background & Context

When using DOMPurify from ipadOS 16.0.0 I experience that rows of numbers, etc. 110717-2214, are converted to an a-tag with href="tel:110717-2214".

Note that ipadOS behaves differently that iOS and macOS. This is only reproducable on ipadOS with Safari. When I try to reproduce it on either Android + Chrome, Win + Chrome or Win + Firefox, it does NOT occur. It can be reproduced in version 3.0.5 and 2.4.0 of DOMPurify.

Bug

Input

110717-2214

Given output

<a href="tel:110717-2214">1107172214</a>

Expected output

110717-2214

It can be reproduced in BrowserStack with iPad 10th, 16 and on real iPads with ipadOS16.6.

A working example can be created here: https://cure53.de/purify add "110717-2214" as a newline in the top of Dirty HTML and click "Sanitize textarea value, then write result to DOM " image

Please let me know if I can provide any more information

cure53 commented 1 year ago

Heya, thanks for filing this issue. From what we can see, the "linkification" happens after the sanitization took place, see screenshot. We are tempted to think that we cannot do much here.

live browserstack com_dashboard

Do you know if this iOS behavior is documented somewhere and can be controlled somehow, i.e. meta tag or alike? And, do you happen to know if this happens only when we sanitize or anytime someone inserts such string into the DOM?

meier-andersen commented 1 year ago

I do not unfortunately, but we have been using the package for a long time and the issue just started appearing, so it might be something new introduced with either Safari or ipadOS.

When using it in our production environment we don't get the value directly from the DOM. Instead we grab it with Vue and store it as a string, do some different modifications to it and then we sanitize it. After the sanitzation we don't put it back into the DOM either, so in our case it is treated as a string all the way.

We have also tried console logging and can see that before the sanitization, everything looks fine, but after calling .sanitize, the a-tag is added

Example from vue:

import DOMPurify from 'dompurify';

const title = this.$store.getters["hidden/path"];
let draft ={}
draft.label = DOMPurify.sanitize(title);

When console.logging title it looks as expected When console.logging draft.label, it includes the a-tag

cure53 commented 1 year ago

So, I just had a look on Browserstack and it seems that this happens independently of any sanitization:

<body>
<script>
document.open();
document.write('110717-2214');
</script>
meier-andersen commented 1 year ago

I agree that it looks like something that happens outside of the library Could this be something? https://www.joshuacolvin.net/prevent-safari-phone-number-detection/ https://stackoverflow.com/questions/226131/how-to-disable-phone-number-linking-in-mobile-safari

cure53 commented 1 year ago

Oh, nice :smile:

Yep, that does the trick: <meta name="format-detection" content="telephone=no" />

meier-andersen commented 1 year ago

Will the sanitize method be updated so it includes the meta-tag or do you expect us to add it ourself? In our case we handle it as a string, so we don't really have any place to add a meta-tag

cure53 commented 1 year ago

Absolutely not, not our bug :smile: We cannot fix around browser weirdness like this without breaking things in the long term.