8

Background

I'm designing a web widget for a new SaaS for embedding in a password-protected CMS. This would allow the customer to add something like the following to all the pages in their CMS to display some information from my SaaS system:

<script src="https://www.awesome-saas.com/widget.js?userToken=xyz" id="widget"/>

When a user registers with my customer's website, my customer calls my API to retrieve a UUID for the new user in my SaaS system. This is the user token. The unique id used in my customer's CMS is not passed in the API call. The customer CMS stores the association between user's unique id and the token provided by my system. No personal information is stored in my system (no names, DoBs, credit card details etc). This token generation approach ensures anonymity of the data stored in my system and ensures data residency compliance for my platform.

The CMS provides the user token to my javascript widget and the widget makes a request to my API passing the user's token to retrieve a JSON snippet to render on the page.

https://www.awesome-saas.com/getInfo?userToken=xyz

The JSON snippet that is returned does not contain any personal information in it.

All communication between the CMS, the user's browser and my API is done over SSL. There is no sharing of user session between the CMS and my SaaS system.

Problem

How can I secure the requests to my API originating from the javascript widget whilst making it as easy possible for my customer to integrate my service with their CMS?

Some options I have considered:

Option 1

Just passing the UUID token to my SaaS' API is good enough. It would be extremely hard to guess and even if someone managed to do that they wouldn't know who the retrieved data related to.

Pros

  • makes integration easy
  • the responses to my API can easily be cached

Cons

  • could be a hard sell to customer, auditors or regulators
  • it's security through obscurity which feels wrong

Attack vectors

  • compromised browser history would reveal user token
  • brute force guessing could get lucky

Option 2

Get the customer CMS to encrypt all generated tokens and share their public key with us. The encrypted token gets passed to my API, I decrypt it using the customer's public key.

Pros

  • ensures the token has originated from the customer CMS rather than a brute forcer
  • the brute forcer now has to try and guess an encrypted version of an incredibly hard to guess number

Cons

  • can't cache the requests to my API because the encryption on the token needs to be checked every time
  • more work for the customer to integrate with me i.e. code change

Attack vectors

  • compromised browser history would reveal encrypted user token
2

If the token never expires, an attacker can harvest and use the token to access your site indefinitely. Non-expiring tokens can be shared around, with LOTS of attackers using your still-valid tokens.

However, the non-expiring token presents an integration problem. Basically the customer site needs to communicate with your SaaS to obtain a currently-valid token and renew tokens as needed.

You might consider an OAuth 2 type of approach. Your OAuth 2 server hands out tokens (which expire) to the customer website. When your SaaS receives the token, your SaaS validates the token against the OAuth 2 server. If your customers are comfortable with OAuth 2 integration, that might be all you need.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.