Was this article helpful?

Security Guidelines

Last modified 12:48, 21 Jul 2014

The Gigya service is designed to provide maximum security for your critical data. Please follow the guidelines provided in this document to make sure you are leveraging all the security features built into the Gigya service.

   

Protect Your Secret Key

Your "Secret Key" is provided in BASE64 encoding, at the bottom of the Site table in the Dashboard section on the Gigya's website (please make sure that you have logged in to Gigya's website and that you have completed the Gigya's ​Site Setup process).
The secret key is a cryptographic random number used as a shared secret between your application and Gigya. Anyone who gains access to this key may pretend to be you and perform actions on your users on your behalf, therefore it is crucial to protect the secret key. Take extra caution and never ever use the secret key on a client where malicious users could gain access to it.

 

Load the Gigya JavaScript Library over HTTPS when used on Secured Web Pages

The Gigya service supports HTTPS, meaning that you have the choice to communicate with the Gigya service over a secure connection (SSL).
When integrating the Gigya service within a secured page (for example, in your login page), it is highly recommended to communicate with the Gigya service over a secured connection as well.
Implementing this is very simple. All you need to do is to load the Gigya JavaScript library file from our HTTPS domain. This will not only load the library code itself over HTTPS but will cause the library to perform all its communications with the Gigya server over HTTPS as well.

 

As a reminder, every page that uses the Gigya API must load Gigya's JS library file in the <HEAD> section (refer to Getting Started, for the complete guide).

On secured pages, the line of code should be:

<script  src="https://cdns.gigya.com/JS/socialize.js?apikey=INSERT-YOUR-APIKEY-HERE" ></script>

 

Notes:
  • If you are using generated code or one of our code examples, the above line should substitute the equivalent line that loads Gigya's JS library file from an HTTP domain.
  • The ActionScript SDK will automatically detect when the containing SWF is loaded over HTTPS and will automatically switch to using HTTPS.

 

 

Validate the UID Signature in the Social Login Process

The social login process requires the user to login to one of the providers supported by Gigya. Obviously this process has to happen on the client side, which means there is a risk that a malicious user will try to tamper with the data sent from the client to the server. The most important piece of data is the UID, which is used to authenticate the user and log him/her into your system. Gigya uses HMAC-SHA1 digital signatures to prevent tampering with the UID and therefore it is crucial to validate the signature before logging the user in based on the UID coming from the browser.

Please refer to the Social Login documentation, for a complete overview of the social login flow and the signature verification within it.

 

If you are using one of Gigya's SDKs, implementation is simple. Use the SigUtils.validateUserSignature() method provided in your SDK.
The method receives four parameters: the UID to be validated, a timestamp, the secret key and the signature. Obtain your partner's 'Secret Key' from Gigya's Site Setup page. The UID, timestamp and signature are provided in the UID, signatureTimestamp, UIDSignature fields of the User object respectively.
See further details in the reference documentation for your SDK.

 

If there is no SDK available for your language and you are using our JavaScript API you will need to implement the signature validation process. The following section gives the implementation steps.

 

Signature Validation Process

 Please follow these steps to implement signature validation:

  1. Validate that the timestamp is within 3 minutes of your current server time. Note that the timestamp is in "Unix time format" meaning the number of seconds since Jan. 1st 1970 and in GMT/UTC timezone. The timestamp is provided in the signatureTimestamp field of the User object.

  2. Construct a signature from the UID, signatureTimestamp and your secret key. Follow the instructions in the Constructing a Signature section below.

  3. Compare the signature you have calculated to the one generated by Gigya. If the UID signature is valid the two would be exactly the same. The Gigya signature is provided in the UIDSignature field of the User object.

  

Following is a pseudo code of the validation process:

boolean isValidSignature(timestamp, UID, secretKey, signature)
{
    If abs(now-timestamp)>180 then return false;      // Validate that the timestamp is within 3 minutes of your current server time
    mySignature = constructSignature(timestamp, UID, secretKey);  // See the code of this method in "Constructing a Signature" section below
    if (mySignature<>signature) return false;        // Compare the signature you calculated to the one received
    return true;
}

 

Following is a Perl implementation of the validation process:

use Digest::HMAC_SHA1 qw(hmac_sha1);
use MIME::Base64;

# construct signature
sub constructSignature {
       my ($key, $uid, $timestamp) = @_;
       return (encode_base64(hmac_sha1($timestamp.'_'.$uid, decode_base64($key)), ''));
}

# compare incoming signature with constructed signature
sub isValidSignature {
       my ($key, $uid, $timestamp, $signature) = @_;
       my $constructedSignature = constructSignature($key, $uid, $timestamp);
       return($signature eq $constructedSignature);
}

 

Constructing a Signature

Please follow these steps to produce a signature: 

Your partner's "Secret Key" is provided in BASE64 encoding, at the bottom of the Sites Table in the Dashboard section in Gigya website (please make sure that you are logged in to Gigya's website and that you have completed the Gigya's Site Setup process).

  1. Construct a "base string" for signing: "%Timestamp%_%UID%" replacing %Timestamp% and %UID% with the corresponding values.

  2. Convert the base string into a binary array using UTF-8 encoding.

  3. Optional - If you have a mechanism for storing and verifying cryptographic nonces it is recommend that you store the base string as a nonce and verify that you only get the same base string once.

  4. Convert your "Secret Key" from its BASE64 encoding to a binary array.

  5. Use the HMAC-SHA1 algorithm to calculate the cryptographic signature of the "base string" constructed in step 1, with your binary "Secret Key" calculated in step 4 as the key. The HMAC-SHA1 algorithm is implemented in many standard libraries and is readily available in any web development environment. The HMAC-SHA1 method usually receives two parameters: a binary key, and a buffer to be signed. It returns a binary array containing the signature.

  6. Convert the signature to a BASE64 string.

     

Following is a pseudo code of the signature construction:

string constructSignature(string timestamp, string UID, string secretKey) 
{
    baseString = timestamp + "_" + UID;                                  // Construct a "base string" for signing
    binaryBaseString = ConvertUTF8ToBytes(baseString);    // Convert the base string into a binary array
    binaryKey = ConvertFromBase64ToBytes(secretKey);     // Convert secretKey from BASE64 to a binary array
    binarySignature = hmacsha1(binaryKey, baseString);      // Use the HMAC-SHA1 algorithm to calculate the signature
    signature = ConvertToBase64(binarySignature);              // Convert the signature to a BASE64
    return signature;
}

 

Notes:
  1. Signature construction should be implemented on the server side.
  2. When sending the parameters from your client to your server, please make sure you encode the UID parameter using the encodeURIComponent() function, before sending it to your server, and then decode it on your server before calculating the signature.
  3. This algorithm implementation applies when using Gigya's JavaScript API or a Mobile SDK. When using our REST API, please sign the HTTP requests using the algorithm that is described under the Signing requests section of the Using the REST API guide.

 

Validate Friendship Signatures when Required

In some scenarios it is required to validate friendship signatures to make sure the user is really a friend of another user. For example, suppose you have a news web site and you keep track of your articles read by your users. When a user logs in to your site you want to show her what articles her friends have recently read on your site. Without signature verification a malicious user may tamper with the friends list and pretend to be a friend of users he is not really friends with, by that he would gain access to the articles read by those users and violate their privacy. To prevent this scenario Gigya provides an optional "friendship signature" that verifies the two users are really friends.

In order to enable the friendship signature you must set the signIDs field to 'true' in the global configuration object passed to  socialize.getFriendsInfo or socialize.showFriendSelectorUI methods. The result of this action is that all the Friend objects returned by these methods will be signed by Gigya. Now your job is to validate the signature received within each Friend object.
 

If you are using one of Gigya's SDKs, implementation is simple. Use the SigUtils.validateFriendSignature() method provided in your SDK. 

The method receives five parameters:

  1. UID - the UID of the current user.
  2. timestamp - use the signatureTimestamp field of the Friend object.
  3. friendUID - the UID of the friend to be validated. Please use the UID field of the Friend object.
  4. secret - use your partner's 'secret key', obtained from Gigya's Dashboard page.
  5. signature - use the friendshipSignature fields of the Friend object.

 

If there is no SDK available for your language and you are using our JavaScript API you will need to implement the signature validation process. The process is identical to the process described in the Signature Validation Process section, except the base string is constructed as "%timestamp%_%friendUID%_%UID%". Where %timestamp% is provided in the signatureTimestamp field of the Friend object, %friendUID% is provided in the UID field of the Friend object, and %UID% is the current user's UID.

 

 

Signed UIDs Passed to Gigya's JavaScript API Methods

For the same reasons mentioned above, some client side API methods, such as socialize.notifyRegistration, socialize.setUID and socialize.notifyLogin require you to sign UIDs passed to them in order to validate the authenticity of those UIDs. It is vital that you construct these signatures on your server side and pass them to your client for making the API call. The "signature" parameter of the socialize.notifyRegistration, socialize.setUID and socialize.notifyLogin methods is defined for this objective, and is a required parameter. Gigya will verify the authenticity of the signature parameter to prove that it is in fact coming from your site and not from somewhere else.
Follow the instructions below to set the signature parameter of the method, and make the API call as soon as possible after that to prevent the signature from expiring.

If you are using one of Gigya's SDKs, implementation is simple. Use the SigUtils.calcSignature() method provided in your SDK. The method returns a signature as expected by Gigya. The method receives two parameters:

  1. baseString - construct the base string according to the specification in each respective method reference documentation.
  2. key - use your partner's 'secret key', obtained from Gigya's Dashboard page.

 

If there is no SDK available for your language and you are using our JavaScript API you will need to implement the signature calculation process. Please follow the implementation steps described in the Constructing a Signature section.

 

Control Session Expiration

When a user logs in via Gigya, Gigya creates a login session for the user. For customers of Gigya's Social Login the session stays valid forever, or until the socialize.logout method is called. For Registration-as-a-Service users, default behavior is that the session ends when the browser is closed or when accounts.logout is called.
Gigya gives you the option to change the default behavior and decide when to terminate a login session. 
Use the sessionExpiration parameter of the (Socialize) showLoginUI / login or (RaaS) gigyaPlugins.sessionExpiration parameter in accounts.setPolicies, to set session expiration. Note that logging-out and cookie deletion will end a session regardless of settings.  

  • Assign a positive integer value to define the time in seconds that Gigya will keep the login session valid for the user.
  • Assign the value '0' to end the session when the browser closes. This is the default setting in RaaS. 
  • Assign the value '-1' for dynamic control over session expiration. Dynamic control is done using a cookie. Read below how to define a Gigya session-expiration cookie.
  • RaaS only: Assign the value '-2' to have the session last indefinitely.

 

Defining a Session Expiration Cookie

To dynamically terminate a Gigya session, you will need to generate and store a 'session-expiration' cookie. You should generate the cookie during each of your server responses, so that the expiration time is counted from the time of the latest user activity on the site. The cookie should be located on your site's base domain (e.g. yoursite.com), and have the following structure:
 

Cookie Name:

"gltexp_" + "INSERT-YOUR-APIKEY-HERE"

Replace "INSERT-YOUR-APIKEY-HERE" string with your Gigya API-Key, which can be obtained on the  Dashboard page on the Gigya website.

 

Cookie Value:

If you are using one of our Server Side SDKs, then you can use the SigUtils.getDynamicSessionSignature utility method to generate the cookie value.

Otherwise, basically the value of the cookie is a signed expiration time. The value format is:

<Expiration Time in Unix Time Format> + '_' + BASE64(HMACSHA1(<Your Secret Key>, <Login Token> + '_' + <Expiration Time in Unix Time Format>))

Where:

  • <Expiration Time in Unix Time Format> - The expiration time in seconds since Jan. 1st 1970 and in GMT/UTC timezone.
  • <Login Token> - The login token received from Gigya after successful Login. Gigya stores the token in a cookie named: "glt_" + <Your API Key>
  • <Your Secret Key> - Your Gigya "Secret Key", is provided, in BASE64 encoding, at the bottom of the  Dashboard page on the Gigya's website.
  • HMACSHA1 - Apply the HMAC-SHA1 algorithm to sign the base-string (2nd parameter) using the secret key (1st parameter).
  • BASE64 - Convert the signed string to a BASE64 string.

Please refer to Constructing a Signature for a detailed explanation on how to apply the HMAC-SHA1 algorithm to sign the base-string (Note, ignore the first step that constructs a base string).

Pseudo code of cookie value calculation:

    unsignedExpString = loginToken + '_' + expirationTimeUnix; // define base string for signing
    
    signedExpString = BASE64(HMACSHA1(secretKey, unsignedExpString)); // sign the base string using the secret key

    cookieValue = expirationTimeUnix + '_' + signedExpString;   // define the cookie value

 

Path:

The location of the cookie should always be your site's base domain, i.e. path="/".
Make sure to use only your base domain (e.g. yoursite.com), do not use a subdomain (e.g. news.yoursite.com) or subfolders (e.g. yoursite.com/sports).

 

Code Sample

The following is a PHP code sample that generated a session-expiration cookie:

$APIKey = 'PUT_YOUR_API_KEY_HERE';
$secretKey = 'PUT_YOUR_SECRET_KEY_HERE';

// This method generates and stores a 'session-expiration' cookie
// that will dynamically terminate a Gigya session <secondsToExpiration> seconds from now
function generateGigyaSessionExpirationCookie($secondsToExpiration) {
    $cookieName = "gltexp_" . $APIKey;  // define the cookie name
    $cookieValue = calculateExpCookieValue($secondsToExpiration);    // calculate the cookie value
    $cookiePath = "/";     // cookie's path must be base domain
    setcookie($cookieValue, $cookieName, time() + $secondsToExpiration, $cookiePath);
}

function calculateExpCookieValue($secondsToExpiration) {
    $currentTime = time(); // current time in milliseconds
    $expirationTime = $currentTime + $secondsToExpiration; // expiration time in Unix time format
    $tokenCookieName = "glt_" . APIKey;   //  the name of the token-cookie Gigya stores
    $loginToken = $_COOKIE[$tokenCookieName]; // get the login token from the token-cookie.
    $unsignedExpString = $loginToken . '_' . $expirationTime; // define base string for signing
    $signedExpString = signBaseString($secretKey, $unsignedExpString); // sign the base string using the secret key
    $cookieValue = $expirationTime + '_' + $signedExpString;   // define the cookie value
    return $cookieValue;
}

function signBaseString($key, $unsignedExpString) {
    $unsignedExpString = utf8_encode($unsignedExpString);
    $rawHmac = hash_hmac("sha1", utf8_encode($unsignedExpString), base64_decode($key), true);
    $signature = base64_encode($rawHmac);
    return $signature;
}
Notes
  • This sample is not meant to be fully functional code. For brevity's sake, only the code required for demonstrating the cookie generation is presented.
  • The code is server-side, you must never use a secret key from the client side (Javascript).

Use REST API Calls when Verified User Data is Required

The signature mechanism described above will prevent any tampering with users' and friends' IDs but it is not meant to protect other data fields, like the user name or email address. If your application requires this data to be authenticated with the data received from the provider, you should make a REST API call to Gigya, directly from your server to retrieve that data. Learn more in the Using the REST API guide.

 

Choose the Right Balance Between Performance and Privacy

Gigya's JavaScript API, REST API and SDKs offer you a choice of making API calls over HTTP or HTTPS. Using HTTPS ensures that no one can eavesdrop on the data passed over the wire but on the other hand it is significantly slower than HTTP communication. Most web sites use HTTP for everything except the most critical data exchanges, such as the login process. You should consider which API calls justify being called over HTTPS and which will benefit from the extra performance of HTTP.

 

Signing REST API Calls

When making REST API calls over HTTP the call has to be signed using the OAuth 1.0 signature calculation method. For more information see the Signing requests section of the Using the REST API guide.

 

General Note about Signatures

Remember that signatures contain binary data encoded using the BASE64 format. That format uses characters that must be properly encoded when passed between the browser and the server or the signature verification will fail.

Was this article helpful?
Pages that link here
Page statistics
21696 view(s) and 11 edit(s)
Social share
Share this page?

Tags

This page has no custom tags set.

Comments

You must to post a comment.

Attachments