13

I have this web application that is going to be all client-side technology (HTML, CSS, JavaScript/AngularJS, etc...). This web application is going to be interacting with REST API in order to access and modify data. Right now it is undecided on what type of authentication system the REST API is going to use.

From my understanding, any type of API authentication system (API Keys, OAuth 1/2, etc...) is going to have certain data that needs to be kept secret otherwise access can be compromised. For API Keys, they keys themselves need to be secret, for OAuth 2 the client secret/access tokens/refresh tokens need to be kept secret, I am sure a few of the 4 keys involved in OAuth 1 needs to be kept secret (not too much experience with OAuth 1). I have been trying to think if there is a way to store this secret stuff in a pure client-side web application without a middle layer of sorts on the server side.

I have been trying to think about this and I can't think of any place to do that. I mean I can't store it in javascript because anyone can just view the source or open up the console and get the data. I am not 100% sure how secure localStorage is and if users can access/modify that data. Even if local storage was secure, the two ways I can think of getting data into it are not. One way is to just store the data in the javascript source code which is the most insecure thing I can think of. Now if I was using something like OAuth 2 in which the rest api itself would give me the tokens, that would still not be that secure (better than the first option) because those tokens would be returned as plain text that anyone who can see the requests the computer is making could see.

Is there any way to have an application that is completely running client side be able to store secret pieces of data securely without some sort of middle layer on the server side?

3
  • Localstorage is browser-specific, but taking Opera on Windows as an example, it's just some disk files in the user's profile folder, so it's essentially unprotected. Apr 7 '13 at 13:01
  • One way would be to keep the secret on the server in a db and only have application_id on the client. Then do the oauth query from the server, so this is some kind of proxy approach. Dec 6 '14 at 18:30
9

No, it can never be completely secure. The user is in control of the hardware, and you are trying to keep something out of their hands. Ultimately, they CAN get it through one means or another. Since you are working from javascript, your position is MUCH worse than a normal computer application, as not only does the user control the hardware, they control the sandbox that you are running in.

You can hide things, and make it hard to get to stuff, but in the end they CAN get it out, if they try hard enough.

2
  • 4
    ^this. How "secret" is the secret data, and how much time and money is protecting it actually worth? "Industry standard" efforts might be sufficient.
    – DaveE
    Apr 5 '13 at 18:14
  • +1 Excellent answer. With a JavaScript debugger, I can alter your application, view intermediate values, etc. If I want the information, I will get it. Apr 7 '13 at 13:11
2

When designing security systems, one always needs to think about the threat model. "Make it secure" is a silly requirement, not actionable or verifiable. "Prevent the user from extracting the access tokens from the application" is much better, and defines the boundaries of the solution. "Prevent others from obtaining a user's access tokens" is also better, and defines a completely different solution space. Solutions for one won't necessarily solve the other (e.g., the latter absolutely requires SSL if WiFi is involved, but that won't affect the former at all).

0

one option is for the REST API to grant access or not based on a user login; it can return a session-based token (guid, hashed string, whatever you like) which can be passed to the other REST API calls to authenticate access

if you're worried about storing the user login info on the client machine, then don't, but the user will have to enter the account and password information every time

not that familiar with OAuth et al, but I see no compelling reason above to store authentication information persistently at all...

1
  • As for reasons, there is always "comfort" which obviously is the arch-nemesis of "security" and "safety".
    – henon
    Apr 19 '18 at 14:20
0

@Michael Kohne is mistaken, there is 1 very established way to protect data in the browser. Banks do it, every site on the internet that shows you content that only you should see can do it securely. @Ross Patterson started strong and is so close to being a perfect answer. The right approach is using a threat model and apply a risk based decision. But what was missing is something actionable for you.

Simply put; it will be deemed "secure" by the user, if the user is "challenged" before the sensitive information is sent to the browser. A challenge can be an interaction like a simple passphrase or something more complicated like MFA, or it can be out-of-band like most password-less options (hardware token, bio-metric, or magic link emailed to the user). There is also the non-interactive answer, like public key cryptography that is used by many companies like protonmail to ensure zero-knowledge email service that only the "browser user" can read their emails and even the email providers can't. You may have noticed in 2018 reCAPTURE v3 has a zero-interaction solution (but most sites still use the annoying v2 that asks you to click annoying images for 5mins).

All of this to say;

  1. Challenge the user, or use client-side crypto, and after the server validates the individual you can share a secret with the browser user securely
  2. Make sure your transfer is secure too, TLSv1.2 or newer with only Forward Anonymity cipher permitted - no fallback allowed
  3. If you don't consider this secure, you're pretty much alone in that opinion and should disconnect, move to the mountains of Antarctica, and make yourself a tin-foil hat

Hope that gives you, and other readers, the tools to make good choices

3
  • 1
    You answer is ignoring the situation, which is that the OP wants to keep certain pieces of information secret from the authenticated user, on the authenticated user's machine. Not straight-forward at all. Jan 4 at 6:18
  • Not entirely true, if the user needs the information it's sent to them and only them with assurance through identify challenge and verified cryptographically. If they don't need it, don't send it. If what is described by the OP, OAuth particularly, it requires a server side step but the token/key it results in is still sensitive and it is fine to go the the browser, for that user that owns it.
    – stof
    Jan 5 at 7:59
  • I can be more practical here, localStorage persists data for a browser, and follows same origin cors rules t(if it worked differently hat would be a browser zero day). So for a single user scenario where your session system is designed like google accounts (you can only have 1 active user in the browser at a time) then using localStorage is perfectly secure. Thus all of these are considerations for your threat modelling, and if you fulfill your functional and business requirements within your acceptable risk posture there's nothing more you can do.
    – stof
    Jan 5 at 7:59

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.