ChrisC
ChrisC

Reputation: 2703

Use of OAuth "client credentials" in browser-based app

We're building a web application that handles user join applications, and are considering a few options around client-server versus SPA type applications. Our preference from a user experience perspective is probably fully client-side SPA, but I have API security concerns.

Because we're not authentication users (they're not users yet), the OAuth standard would imply we would need to use the "client credentials" grant type. This is not a problem if the server handles this, but in an SPA the credentials themselves are sitting in the browser for anyone to see, and our API gateway could not distinguish between a legitimate API call from our SPA in the browser versus a script someone has written with the harvested details.

A server side application could hide the client credentials and at least make sure that a) API calls require an active session (using cookies), and b) we can limit the number of certain API calls to just one per session. The server could call our API gateway with its own private credentials having done a few checks.

On the other hand with a Single Page Application running in the browser about the only controls I can think of are to do rate limiting on API calls in the API gateway, but I suspect this will achieve very little.

Random thought: One idea I had was to use "implicit" OAuth grant type as if it was a user authentication process. When we redirect to the "login" page, it actually requires no user interaction and instead grabs a fingerprint of the device (e.g. IP address, browser, language, screen resolution) then redirects back as a "successful" login. Then the client has a unique access token and we've tracked a few details about the end user for audit purposes, and potentially risk evaluation. This requires customisation of our Auth Server - certainly possible but not necessarily ideal.

Are there any other approaches people have taken to protecting API calls in SPA web apps which are successful and secure? Or am I stuck with routing API calls through the app server which applies browser-based controls?

Appreciate any thoughts or insights...

Upvotes: 5

Views: 1501

Answers (1)

ChrisC
ChrisC

Reputation: 2703

If anybody cares - and judging from the number of views, possibly not! :) - the approach we're taking is as follows:

Where possible:

  • We'll have an application server of some sort responsible for dynamically generating the JavaScript for the page rather than serving static content from a web server
  • The app server is going to internally exchange the client credentials for an access token with a time limit, and embed that access token in the JavaScript sent to the browser
  • If a hacker grabs the access token then they can use it but only within a limited time window (although they could always go back and get a new one by requesting the site again, but that's not that different to POSTing to a web form either)
  • Applying rate limiting at the API gateway level to match expected API traffic from the legitimate site, so if someone scripts something to use the API and a harvested token then not only will they not have long to do it, they won't be able to hammer the site with unlimited calls

Where it's not possible to dynamically insert the access token into the JavaScript:

  • we're either sacrificing the SPA and doing client-server, or we're just putting client credentials in the JavaScript anyway and acknowledging that they could be compromised
  • We apply rate limiting at the API gateway again
  • The credentials are treated only as an indication for tracking and rate limiting purposes

I decided against the tricky redirection-with-fingerprinting option as far too complex for our needs, but others might want to pursue if the approaches above don't work.

Hope someone finds this useful.

Upvotes: 4

Related Questions