Closed Bug 1502316 Opened 6 years ago Closed 6 years ago

The button 'continue with google' from pinterest does not perform any action when clicked

Categories

(Firefox :: Protections UI, defect, P2)

64 Branch
defect

Tracking

()

RESOLVED DUPLICATE of bug 1505212
Tracking Status
firefox63 --- unaffected
firefox64 --- unaffected
firefox65 --- fixed

People

(Reporter: cbaica, Unassigned)

References

(Blocks 1 open bug)

Details

(Keywords: regression, Whiteboard: [privacy65])

[Note]:
- Not sure if this is the right component. Please move it to the correct one if necessary.

[Affected versions]:
- Fx64.0b4
- Fx65.0a1

[Affected platforms]:
- macOS 10.13
- Ubuntu 16.04 x86
- Windows 10 x64
- Windows 8.1 x86

[Steps to reproduce]:
1. Launch Firefox.
2. Go to www.pinterest.com
3. Click 'Continue with Google' button.

[Expected result]:
- A warning is received that a pop-up window was supposed to open.

[Actual result]:
- Nothing happens.
- 'best case': A pop-up window is opened and closed without any warning and clicking the button again does nothing.

[Regression range]:
- The button works without any issues in Fx64.0b3.

[Additional notes]:
- The button works without any issues when clicked from a private browsing session.
- The 'Continue with Facebook' button correctly opens the pop-up warning.
- The button for google login is also broken on https://9gag.com/login website.
So this is a regression? We need a regression range then.
(this doesn't sound like event handling issue, but without regression range hard to say)
Priority: -- → P3
Disabled "Content Blocking" from hamburger menu fixes the problem for me on Nightly65.0a1 Windows10.
thanks.
Not sure where content blocking stuff lives. Perhaps DOM: Security?
Component: DOM: Events → DOM: Security
Blocks: etp-breakage
This works on Safari 12 because accounts.google.com can get its cookies as an iframe there...
Steven, any idea what's different between this embedding of Google Login and yours here? https://senglehardt.com/test/identity_providers/google.html

Yours works, and this one doesn't.  It would be nice to have a simpler test case here.
Flags: needinfo?(senglehardt)
Component: DOM: Security → Tracking Protection
Product: Core → Firefox
I looked a bit more into what happens here.  The thing that fails is a document.cookie getter call from https://ssl.gstatic.com/accounts/o/2679293615-postmessagerelay.js, made inside an iframe navigated to <src="https://accounts.google.com/o/oauth2/postmessageRelay?parent=https%3A%2F%2Fwww.pinterest.ca&jsh=m%3B%2F_%2Fscs%2Fapps-static%2F_%2Fjs%2Fk%3Doz.gapi.en_US.UySIuUG6Ui4.O%2Fam%3DQQ%2Frt%3Dj%2Fd%3D1%2Frs%3DAGLTcCNbtB-oiGwJOpRg4JlZgOHFec0qpg%2Fm%3D__features__#rpctoken=423959811&forcesecure=1">.

The unminified code involved is as below:

K.prototype.evaluate = function() {
    var a = {},
        c = "";
    try {
        c = String(document.cookie || "")
    } catch (m) {}
    c = c.split("; ").join(";").split(";");
    for (var b = 0, d = c.length; b < d; ++b) {
        var e = c[b],
            f = e.indexOf("="); - 1 != f ? a[e.substr(0, f)] = e.substr(f + 1) : a[e] = null
    }
    this.b = a;
    if (this.b.SID)
        if (this.f = this.f.split(".")[0].split("@")[0], this.g = String(this.b[0 == this.i.indexOf("https://") ? "SAPISID" : "APISID"] || ""))
            if (a = 0 == gadgets.rpc.getOrigin(String(window.location.href)).indexOf("https://") ? "SAPISID" : "APISID", this.h = String(this.b[a] ||
                    "")) {
                c = String(this.b.LSOLH || "").split(":");
                b = c.length;
                if (1 == b || 4 == b) this.l = c[0];
                if (3 == b || 4 == b) a = String(c[b - 3] || ""), c = String(c[b - 1] || ""), b = this.h, a ? (d = [a], b && d.push(b), b = I(d.join(" ")).substr(0, 4)) : b = null, b === c && (this.j = a);
                this.a && (a = this.a.indexOf("."), -1 != a && (a = this.a.substr(0, a) || "", this.a = a + "." + J([this.g, this.i, this.f, this.l, this.j, a]).substr(0, 4)));
                a = J([this.g, this.i, this.f, this.a]);
                this.a && (a = a + "." + this.a);
                this.c = a
            } else this.c = "";
    else this.c = ""
};

They're effectively looking for the SID cookie, which they will never receive because we block the cookies from accounts.google.com.
Here is another interesting discovery.

Pinterest overlays the following transparent Facebook iframe on top of the "Continue with Facebook" button:

<iframe name="f12f2c602f364e8" allowtransparency="true" allowfullscreen="true" scrolling="no" allow="encrypted-media" title="fb:login_button Facebook Social Plugin" style="border: medium none; visibility: visible; width: 268px; height: 40px;" src="https://www.facebook.com/v2.7/plugins/login_button.php?app_id=274266067164&amp;button_type=continue_with&amp;channel=https%3A%2F%2Fstaticxx.facebook.com%2Fconnect%2Fxd_arbiter%2Fr%2F__Bz3h5RzMx.js%3Fversion%3D42%23cb%3Df56b97fdeef6e2%26domain%3Dwww.pinterest.ca%26origin%3Dhttps%253A%252F%252Fwww.pinterest.ca%252Ff38675b4f090964%26relation%3Dparent.parent&amp;container_width=268&amp;locale=en_US&amp;scope=public_profile%2Cemail%2Cuser_likes%2Cuser_birthday%2Cuser_friends&amp;sdk=joey&amp;size=large&amp;use_continue_as=true&amp;width=268px" class="" height="1000px" frameborder="0"></iframe>

Because of the existence of this button, when the user clicks on it (assuming they've whitelisted pinterest in our pop-up blocker) our pop-up detection heuristic will kick in correctly and whitelist Facebook on Pinterest.

There is also this iframe for Google embedded in the document:

<iframe ng-non-bindable="" hspace="0" marginheight="0" marginwidth="0" scrolling="no" style="position: static; top: 0px; width: 117px; margin: 0px; border-style: none; left: 0px; visibility: visible; height: 36px;" tabindex="0" vspace="0" id="I0_1541109481588" name="I0_1541109481588" src="https://apis.google.com/_/widget/render/signin?usegapi=1&amp;scope=profile%20email&amp;clientid=694505692171-31closf3bcmlt59aeulg2j81ej68j6hk.apps.googleusercontent.com&amp;apppackagename=com.pinterest&amp;redirecturi=postmessage&amp;accesstype=offline&amp;cookiepolicy=single_host_origin&amp;origin=https%3A%2F%2Fwww.pinterest.ca&amp;url=https%3A%2F%2Fwww.pinterest.ca%2F&amp;gsrc=3p&amp;jsh=m%3B%2F_%2Fscs%2Fapps-static%2F_%2Fjs%2Fk%3Doz.gapi.en_US.UySIuUG6Ui4.O%2Fam%3DQQ%2Frt%3Dj%2Fd%3D1%2Frs%3DAGLTcCNbtB-oiGwJOpRg4JlZgOHFec0qpg%2Fm%3D__features__#_methods=onPlusOne%2C_ready%2C_close%2C_open%2C_resizeMe%2C_renderstart%2Concircled%2Cdrefresh%2Cerefresh%2Conauth&amp;id=I0_1541109481588&amp;_gfid=I0_1541109481588&amp;parent=https%3A%2F%2Fwww.pinterest.ca&amp;pfname=&amp;rpctoken=31521064" data-gapiattached="true" title="Sign in with Google" width="100%" frameborder="0"></iframe>

This iframe has a Google login button inside it (like the one found on this test page https://senglehardt.com/test/identity_providers/google.html), but this iframe has been placed off-screen since it is inside this div:

<div style="left: -99999px; opacity: 0; position: relative; top: -999999px; text-indent: 0px; margin: 0px; padding: 0px; background: transparent none repeat scroll 0% 0%; border-style: none; float: none; line-height: normal; font-size: 1px; vertical-align: baseline; display: inline-block; width: 117px; height: 36px;" id="___signin_0"></div>

If Pinterest had overlayed this iframe also on top of the "Continue with Google" button, then the Google login case would also trigger our heuristics correctly.

It may be worthwhile reaching out to Pinterest to see if this is a change they'd be able to make.
See Also: → 1505212
hi christian, this issue might become a problem in the upcoming firefox 64 release, see comment #9 for some details. could you forward this to the right team at pinterest?
Flags: needinfo?(vueringschristian)
(In reply to [:philipp] from comment #10)
> hi christian, this issue might become a problem in the upcoming firefox 64
> release, see comment #9 for some details. could you forward this to the
> right team at pinterest?

This may become an issue with Firefox 65 actually not 64.  The code in question in Firefox 64 will get disabled in late betas going out after today AFAIK.  It would still be nice if we can get a contact from Pinterest to have a look at this.
Ehsan, the root cause here appears to be the same as Bug 1505212. Although it doesn't show in the console, I stepped through the code to find why there was no window opened when cookies were blocked. 

In script: https://apis.google.com/_/scs/apps-static/_/js/k=oz.gapi.en_US.Xw0pqcgIesM.O/m=client,plusone/rt=j/sv=1/d=1/ed=1/am=QQ/rs=AGLTcCPaNTjxj8Bhrwj_BgR3cN8dv7y7qQ/cb=gapi.loaded_0

The following code section is responsible for triggering the popup:

  _.jH = function (a, c) {
    bm();
    a = Mm(a);
    Nm(a);
    var f = gz(a),
    g = new _.aK(f);
    'none' == a.prompt ? Bn(g, a, function (a) {
      a.status = a.error ? {
        signed_in: !1,
        method: null,
        google_logged_in: !1
      }
       : {
        signed_in: !0,
        method: 'AUTO',
        google_logged_in: !0
      };
      c(a)
    })  : ZF(g, a, function (a) {
      if (a.error) a.status = {
        signed_in: !1,
        method: null,
        google_logged_in: !1
      };
       else {
        var f = a.access_token || a.id_token;
        a.status = {
          signed_in: !!f,
          method: 'PROMPT',
          google_logged_in: !!f
        }
      }
      a['g-oauth-window'] = g.kga.h8;
      c(a)
    })
  };
  ZF = function (a, c, f) {
    var g = new Tm(c.response_type);
    f = An(a, g, f);
    var h = {
      responseType: g.toString()
    };
    Gw(h, [
      'sessionMeta',
      'extraQueryParams',
      'gsiwebsdk'
    ], c.gsiwebsdk || '2');
    Cs(g) && Gw(h, [
      'sessionMeta',
      'extraQueryParams',
      'access_type'
    ], c.access_type || 'offline');
    c.redirect_uri && Gw(h, [
      'sessionMeta',
      'extraQueryParams',
      'redirect_uri'
    ], c.redirect_uri);
    c.state && Gw(h, [
      'sessionMeta',
      'extraQueryParams',
      'state'
    ], c.state);
    c = ol();
    a.RV ? f({
      authResult: {
        error: 'idpiframe_initialization_failed',
        details: a.vY().error
      }
    })  : (a.V5 = f, rl(a, c, h))
  };

This fails with the result

details: "localStorage is not available in the current environment."
error: "idpiframe_initialization_failed"

I wonder whether this failure will apply to any website that uses the google apis click handler (rather than simply using Google's signin button (like my test page does). The fix here would be for Google to expect to not have localStorage access until after the pop-up is created, rather than check if it has access prior to the pop-up.
Flags: needinfo?(senglehardt)
The 9gag login referenced in comment 0 uses the same click handler as pinterest, so I suspect any site which uses this handler will have the same issues. To get an idea of how common this is, we should check if this is a recommended design pattern in their documentation.

The following onclick function is registered by: https://apis.google.com/_/scs/apps-static/_/js/k=oz.gapi.en_US.Xw0pqcgIesM.O/m=signin_annotation/rt=j/sv=1/d=1/ed=1/am=QQ/rs=AGLTcCPaNTjxj8Bhrwj_BgR3cN8dv7y7qQ/cb=gapi.loaded_0

function() {
  _.Ix(f, g)
}
Priority: P3 → P2
Whiteboard: [privacy65]
This is fixed with the patch in bug 1505212.
Status: NEW → RESOLVED
Closed: 6 years ago
Flags: needinfo?(vueringschristian)
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.