IdentityModel / oidc-client-js

OpenID Connect (OIDC) and OAuth2 protocol support for browser-based JavaScript applications
Apache License 2.0
2.43k stars 841 forks source link

IFrameWindow.js - Detecting and processing postMessage from another service #1221

Closed paulmowat closed 3 years ago

paulmowat commented 4 years ago

Hi,

I'm hitting an issue when trying to use this library to do silent renews/authentication via iframe.

Within my application. I'm using a tool called Pendo that collects analytics etc. It also sets itself up using a iframe to communicate with it's service.

The IFrameWindow.js _message function is detecting when the Pendo tool does it's own postMessage which returns a object. Since both iframes are for the same origin and content window (both are on the same page) it's allowing the message to be passed through as a success.

Downstream this then results in a 'OidcClient.readSigninResponseState: No state in response' since it doesn't understand the format of the data (i.e. a object) that's came from the Pendo postMessage and the process stops.

Is there a way to improve the logic below from the IFrameWindow.js _message function so it only processes postMessages that are related to oidc?

if (this._timer &&
  e.origin === this._origin &&
  e.source === this._frame.contentWindow
) {
  let url = e.data;
  if (url) {
    this._success({ url: url });
  }
  else {
    this._error("Invalid response from frame");
  }
}

Happy to do a PR to try resolve. Any pointers would be appreciated :)

Thanks

Paul

paulmowat commented 4 years ago

I've made a small change on #1223 to add some checks to ensure the e.data is actually a URL. This has helped solve my problem, although if there's a way to validate the url against some of the oidc config that might be better?

tharidu commented 4 years ago

We have also come across this issue. After doing the further investigation, we have concluded this is due to Pendo's messaging to Checksession iframe. Pendo uses frames to get all the iframes in the window and do postMessage sending a Pendo specific payload. This breaks session state logic in CheckSession iframe and thus stops the oidc-client. This is a issue that need to be fixed from Pendo side rather than oidc-client.

josundt commented 3 years ago

@paulmowat Me and @tharidu raised an issue to the Pendo team and they have now fixed it, and we have verified that fix. The problem was that the Pendo script was posting messages to all iframes; not only the ones created by the Pendo script. The oidc checksession iframe therefore received a malformed message from the Pendo script which caused an error. After the fix, Pendo only posts messages to the iframes "owned" by Pendo.

paulmowat commented 3 years ago

@josundt Thanks for letting me know. That is great news that it's been sorted at Pendos side.