Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using the google javascript api within a sandboxed iframe environment

I have an HTML5 app which uses the google javascript API. I discovered recently that this app needed to run within an iframe sandboxed environment. I know that it looks like trying to workaround the very goal of the sandboxed environments; however some features are still allowed for the iframe (see constraints below), which makes me think that there is some hope.

I am facing issues during the authentication process: when loaded, the google javascript api appends an iFrame on the original page (which is already an iframe in my case) and uses a postMessage mechanism to communicate between windows. I would like to use the google api for the OAuth2.0 authentication process as well as for querying the API.

Here is a reproduction case; I am using a simplified version of the authSample.html page provided by google.

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8' />
    <title>original auth page</title>
</head>
<body>
    <button id="authorize-button">Authorize</button>
    <div id="content">Not authentified</div>
    <script type="text/javascript">
        var clientId = '<use yours>';
        var apiKey = '<use yours>';
        var scopes = 'https://www.googleapis.com/auth/analytics.readonly';
        var authorizeButton = document.getElementById('authorize-button');
        var resultDiv = document.getElementById('content');
        function handleClientLoad() {
            gapi.client.setApiKey(apiKey);
            authorizeButton.onclick = handleAuthClick;
        }

        function handleAuthResult(authResult) {
            if (authResult && !authResult.error) {
                makeApiCall();
            } else {
                resultDiv.innerHTML = "handleAuthResult Failed";
            }
        }

        function handleAuthClick(event) {
            gapi.auth.authorize({ client_id: clientId, scope: scopes, immediate: false }, handleAuthResult);
            return false;
        }

        function makeApiCall() {
            gapi.client.load('analytics', 'v3', function () {
                resultDiv.innerHTML = "api call successful";
            });
        }
    </script>
    <script src="https://apis.google.com/js/client.js?onload=handleClientLoad"></script>
</body>
</html>

The containing page, which will be used by the end-users looks like:

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8' />
    <title>iframed page</title>
</head>
<body>
    <iframe id="8D681BA3DED5" width="400px" height="400px" 
            frameborder="0" sandbox="allow-scripts allow-forms allow-same-origin ms-allow-popups allow-popups" marginheight="0" marginwidth="0" 
            name="MyTest" src="https://localhost:4000/AuthSample.html"></iframe>
</body>
</html>

Obviously you will have to execute this page after replacing the actual src for the iframe by your server authSample.html url.

If you run it on different browsers, you will notice different behaviors for the failure. I tried to exploit the fact that the popups are allowed but it seems that browsers have implemented differently the fact that the opened window should also be openned in a sandboxed environment.

I would like to avoid writing my own webservices for the authentication. In addition, I believe that users would be more secure entering their credentials using the usual google web page (with an url accounts.google.com). If you have an idea, that may work with recent browsers, feel free to submit it.

Thank you

like image 467
Benoit Patra Avatar asked Nov 26 '22 07:11

Benoit Patra


1 Answers

I have found a solution, the basic idea is to do the auth flow in a popup that will not inherit the sandbox cross origin security restrictions. Indeed, the sandbox has the following attributes sandbox=”allow-scripts allow-forms allow-same-origin ms-allow-popups allow-popups”

I wrote a small blog post explaining in detail the solution.

EDIT (September 2016):

At Keluro we released an open source code sample to leverage the sign-in technicalities. It is used more for connecting to Azure AD/Office 365 but the client side using dialogApi and the popup as a fall back can be reused.

like image 131
Benoit Patra Avatar answered Dec 05 '22 17:12

Benoit Patra