Friday, March 8, 2013

Second factor authentication

Second factor Authentication at Bank of America

Introduction

BAC online banking (OLB) application has username and password for authentication. If OLB does not recognize the browser, it presents a challenge question to the user.

SafePass

Second factor authentication is called SafePass by BAC. It provides another layer of security in case the username, password are compromised. SafePass sends a SMS to your registered cell phone with a six digit code and prompts to enter it on the OLB website. If it matches, user is allowed to login.
If you watch the traffic between the browser and OLB, you will notice that the SafePass widget is hosted on a different server and if you dissect it more, you will find that it uses JSONP.

Sample SafePass code.

If you have logged in to the BAC site in another tab, SafePass should come initialized.

JSONP

JSON with padding is used to provide html widget like solution for mashups. Instead of having different web pages have the same html, JavaScript, stylesheets and images, the widget is created as an application and is embedded on the different web pages. To allow for cross domain JavaScript access, JSONP is used.
To read more about JSONP please use the following links.
http://api.jquery.com/jQuery.ajax/
http://en.wikipedia.org/wiki/JSONP
Let us first see how it is implemented and we will then figure out how it works.

BAC Implementation

Pages like "Add a Payee" in BillPay or "Outside the Bank Transfer" in Transfer application load the following JavaScript files.
First it loads JQuery core and UI libraries.
https://safe.bankofamerica.com/pa/global-assets/1.0/script/jquery-core.js
https://safe.bankofamerica.com/pa/global-assets/1.0/script/jquery-ui.js 
The third is BAC code for JSONP
https://safe.bankofamerica.com/pa/components/utilities/vipaa-safepass-client-util/1.2/script/safepass-nonflash-widget.js
Looking at the safepass-nonflash-widget.js, we find that it uses JQuery ajax call.

$skwjq.ajax({ // skwjq is JQuery. Instead of $, it is using skwjq
   async: (typeof(spwAsynchAll) !== "undefined"? spwsynchAll : false), // looks like spwsyncAll is undefined
   url: safePassInitUrl, // points to the widget self
   type:'GET',
   dataType: 'jsonp', // As per JQuery docs, Adds an extra "?callback=?" to the end of your URL 
   crossDomain: true,
   cache: false,
   timeout: 20000,
   beforeSend:function(){   
   },        
 error: function(XMLHTTPRequest,textStatus,errorThrown) { 
   $skwjq(spwDivId).html(XMLHttpRequest.responseText + "
   TextStatus: " + textStatus + "
   ErrorThrown: " + errorThrown);
 },        
 success: function(data){
   $skwjq(spwDivId).html(""); //spwDivId: "#safepassNonFlashwidget"
   $skwjq(spwDivId).append(data.htmlSource); // appends the widget to the div
   if ($skwjq('#spw-progress-bar').length > 0) {
     spwProgressBar.setPercent(50);
   }
 },
 complete: function(XMLHTTPRequest,textStatus){ 
   if($('ul.safepass-tab li.sp-mobile').length > 0 && $('ul.safepass-tab li.sp-card').length > 0) {
     if($('ul.safepass-tab li.sp-card:hidden').length > 0) {
       $('ul.safepass-tab li.sp-mobile a').removeAttr('href');
     } else if($('ul.safepass-tab li.sp-mobile:hidden').length > 0) {
       $('ul.safepass-tab li.sp-card a').removeAttr('href');
     }    
   }
 }
});

How it works

The hosting webpage defines a div tag with id=safepassNonFlashwidget. This id is used to attach the widget to the DOM. It will help you to understand better if you put a breakpoint in safepass-nonflash-widget.js.showNonFlashWidget()
The variables of interest have the following values
  1. spwDivId: "#safepassNonFlashwidget"
  2. safePassInitUrl: https://secure.bankofamerica.com/login/sign-in/incoming/safepassInitScreen.go

The JQuery.ajax call invokes URL https://secure.bankofamerica.com/login/sign-in/incoming/safepassInitScreen.go?callback=jsonp1362762508183&_=1362762519426. The callback is the success part of the ajax call. JQuery appends the timestamp to the callback to make each callback unique.
Actually there are multiple JSONP calls occuring.
  1. The first JSONP loads following script files from https://secure.bankofamerica.com/pa/components/utilities/safepass-widget-html-util/1.1/script/. It is a loader for SafePass.
    safepass-widget-html-util.js
    crypto-sha1-hmac-pbkdf2-blockmodes-aes.js
    safepass-widget-layout.js
    
  2. The second JSONP call occurs in safepass-widget-html-util.js. The function is spwGetSafepass(). This actually gets the html to display the widget.
  3. The third JSONP call gets the user specific mobile data.

SAML

When you enter the code sent to your mobile, and click on "Send" button within the widget, two things happen.
  1. SAML assertion is generated on the secure.bankofamerica.com and since that is few kbytes in size, a corresponding artifact is generated.
  2. the method sendToJavaScript() is invoked in the browser and that copies the SAML artifact to the hidden input field.

The SAML artifact is submitted along with the html form. The OLB, or BillPay or Transfer application takes that artifact, makes a webservice call to secure.bankofamerica.com and retrieves the SAML assertion. That assertion is parsed and validated.

Disclaimer

This blog describes working of SafePass, Second factor authentication on BAC website. The code keeps on changing and evolving. So what is observed today may not be seen tomorrow, making this blog inaccurate or pointless.

1 comment:

  1. Hello Dhaval,

    I got your resume from Indeed.com and I like to talk to you regarding the opportunity.

    Kindly forward me the your updated resume for our references.

    Thanks,
    Parameswaran Bhaskar
    E-Business International Inc
    Direct: 732-853-1975
    pbhaskar@ebintl.com

    ReplyDelete