Storing API access token server-side - javascript

I have built an app in React that uses the Dropbox API & will be stored on AWS S3 & CloudFront. The app accesses the Dropbox folder using a token. At the moment this token is client-side and obviously is completely accessible.
I have tried reaching out to Dropbox, looked into cookies & HTML5 web storage but can't seem to find a simple explanation.
What would be the simplest way of securing this token on the server?

There are few pros and cons of storing an access token in the server.
However, the most secure way of storing it on your server is sending it to the server via https link.
One major disadvantage of storing an access token in the server is that you, as the owner of the service, is bound to take the responsibility of securing the token. If your server is ever compromised, the hacker gets access to all the data of all the users by having simple access to all their access tokens.
You can always store the dropbox access token on the client side as a storage variable. Each storage is accessible only to the scripts served from the same domain.
~Edit~
If the Dropbox account is owned by the owner of the website and it should be hidden from the end user, you need to operate the Dropbox account from within the server. This DropBox accessing microservice has to be utilized as a proxy for accessing files.

Related

How to store OAuth2 access tokens in a React application?

I'm new to React and want to securely store the OAuth2 access token to invoke APIs. I have found following options,
Keep it in the local-store/session-store (This can be vulnerable to XSS attacks)
Having a back-end for the React application and store access token in back-end session and keep a session cookie to identify browser session. Then make all the API calls through back-end to add Bearer header.
Encrypt the access token and store it as a cookie. API access will be haven through the back-end where encrypted cookie will be decrypted and added as a Bearer header.
What will be the best solution for this?
I would go for third option
Encrypt the access token and store it as a cookie. API access will be haven through the back-end where encrypted cookie will be decrypted and added as a Bearer header.
Everything related to token we have to store in the client side there is no way around but can make it secure by adding encryption to it to make it more secure but this approach will make developer has to setup encrypt and decrypt algorithim to handle to token
Your second option is best. We also doing this.
Having a back-end for the React application and store access token in back-end session and keep a session cookie to identify browser session. Then make all the API calls through back-end to add Bearer header.
One of the best solution I found recently is oauth2-worker, here it stores tokens in variables inside a worker so that it won't be accessible from the js running on the applications. Also it works as a proxy and we need to make API calls through the worker so that it adds the Authorization header.

Secure access directly from web app to amazon s3?

Per my review of how to setup secure access to amazon s3 buckets it looks like we first generate an IAM user and then tie a security policy allowing s3 access to that user. After that we can generate API keys for the bucket, which can authenticate request for bucket access. That's my understanding at this point, please correct me if I missed something.
I assume the API keys should be server side only (The Secret Access Key). In other words it's not safe to place these directly inside the webapp? Hence we would first have to send the data to our server, and then once there we can send it to the bucket using the API key?
Is there any way to secure access directly from a web app to an amazon s3 bucket?
Approach Summary
Per the discussion with #CaesarKabalan it sounds like the approach that would allow this is:
1) Create an IAM user that can create identities that can be authenticated via Amazon Cognito - Lets call the credentials assigned from this step Cognito Credentials.
2) The user signs in to the webapp with for example Google
3) The webapp makes a request to the webapp's server (Could be a lambda function) to signup the user with Amazon Cognito
4) The webapp now obtains credentials for the user directly from Amazon Cognito and uses these to send the data to the s3 bucket.
I think that's where we are conceptually. Now it's time to test!
From your question I'm not sure what portions of your application are in AWS nor your security policies but you basically have three options:
(Bad) Store your keys on the client. Depending on the scope of your deployment this might be ok. For example if each client has it's own dedicated user and bucket there probably isn't much risk, especially if this is for a private organization where you control all aspects of the access. This is the easiest but less secure. You should not use this if your app is multi-tenant. Probably move along...
(Great) Use an API endpoint to move this data into your bucket. This would involve some sort of infrastructure to receive the file securely from the client then move it into S3 with the security keys stored locally. This would be similar to a traditional web app doing IO into a database. All data into S3 goes through this tier of your app. Downsides are you have to write that service, host it, and pay for bandwidth costs.
(Best) Use Amazon Cognito to assign each app/user their own access key. I haven't done this personally but my understanding is you can provision each entity their own short-lived access credentials that can be renewed and you can give them access to write data straight to S3. The hard part here will be structuring your S3 buckets and properly designing the IAM credentials for your app users to ONLY be able to do exactly what you want. The upside here is the users write directly to S3 bucket, you're using all native AWS services and writing very little custom code. This I would consider the best, most secure, and enterprise class solution. Here is an example: Amazon S3: Allows Amazon Cognito Users to Access Objects in Their Bucket
Happy to answer any more questions or clarify.

RESTful API write security

I've recently started using modern front end technologies like React/Angular and as a result have started using tools like JSON Server to recreate dummy restful db interactions.
My understanding is that most rest api's authenticate via some kind of token and secret that is either passed as part of the url or as a header. This seems fine for retrieving data, but is it not risky exposing these login credentials in a front end language like JS when writing is possible?
My thinking is that all it would take is a simple view source for somebody to steal my token/secret and potentially start populating my db with data.
In the problem that you describe the client (browser) has the login credentials because the server provide them. There is no "exposing" as the credentials are already exposed. Exposing your credentials to every client means that there is no security.
When we talk about security we consider as a client the browser not the real person that operates the browser. As you said, the real person can access all the browser's data.
To secure your API the secret key must be kept secret. This means that each client has a different key and uses it to get their data/services from your RESTfull server.
In a simple senario this key can be used/managed like the session id.
The client should first pass through an authorization process (login maybe) and then a temporary key can be generated for the client's session.
Generally, a key is converted to rights. If every client by default has the key, everyone has the default rights, so you may also remove the key and set the default rights to every request.
A client that you don't want to have full access to your db should have a key that gives him limited access to your db.
On the other hand, if the client provides the key, this is secure. For example a php code on a server that uses the secret key for accessing your API.

How do websites keep you logged in

Quick Question: When you login to your account on a website what does it do to keep you logged in so you don't login again and again when you visit another page?
Cookies and Session are some of the traditional ways that authentication details are stored in browser. However through these approaches server has to keep track of logged in users and their cookies to validate. So there is some server operation in managing logged in users. However there's a new approach known as JSON Web Token aka JWT. Here server will generate an user specific token and sends into browser client on logging moment. Browser will store this token in HTML5 Local Storage or Session Storage and will be sending this token with every request! So here for every refresh browser code can check for the availability of this token in Local Storage or Session Storage. Advantage of this approach is that the server doesn't have to keep track of issued token and is able to extract data from token if needed. This JWT is widely used in authenticating Web applications developed using advanced Javascript frameworks : Angularjs or Reactjs(with supporting libraries)
Browsers will keep you logged in by using some sort of browser storage. (for example cookies or localStorage or...). This data is called session data.
Html pages are stateless, that means when you refresh a page, all data that came from the server previously, are removed, and have to be requested again.
Now to request a protected page, there has to be a way to tell the server that you are the user that is logged-in a few minutes ago! This is done by storing some encrypted data in browser, usually in cookies.
Browsers are designed in a way that automatically send a specific page's all cookies to server when the page is opened. Server has the exact encrypted data in files or database and compares it with browsers data. if they match, server will allow protected content to get viewed by user, so will send the requested content as response.
you can simply test this by clearing your browser cache after login and then refresh, you will see that you are logged out, and not allowed to see protected page.
It is all about sessions.
Source
In computer science, in particular networking, a session is a
semi-permanent interactive information interchange, also known as a
dialogue, a conversation or a meeting, between two or more
communicating devices, or between a computer and user
Web server session management
...
Hypertext Transfer Protocol (HTTP) is stateless: a client computer
running a web browser must establish a new Transmission Control
Protocol (TCP) network connection to the web server with each new HTTP
GET or POST request. The web server, therefore, cannot rely on an
established TCP network connection for longer than a single HTTP GET
or POST operation. Session management is the technique used by the web
developer to make the stateless HTTP protocol support session state.
For example, once a user has been authenticated to the web server, the
user's next HTTP request (GET or POST) should not cause the web server
to ask for the user's account and password again. For a discussion of
the methods used to accomplish this see HTTP cookie and Session ID
In situations where multiple web servers must share knowledge of
session state (as is typical in a cluster environment) session
information must be shared between the cluster nodes that are running
web server software. Methods for sharing session state between nodes
in a cluster include: multicasting session information to member nodes
(see JGroups for one example of this technique), sharing session
information with a partner node using distributed shared memory or
memory virtualization, sharing session information between nodes using
network sockets, storing session information on a shared file system
such as a distributed file system or a global file system, or storing
the session information outside the cluster in a database.
If session information is considered transient, volatile data that is
not required for non-repudiation of transactions and does not contain
data that is subject to compliance auditing then any method of storing session information
can be used. However, if session information is subject to audit
compliance, consideration should be given to the method used for
session storage, replication, and clustering.
In a service-oriented architecture, Simple Object Access Protocol or
SOAP messages constructed with Extensible Markup Language (XML)
messages can be used by consumer applications to cause web servers to
create sessions.
In raw php (most well known frameworks has session management middleware, so you shouldn't worry about it) if you want to manage a session, you have to include
session_start();
procedure on top of your pages. When you do this, you are creating a 24 minutes (1440 seconds) session (by default).
You can modify it to any integer from your php.ini file.
All session data in php stored in $_SESSION global. Hence, it is an array, so you can set session variables (aanything you want) like,
$_SESSION['user_name'] = 'ernesto';
$_SESSION['foo'] = 'bar';
...
At any time of your application, you can remove $_SESSION variables,
session_unset();
Assume, you've already set variables above,
print_r($_SESSION);
will print empty array as you've removed variables by unset procedure.
If you want completely to destroy a session,
session_destroy();
will do it for you.
use cookie you can learn: Cookie or Session you can learn Session

Down-scoping Oauth access-token, possible?

I am developing an open source javascript project. It has client side database, Oauth Connect login and bear-token base access to cross domain resource servers like (GData, Google cloud storage, AWS via proxy). The main focus is on consumer cloud data (you know, developer got free data storage).
The main goal to provide database to the web app without using backend server. It is achieved by keeping Oauth 2 refresh token in the server, providing access token to the web app so that it can populate its client side database, directly from resource servers. Dumb proxy server may be necessary for updating back to the resource server.
Login user may share his data to other login user. Server provides access token as necessary. In that case I wish to down-grade the access token. Generally once a new user start using the app, the server request off-line multiple scopes read-write grant. Currently, I as far I can understand a refresh token can generate access token of exact scopes.
Is that possible to request a down-graded access token from an offline refresh token? Even down grading from read-write to read-only is very useful.

Categories

Resources