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