Security Guidelines

Skip to end of metadata
Go to start of metadata

 

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.

When using any REST API that transmits sensitive data, e.g., passwords or secrets,  recommended best practice is to always use POST requests via an SSL secured connection. When using any Gigya APIs, attempting to send a secret over a non-SSL connection will result in an errorCode: 403006 - Secret Sent Over Http.

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 Web SDK 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 Web SDK from our HTTPS domain. This will not only load the SDK itself over HTTPS but will cause the SDK 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 Web SDK 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/gigya.js?apikey=INSERT-YOUR-APIKEY-HERE" ></script>

 

Alternatively, you can use a simple script to determine if the page is being served  over http or https and dynamically construct the script.

//This places the Gigya Web SDK at the end of the page <head>
function addGigyaWebSDK(apiKey) {
    var apiKey, gig, gSrc;
    if (apiKey) {
        apiKey=apiKey;
        if ((window) && (typeof(window.location.protocol) !=='undefined')) {
	        gig = window.location.protocol == "https:" ? "https://cdns.gigya.com/JS/gigya.js?apiKey=" : "http://cdn.gigya.com/JS/gigya.js?apiKey=";
	        gig = gig + apiKey;
	        gSrc = document.createElement('script');
	        gSrc.type="text/javascript";
	        gSrc.src=gig;
	        document.getElementsByTagName('head')[0].appendChild(gSrc);
        }
    } else {
        if (console) {
            console.warn("No Gigya API Key Found!");
        }
    }
}
addGigyaWebSDK('Your-API-Key');

Notes:

  • In the above code example, note https://cdns.gigya.com, as opposed to the non-SSL SDK located at http://cdn.gigya.com.
  • If you are using generated code or one of our code examples, the above line should substitute the equivalent line that loads Gigya's Web SDK from an HTTP domain.

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.

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 Web SDK you will need to implement the signature validation process. The following section gives the implementation steps.

Using A User Key or Application Key

If you are using a user key or application key and their corresponding secret (as opposed to the partner secret in your Dashboard) you can use accounts.exchangeUIDSignature to verify a UID signature with a userKey/secret instead of a Partner secret.

Signature Validation Process

The following graphic illustrates the login and 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 in the 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.

 

The following is the validation process in pseudo-code:

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;
}


The following is a PHP example of validating a signature using our PHP SDK.

<?php
require_once('GSSDK.php');
require_once('secret.inc.php');
require_once('apiKey.inc.php');
$UID = <UID>;
$timestamp = <signatureTimestamp>;
$secret = <secret>;
$signature = <UIDSignature>;
$isValidSession = SigUtils::validateUserSignature($UID,$timestamp,$secret,$signature);
if ($isValidSession === true) {
    echo 'Validation passed!<br />';
} else {
    echo 'Validation failed!<br />';
}
?>


The following are Perl and Ruby implementations of the validation process not using an SDK:

Perl

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

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, binaryBaseString);    // 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 Web SDK 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 Web SDK 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 Web SDK 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 Web SDK 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 or Raas, the session stays valid forever unless the socialize.logout method is called (accounts.logout for RaaS) or the cookie is deleted.

Gigya gives you the option to change the default behavior and decide when to terminate a login session. 

Use the sessionExpiration parameter of showLoginUI/login (in Social Login) or the gigyaPlugins.sessionExpiration parameter in accounts.setPolicies (in RaaS) to set session expiration. Note that logging out and cookie deletion will end a session regardless of settings.

This parameter defines the length of time that Gigya should keep the user's login session valid.

The expected values are:

  •  0 - Session expires when the browser closes.

  • -1 - Session ends immediately and a cookie is stored on the site visitor's client (browser) which allows the site to change the expiration while the user is logged in. Useful if you always and only set the session expiration via individual API methods. For additional information see how to Control Session Expiration.

  • -2 - Session is valid forever.

  • Any custom integer, defined as the number of seconds to keep the session active, e.g., 3600  (which is equivalent to 1 hour).  In this case, the session will remain valid until it expires or until it is explicitly ended (e.g., by calling accounts.logout).

You can override global policy settings and the Global conf setting via setting the expiration as a parameter in any of the supported API methods (i.e., notifyLogin). When this parameter is set via an API method, it overrides the value of the identical parameter in Global Conf (the global configuration object).

If this parameter is not set for the API method, the value from Global Conf is used. If the parameter is not set in Global Conf, the login session uses the default.

Defaults: 

  • When RaaS is enabled for the API Key, default expiration is 0 (when the browser closes).
  • When using Social Login (RaaS is not enabled), default expiration is -2 (the session is valid forever and only terminates when the user logs out or the cookie is deleted).

Note: In a Single Sign-On (SSO) situation, if different sites in the group have different session expiration values, the user's session expiration is governed by the site they originally logged into. Visiting other sites in the same SSO group (that may have higher or lower session expiration values) does not create a new session and does not change the session expiration value of the user's current session.

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.

If sessionExpiration is set to -2 (valid forever), session expiration cookies are disregarded. To end the session, call socialize.logout (accounts.logout for RaaS) or delete the session cookie.

 

The session expiration 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, 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 Format> - The expiration time in seconds since Jan. 1st 1970 and in GMT/UTC timezone.
  • <Login Token> - A substring of the cookie received from Gigya after successful Login. Gigya stores this in a cookie named: " glt_" + <Your API Key>To get the login token, take the substring of all characters up to the first pipe delimiter. See the php code sample below. 
  • <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.

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 (i.e., news.yoursite.com) or subfolders (i.e., 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($cookieName, $cookieValue, time() + $secondsToExpiration, $cookiePath);
}

function calculateExpCookieValue($secondsToExpiration) {
    $currentTime = time(); // current Unix time (number of seconds since January 1 1970 00:00:00 GMT)
    $expirationTime = $currentTime + $secondsToExpiration; // expiration time in Unix time format
    $tokenCookieName = "glt_" . APIKey;   //  the name of the token-cookie Gigya stores
	$tokenCookieValue = trim($_COOKIE[$tokenCookieName]); 
	$loginToken = explode("|", $tokenCookieValue)[0]; // 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 Web SDK, 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. BASE64 format (as well as email addresses, etc.) uses characters that must be properly encoded when passed between the browser and the server or the signature verification will fail. Be sure to use encodeURIComponent() on all pertinent strings.

Example

userKey='LV/24EGI7T+xl';
userKey=encodeURIComponent(userKey); // >> LV%2F24EGI7T%2Bxl

 

Application and User Keys

Using the Gigya API with a User Key

If you are not the main site administrator, you may not have access to the Partner Secret Key. Instead, you can call the GIgya API using your user key and user secret. You still need to pass the API Key of the target site. Note that calls performed this way are subject to the user key's permissions and are logged for auditing purposes.

When you pass a request across HTTPS, include the site's API Key and your personal User Key and Secret. For example:

 

https://...?apiKey=[SITE_API_KEY]&userKey=[USER_KEY]&secret=[USER_SECRET]

 

For more information about user keys, including instructions for finding your user key in the Gigya Console, see Using the User Key.

Creating A User Key

You can make REST Requests using a userKey and secret. This is useful for delegating access to Gigya APIs without revealing your account's secret to multiple users. You can create multiple Applications, and give groups of users access to these various applications with each application having only the permissions that you define in it's settings. Each application has a userKey and secret that can be used when making REST calls to Gigya API Endpoints.

Another benefit of using a userKey and secret is that the user does not have to construct or check signatures, however, this means that all requests must be conducted over HTTPS.

To manage your Gigya Applications:

  1. Login to your Gigya Console.
  2. Navigate to the Admin tab.
  3. Select Manage Applications.
  4. Once on the Applications page, press Create New Application and follow the on-screen prompts.



  5.  Once the app is created you can view the Apps userKey and secret by clicking the Edit icon, which will take you to the apps Edit Application page.



  6.  You can disseminate this userKey and secret to users whom you want to attain the privileges associated with this app. Users will use this userKey and replace the secret parameter in the request with the secret associated to this key.
  7. If at any time you want to revoke access for users using this Application, simply delete it from your account and all future attempts to use this userKey and secret will fail.

 

curl Code Example

curl https://accounts.us1.gigya.com/accounts.search 
 --data-urlencode "apiKey=3_mKxxxxXXXXXXXXxxxxxxxxXXXXxxXxxxxxxxxxxxxxxxxxxXXXXXXXXXXXXxxxxx" 
 --data-urlencode "userKey=AJxXXxXxxX2X" 
 --data-urlencode "secret=X73xXXXXXxxxxXXXxxxXXXx656767Xxx" 
 --data-urlencode "format=json" 
 --data-urlencode "query=select UID, identities.provider, identities.providerUID from accounts limit 10"

In the above example, the secret is the secret associated with the userKey, not the account secret located in the Gigya Dashboard.