6

I'm wondering if using Javascript closures is a useful technique to limit exposing data to XSS? I realize it wouldn't prevent an attack, but would it reliably make an attack more difficult to execute, or would it only make my code more irritating to write and read (a waste of time)?

I got the idea from the Auth0 documentation regarding storing OAuth/OIDC tokens. It reads:

Auth0 recommends storing tokens in browser memory as the most secure option. Using Web Workers to handle the transmission and storage of tokens is the best way to protect the tokens, as Web Workers run in a separate global scope than the rest of the application. Use Auth0 SPA SDK whose default storage option is in-memory storage leveraging Web Workers.

If you cannot use Web Workers, Auth0 recommends as an alternative that you use JavaScript closures to emulate private methods.

I can see how this is better than just putting the token or other sensitive information in localstorage. In localstorage an XSS attack needs only to execute localStorage.token to get the token.

Now, if you're not familiar with tokens just apply this reasoning to any sensitive to information. In my case I want to build a client-side cache mapping user IDs to usernames for an administrative interface, but I realize that client IDs and usernames are somewhat sensitive, so I wondered if I could "hide" the data.

DavidS
  • 163
  • 4

1 Answers1

6

The goal here is to keep the token secret, even if an attacker exploits an XSS vulnerability - sort or like emulating the HTTP-only flag for cookies, in other words. I guess the closure would be a function that calls the API for you, using the token for authentication, and then return the result of the API call. In that way, you never have to touch the token.

Using closures would offer only a partial protection for a number of reasons:

  • There are lots of other powerful things an attacker can do with XSS. Like stealing the victims password through keylogging.
  • Even if you can't get the token, you can still make calls to the backend with it through the closure. So maybe not permanent access, but temporarey access.
  • You can probably still steal the token in some clever way.
    • My best bet would be to add a service worker that proxies any request to the API and picks it out of them. Not sure this is possible, but I would think so.
    • If the closure allows the caller to specify the URL of the API, just make the calls to evil.com...
    • The token has to get into the closure somehow. Is it hardcoded into the JS code? Grab it with element.innerHTML on the script tag. If not, steal it before it gets into the closure. This may or may not be possible, depending on the set up and the nature of the XSS vulnerability.

Since the protection is so limited, I would not spend a lot of effort on this. Especially, I would not write convoluted and complicated code just to achieve this. But closures can be a good thing for code quality, so if they fit with your code style by all means do use them.

Anders
  • 64,406
  • 24
  • 178
  • 215