-
Notifications
You must be signed in to change notification settings - Fork 319
Support <Elements> within a shadow DOM #216
Comments
@bcanseco Hi! Thanks for writing in. I'm Matt and I work at Stripe. You are totally right here--Elements is currently not compatible with shadow DOM. We have this on our backlog and are looking forward to addressing it in the future (no concrete timeline at the moment unfortunately). I will be sure to let you know when the fix does roll out! |
Not just Chrome, shadow dom is supported in a number of browsers. For example, firefox support is about to land. |
FYI, the way we solve this in stripe-elements custom element is to walk the dom tree until we find the document. |
+1 we also really need this for our solution. As web pages become more plugin focused this is going to be important. |
+1 |
For anyone considering workarounds like tokenizing cards using your own CC forms on the frontend and then capturing charges from your backend: Keep in mind that you eventually need to validate PCI compliance. Yes, your backend never sees credit card information with this approach. HOWEVER, since you're not using the Elements library - you will have to fill in 40 pages of PCI forms every year. More info on that here. |
@bcanseco Thanks for that, that's more reason for stripe to support the full DOM and HTML spec, including shadow DOM. Anyone building a payment app that uses shadow DOM would LOVE to not have to fill out those forms, but unless Stripe decides to support the full DOM spec, we have to use weird workarounds like walking the whole tree. |
@matt-stripe Are there any updates on the progress for shadow dom support? |
Would love to know if this has been fixed - also why is it closed if it's not? |
It's worth mentioning that the workaround we use in |
@bennypowers - does it also break the PCI compliance side of things or is that ok? Also does it do the new PaymentIntent stuff? [UPDATE] I wish Stripe would sort it out and do this properly within stripe! |
Won't break PCI, since even with my component, your users are still entering their numbers into an iframe to stripe.com. but without proper tab order, it is inaccessible. You'll probably need some vile tabindex hacking, either that or very careful dom placement to get it to work the way you'd expect. But i'd be happily proven wrong. all of ☝️ is based on my experience using
|
Hi folks, we don't have any updates regarding shadow DOM support yet. It should still be possible to use Elements without the shadow DOM, so hopefully you're not blocked from integrating Stripe altogether (or forced to fall back to higher levels of PCI). We'll post here if/when we have updates on shadow DOM support. |
There are 8 (pretty minor, fairly repetitive) things in stripe.js which I know of that prevent it from working. There may be more which just happen not to occur in the features we’re using, but still, it’s not a super big diff. I have a patched version which does work, but it will be awkward trying to maintain keeping it in sync with the stripe-hosted script. Any news here? |
Shadow DOM causes some issues with the iframes that Stripe.js uses internally for PCI compliance. It may be possible to change Stripe.js to be compatible with Shadow DOM while preserving PCI compliance, but it's definitely more involved than 8 minor patches. In the meantime, the only workaround is to keep all elements in the main document, doing something like @bennypowers's clever trick in stripe-elements. |
There’s nothing which could be considered PCI-related that I’ve encountered. The iframes are still secure (nothing can change that, really, they are controlled by stripe’s origin exclusively, and none of the Shadow DOM issues concern message passing). It’s only a handful of incorrect assumptions about three things:
Shadow DOM does not change how iframes behave. |
It does. This is the main blocker: whatwg/html@7b56772 That means unless all iframes are in the root document, they cannot discover each other to communicate directly. |
Apologies, I framed that wrong. I should have said it does not change their security characteristics. I’m a bit confused now though because the script creates all of these elements and can hold references to them, and is not obviously failing anywhere. |
While I'm not sure what your patches exactly do, you might end up creating the element iframes but they wouldn't be functioning properly. In particular I don't believe you'd be able to create a Token or PaymentMethod from a card element. Also, a reminder that self hosting Stripe.js (especially a modified versions) is in itself not PCI compliant. |
Why is that exactly? I should hope that no script I run in my origin could compromise Stripe’s security — is that not the case? (To be clear — I believe you of course, just looking to understand what’s going on better. This has all been a pretty frustrating experience so far.) |
@bathos I ran into this same problem as well. I put together a working solution where I have an <iframe> within the shadow DOM that handles loading the Stripe script and rendering |
@hofman-stripe @matt-stripe Would it be possible (at least in the My thought is that this collection would replace |
For security we cannot rely on the Stripe.js script loaded in your page to establish a communication channel between our iframes. They have to discover each other directly. Currently this is done through naming and There are other ways to get references to other frames's Interesting read on the topic: https://medium.com/@bluepnume/every-known-way-to-get-references-to-windows-in-javascript-223778bede2d |
👍 for supporting shadow dom. I got this working by using a slot to pull in a container from outside the shadow dom, but that was easy to do because my component sits directly inside the root DOM. |
This issue was originally reporting a bug when using custom fonts within a shadow DOM. I've changed the title to more accurately reflect the root cause - which is no shadow DOM support whatsoever.
Minimal reproduction (use Chrome)
Environment
Summary
When using stripe elements within a shadow root, passing external fonts to the
<Elements>
component will result in the iframe form getting an inlinevisibility: hidden
style.Even if this style is overriden, creating tokens will later throw the following error:
Other information
The repro above may take a few moments to load. Notice that the fourth box will stay empty.
I'm aware that the fonts are not actually applied to the inner
<CardElement>
in the repro above.The text was updated successfully, but these errors were encountered: