Git Product home page Git Product logo

duo_web_sdk's Introduction

Deprecation Notice

This repository is deprecated by Duo Security. The repository will remain public and visible, and integrations built using this repository’s code will continue to work. You can also continue to fork, clone, or pull from this repository.

However, Duo will not provide any further releases or enhancements.

Duo recommends migrating your application to the Duo Universal Prompt. Refer to our documentation for more information on how to update.

For frequently asked questions about the impact of this deprecation, please see the Repository Deprecation FAQ


Overview

Build Status Issues Forks Stars License

duo_web_sdk - Provides the Duo Web Javascript in an ES6 module format that can be installed via npm/yarn and bundled into your web application.

Installation

Install duo_web_sdk from Github:

  • With NPM: npm install https://github.com/duosecurity/duo_web_sdk.git --save
  • With yarn: yarn add https://github.com/duosecurity/duo_web_sdk.git
  • For development: npm install

Usage

Basic usage would be importing this module and initializing the Duo Authentication Prompt with the signed request passed from the server. The user would authenticate using the prompt, and you would submit the signed response to your backend for verification.

import DuoWebSDK from 'duo_web_sdk';

DuoWebSDK.init({
  iframe: "duo-frame",
  host: host,
  sig_request: sigRequestPassedFromServer,
  submit_callback: someCallback,
});

See the examples folder for a full implementation using React and Express.

Testing

$ npm test

Documentation

General documentation on using Duo Web is available here.

duo_web_sdk's People

Contributors

aaronatduo avatar bradleyhiggins avatar jeffreyparker avatar mschwager avatar robyoder avatar subyraman avatar vbscott avatar xdesai avatar yizshi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

duo_web_sdk's Issues

Nothing posted to post_action URL when running iframe from a file:// URL

I have the iframe running in a local file. Everything seems to load fine, and the authentication buttons work (I get push notifications on my phone, and I get the Success! Logging you in... message), but I see an error in the console:

  • Chrome: Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('file://') does not match the recipient window's origin ('null').
  • Firefox: Failed to execute ‘postMessage’ on ‘DOMWindow’: The target origin provided (‘null’) does not match the recipient window’s origin (‘null’).
  • Safari: Unable to post message to file://. Recipient has origin null.

I don't see anything getting posted to the post_action URL, so I believe this might be why my Okta integration isn't working.

There's a hint here that maybe I need to serve this file from a webserver, but I wanted to make sure I wasn't doing something dumb first.

Tag v2.6 release

We've been asked for what's changed between v2.5 and v2.6. I noticed we haven't actually tagged the v2.6 version yet, which would allowing diffing between the two tags.

Console errors complaining about blob://url

Console gives error about file inject.preload.js:373 which is:

if (document instanceof HTMLDocument)
{
  let sandbox = window.frameElement &&
                window.frameElement.getAttribute("sandbox");

  if (typeof sandbox != "string" || /(^|\s)allow-scripts(\s|$)/i.test(sandbox))
  {
    let script = document.createElement("script");
    script.type = "application/javascript";
    script.async = false;
    // Firefox 58 only bypasses site CSPs when assigning to 'src'.
    let url = URL.createObjectURL(new Blob([
      "(" + injected + ")('" + randomEventName + "');"
    ]));
    script.src = url;
    document.documentElement.appendChild(script);
    document.documentElement.removeChild(script);
    URL.revokeObjectURL(url);
  }
}

specifically this line document.documentElement.appendChild(script);=
screen shot 2018-07-17 at 6 28 47 am

Add a way for host application to get iframe body's height

Using the iframe at it's full width does not normally pose any issues, however, when using it in width constrained scenarios such as mobile devices, the height of the iframe content often changes. This is problematic because the host page cannot determine when this content changes in order make appropriate adjustments to the height of the iframe. This results in two problems:

  • You make the height of the iframe conservatively large which leaves unwanted whitespace in many scenarios. Ex:

image

  • Or you make the iframe too small and end up with users not being able to see the needed content. Ex:

image

Some browsers like Safari do not even show scrollbars so it makes it almost impossible to know there is more content to scroll to, leading to a confused user.

Solution

Use messages to post back the height of the iframe body each time content changes. Examples: https://stackoverflow.com/a/22991952/1090359

I'd recommend the MutationObserver solution.

Finally, add a callback to DuoWebSDK.init() so that host application can react to the new height and apply it appropriately.

Ex:

Duo.init({
    // ...
    content_changed: function (height) {
        // ...
    }
});

npm audit critical security issue

Our npm audit shows this warning. Could you help confirm if this vulnerability?

duo_web_sdk
Severity: critical
Malware in duo_web_sdk - https://github.com/advisories/GHSA-gwjw-ph82-w683
No fix available
node_modules/duo_web_sdk

Screen Shot 2022-06-23 at 11 14 22 AM

Duo.init() can only initialize a single iframe per doc ready

Issue

Consider a SPA where Duo Web SDK factory initialization is only done once (on dom ready).

I can only call Duo.init() once. If I call Duo.init() any other time, the cached iframe variable is reused, which may no longer exists on the page. Therefore the new iframe dom element fails to be setup and load any content.

Example

This can be illustrated in a simple AngularJS app as follows (also see attached .zip for runnable example):

duo-web-spa-issue.zip

<!DOCTYPE html>
<html ng-app="myApp">
<head>
    <meta charset="utf-8">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
    <script src="duo.js"></script>

    <script>
        var myApp = angular.module('myApp', []);
        myApp.controller('myController', function ($scope, $timeout) {
            $scope.loggedIn = false;
            $scope.showLogin = false;

            $scope.login = function () {
                $scope.loggedIn = false;
                $scope.showLogin = true;

                $timeout(function () {
                    Duo.init({
                        host: 'api-4c50a4b2.duosecurity.com',
                        sig_request: 'TX|YWI0OTgxNDg=|cb88d6f90:APP|YWI2NDU0NDg=|10f4d22a',
                        submit_callback: function (theForm) {
                            console.log(theForm);
                        }
                    });
                }, 100);
            };

            $scope.logout = function () {
                $scope.loggedIn = false;
                $scope.showLogin = false;
            };

            $scope.dash = function () {
                $scope.loggedIn = true;
                $scope.showLogin = false;
            };
        });
    </script>

    <style>
        body {
            background-color: #eeeeee;
            font-size: 14px;
            font-family: Arial;
            overflow-y: auto;
            padding: 0;
            margin: 0;
        }

        iframe {
            width: 400px;
            height: 500px;
        }
    </style>
</head>
<body>
    <div ng-controller="myController" class="container">
        <div ng-if="!loggedIn && !showLogin">
            Welcome<br />
            <button type="button" ng-click="login()">Let's Log In</button>
        </div>
        <div ng-if="showLogin">
            Log In With Duo<br />
            <iframe id="duo_iframe"></iframe><br />
            <button type="button" ng-click="dash()">Go To Dashboard</button>
        </div>
        <div ng-if="loggedIn">
            Logged in<br />
            <button type="button" ng-click="logout()">Log out</button>
        </div>
    </div>
</body>
</html>

The first load of showLogin will present the proper iframe contents (note that access denied is expected since I am not using a real signature, but illustrates that the iframe loads the proper page).

image

If you click Go To Dashboard, then Log Out, then Log In again Duo.init() will again be called. This time no content loads from the iframe (iframe has no src according to dev tools).

image

Possible Solution

Expose a way for implementation to clear the iframe variable in the Duo factory?

Can't install via npm

Installing via NPM throws an error:

npm ERR! addLocal Could not install /var/folders/85/hc36n4312rq8q55shdw15zz50p1hct/T/npm-6968-fad008ab/git-cache-9837df60/d43c4bad165cee70d277a986d23eee336426d4cf
npm ERR! Darwin 14.5.0
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "install" "https://github.com/duosecurity/duo_web_sdk.git" "--save"
npm ERR! node v7.6.0
npm ERR! npm  v4.1.2

npm ERR! Invalid version: "2.5"
npm ERR!
npm ERR! If you need help, you may report this error at:
npm ERR!     <https://github.com/npm/npm/issues>

I believe it could be because the version name is not semantic...

Thanks!

Publish To NPM

Is there a reason why you havent published this artifact to NPM? We would like to use this package but due to our build tools/networking/artifcatory/etc we cannot pull down github url style packages from our packages.json file. Would be really nice if you just published this to NPM so it would work the way that most packages do.

When duo_form is used, don't overwrite method and action

If I provide a form element with ID duo_form, it will be used for the post-back to my verification endpoint. In this case, I should be able to specify the form method and action on my element; in particular, it should not be necessary to pass the action to the init method. Currently both the method and action are overwritten when posting the form.

Make version easier to find

The version (v=X.X) is difficult to spot in the JS code. It'd be great if we had some global, or module-level, variable describing the version then used that variable when sending the request. Another plus is people using this library can then programmatically access the version.

Bonus points if we follow semantic versioning (http://semver.org/) :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.