recaptcha icon indicating copy to clipboard operation
recaptcha copied to clipboard

captcha become white after click in iframe on Safari 12.1

Open Mathias1111 opened this issue 5 years ago • 23 comments

Prerequisite:

  • Safari 12.1 (14607.1.40.1.4)
  • The captcha v2 is embedded as an iframe with a certain width (E.g. 1268px or width=100% on 2560x1600)

What I intended to do:

  • I want to solve a reCaptcha v2.

What actually happened:

  • When you click into the captcha it's getting "white" and unusable.

How to reproduce:

  • create a new reCaptcha v2 checkbox key pair
  • set localhost to your domains
  • set the site-key in the iframe.html in the data-sitekey attribute
  • host the index.html and iframe.html (for example with python)
    • python -m http.server 80

fun facts:

  • with a width of 512px the captcha works

example.zip

Mathias1111 avatar May 13 '19 14:05 Mathias1111

@Mathias1111 Thank you for very useful information!

with a width of 512px the captcha works

I've found an evil workaround..

if (window.innerWidth > 512) {
  try {
    window.innerWidth = 512;
  } catch (e) {
    // ignore
  }
}

// then render reCAPTCHA

usualoma avatar May 23 '19 08:05 usualoma

I have exaclty the same issue described by @Mathias1111 But with a width of 512px the captch won't work.

@usualoma How your workaround solve the problem ?

gsoulard avatar Jun 05 '19 13:06 gsoulard

@gsoulard

In grecaptcha.render, the reCaptcha changes the behavior by referring towindow.innerWidth. So we can solve the problem by assigning a value to window.innerWidth before calling grecaptcha.render.

window.innerWidth = 512;
grecaptcha.render('html_element', {
  'sitekey' : 'your_site_key'
});

usualoma avatar Jun 06 '19 05:06 usualoma

@usualoma

Thanks a lot it's working now.

gsoulard avatar Jun 07 '19 09:06 gsoulard

I do not understand this. please help in simple terms how to stop the captcha going white when i click on it

hevian54 avatar Jun 30 '19 06:06 hevian54

I'm pretty sure this is an issue with Safari 12.1 concerning how they do repaint logic in nested IFrames, not a Recaptcha issue (It wasn't an issue in Safari 11.1).

Funny enough, you can even re-create this by putting the demo recaptcha site (https://recaptcha-demo.appspot.com/recaptcha-v2-checkbox.php) in an IFrame.

That being said, until Safari fixes it, if anyone is looking for a better workaround than the 512px width on the outer IFrame (that doesn't work for me because I need the outer IFrame to be able to expand beyond that if needed), I found that injecting the following into the header inside the IFrame with the src beginning with https://www.google.com/recaptcha/api2/bframe will fix the issue:

<style type="text/css">.rc-image-tile-wrapper{transition: auto !important}</style>

This is because the recaptcha has a class "rc-image-tile-wrapper" that has:

transition: 0.1s ease;

And apparently something about doing that inside a nested IFrame the way Recaptcha does is it when the outer IFrame is greater than 512px (man, I hate this bug) causes the entire IFrame to be repainted white in Safari 12.1. (Note that I say repainted, because you can actually still interact with the squares and verify button in the Recaptcha control, so if you remembered where all the squares were you can actually still solve it)

Fun Fact: The "Click verify once there are none left" Puzzles actually don't turn white like the others do in Safari 12.1, and after completing a bunch of Puzzles repeatedly, Recaptcha likes to send you to these types of puzzles instead so this can be very fun to track down.

TGolias-zz avatar Jul 03 '19 18:07 TGolias-zz

@gsoulard

In grecaptcha.render, the reCaptcha changes the behavior by referring towindow.innerWidth. So we can solve the problem by assigning a value to window.innerWidth before calling grecaptcha.render.

window.innerWidth = 512;
grecaptcha.render('html_element', {
  'sitekey' : 'your_site_key'
});

@usualoma

Could you think of a way to apply this workaround for pages where there is no dynamic rendering with 'grecaptcha.render'? The captcha is automatically loaded to a div with class "g-recaptcha". example: <div class="g-recaptcha" data-sitekey="your_site_key"></div> Thanks

tamir-eyal avatar Jul 17 '19 11:07 tamir-eyal

I found that injecting the following into the header inside the IFrame with the src beginning with https://www.google.com/recaptcha/api2/bframe will fix the issue

Injecting how? It’s cross domain?

orcinus avatar Aug 23 '19 16:08 orcinus

@usualoma

Could you think of a way to apply this workaround for pages where there is no dynamic rendering with 'grecaptcha.render'? The captcha is automatically loaded to a div with class "g-recaptcha". example: <div class="g-recaptcha" data-sitekey="your_site_key"></div>

Leave the div in place and load the recaptcha dynamically into it from a callback. E.g.

      <script>
        window.innerWidth = 512;
        var RecaptchaOptions = {
           theme : 'white'
        };

        var recaptchaLoadCallback = function() {
          grecaptcha.render('g-recaptcha', {
            'sitekey' : '<yoursitekey>’
          });
        };
      </script>    
      <script src="//www.google.com/recaptcha/api.js?onload=recaptchaLoadCallback&render=explicit" async defer></script>

Note that this workaround doesn’t work in 100% of the cases. I’ve had the white frame show in about 10% of the cases still.

orcinus avatar Aug 23 '19 17:08 orcinus

I have faced up with the issue through ng-recaptcha npm. Fixed the issue by workaround like: recaptcha { display: inline-block; transform: translate3d(0, 0, 0) }

Casedy avatar Oct 14 '19 11:10 Casedy

hi @Casedy did you tested your fix with the latest safari v13.0.2 ? We implemented fixes mentionned here and they do not work anymore on this new version of Safari...

DanielFrancois avatar Oct 14 '19 11:10 DanielFrancois

@DanielFrancois tested precisely on safari v13.0.2. it is on my mac now.

Casedy avatar Oct 14 '19 18:10 Casedy

I confirm, this also worked on my side for safari v13.0.2, many thanks to you @Casedy see you again after the next Safari update :D

DanielFrancois avatar Oct 16 '19 07:10 DanielFrancois

This does actually work/improve, the 16 tile version now renders correctly.

ghost avatar Oct 16 '19 12:10 ghost

@Casedy any special reason for the display: inline-block ?

IagoLast avatar Oct 17 '19 14:10 IagoLast

@IagoLast It is part of my integration. I didn't check without inline-block.

Casedy avatar Oct 18 '19 02:10 Casedy

Here is a more specific fix based on the answer from @Casedy: .g-recaptcha-bubble-arrow + div:not([class]) {transform:translate3d(0,0,0)!important;}

stevenkovar avatar Oct 21 '19 23:10 stevenkovar

I have been battling this issue as well I was able to fix the traslation to white on click with the following .g-recaptcha { display: inline-block; transition: auto !important;} /*3x3 9 cell reCaptcha*/

.g-recaptcha-bubble-arrow + div:not([class]) {transform:translate3d(0,0,0)!important;} /*4x4 16 cell reCaptcha*/

But for the life of me I can not get the recaptcha back on screen. My challenge iframe is left: -163px. I have tried everything to bring it back to the center but have been having problems.

c0mput3rxz avatar Oct 31 '19 00:10 c0mput3rxz

Being tracked in WebKit as https://bugs.webkit.org/show_bug.cgi?id=204013 It seems like Google worked around this by using a different animation.

smfr avatar Nov 08 '19 19:11 smfr

Hi! I'm trying to inject css to fix this issue, but i'm not sure how can I inject it so it applies inside the captcha challenge iframe?

uriklar avatar Dec 05 '19 07:12 uriklar

Hi @smfr! I see the issue you linked is marked as resolved, also you mention Google worked around this somehow, yet I can still recreate this issue in Safari 13.0.3. Can you clarify the status of this issue (If you know of course..) Thanks 🙏

uriklar avatar Dec 08 '19 07:12 uriklar

@Casedy do you mind sharing the exact css that fixes it for ng-recaptcha? I'm also using ng-recaptcha and I'm running into the same issue.

For all those who are reading this: My issue was with bootstrap. Specifically, the css

body > * {
  overflow: hidden;
}

was blowing up the captcha. I put in

body > * {
  overflow: visible !important
}

and it worked.