Handling the oauth token in a website/service - web-services

I have created a website which allows the user to authenticate against oauth2 (from another provider), the basic flow is (assuming a new user):
The user loads my webpage
An OAuth request token key and secret is provided by the OAuth endpoint
I store the request token into the user's cookies
The user is redirected to the OAuth authentication page from an external provider
The user accepts and is redirected by to my webpage with URL parameters which specify the OAuth verifier and OAuth token
Using the request token (retrieved from cookies) and OAuth verifier (passed via URL parameters), I am able to get an access token key and secret from the OAuth endpoint.
I am now able to authenticate with the providers API and use that to get the logged in user ID.
I then store into a MySQL database, the user ID, a token which I generate as a random unsigned integer, OAuth token and OAuth secret. In cases of the token I generate already being in the database, I just continue in a loop until a unique token is generated. The MySQL database has a strong name, username and password. The database user can only access the table in question and only has privileges to add an entry, delete an entry and make a query.
I clear the request token from the user's cookies and instead store the user ID and my generated token.
When a user comes back to my website, I check if they have the user ID and token stored in their cookies, if so I attempt to look up the OAuth token and secret from MySQL. If they are found, I test they are still valid (does the API endpoint accept them) and if so, the user remains 'logged in' to my website. In cases where the user ID or token isn't found in MySQL or cases where it is found, but is not accepted by the endpoint (expired?), I just go back through the flow above.
The above all works correctly, new users can successfully authenticate, returning users find the website remembers them. I do not expose the OAuth token key or secret to the user and instead, give the user this token ID which I generate.
Are there any problems with what I am doing?
Should I be encrypting the OAuth token key and secret in my database?
Is there a problem with the fact if someone was to gain access to the token I generate, along with the user ID, they would be able to call my scripts. Is this a problem?
Should I be encrypting the user ID and token I generate before storing it in the user's cookies? Taking into account, ultimately whatever is stored in the user's cookies will get passed to my script, so if I were to encrypt, store to cookies, then next time read from cookies and decrypt, the user would still be able to access my endpoints by simply passing the encrypted version (assuming the server decrypts, if the client decrypts then the decryption key would be accessible via the users browser anyway), which doesn't immediately appear to offer any further security.
My goal is to tighten up the steps above so it is deemed robust and secure. The actual use case for my web site means it'll only have a tiny number of users (if any) using it. It was more of a learning process for me, combined with implementing something I actually need. But for the learning aspect alone, I would like to make everything sensible and secure. I am not trying to be overly pedantic and implement steps no other similar websites would implement, basically I would like my site to be secure enough that if there ever was a problem, no one could point a finger at me and say I didn't implement an adequate security system.

Related

API: How to secure access from non-related users?

I am developing a REST API. In my mobile application we have multiple user roles, they all use the same API. Think the roles are like customer, supplier, and admin. The API is using tokens, making sure everyone need to be logged in and should send the token to the API.
However, if someone has the token somehow, he can easily any information belong to any user. For an example, using the token of customer A, we can view the information of customer B, C` and so on.
Not only that, we can also access the API calls dedicated for the admins using the above mentioned token.
this is what I thought of doing.
Send the user ID with every request. Also embed the user ID into the token. In the server, before any method is accessed, check whether the user id in request and token are the same.
FYI I am using Firebase authentication and tokens, then use AWS API Gateway to authenticate the access to the API. The user Id I was referring to is in database.
How do you think I can overcome this issue and secure the API?
As long as you make sure to pass the tokens only over secured connections, interception of that token is not very likely. If you then use short-lived tokens (such as Firebase's ID tokens), even when a token does get intercepted it can only be used for a short amount of time.
If a token does get intercepted, you can revoke the token, as shown in the Firebase documentation on managing user sessions.
And finally, you can consider implementing App Check for an additional layer of protection, and check that token too in your own backend.

Tronweb authentication

I want to build a webapp that uses the wallet address as account, but yet I want to store the user in my db to allow specifying a nickname.
The problem I'm dealing with is that I want to call different apis, where the user needs to be authenticated / authorized in order to gain access .
Since the authentication happens 100% client side in my case (through the tronlink extension and TronWeb), I don't see another way as to add supplementary authentication for my webapp specifically.
If the user logs in to my app with a different password (not using the private key of the wallet), it seems like bad user experience as the user needs to authenticate twice (through Tronweb AND my webapp with a password).
How do you solve this problem?
It seems that the way to handle this is to foresee a separate login flow for the web app after all.
Even when the user already has logged in into Tronlink, it needs to obtain a token to authenticate rest calls.
The way it would appear to work is by generating a random nonce and storing this nonce along with the public key in the User table.
The login flow then consists of signing the nonce in the front-end, and verifying the signature in the backend after which the token will be generated and returned.

How to authorize user in RESTful request?

From the posts about REST services, I see that it should not be used sessions together with REST, and with every request there is need to send user credentials to the REST service. But I don't see that somebody continues then how to make the authorization in next requests after login.
In my project, I authenticate (login) the user, checking his credentials from database server.
If with every REST request also comes user credentials again, does this mean that, for any need of authorization after login, I need to check the credentials again from the database?
This means, after login, with almost every click and surfing pages, I need to access to the database to check the user credentials, just like I do it for login.
Or...
Am I missing some thing?
Is there another way to remember in the server side that the user had already logged in before and thus is authorised?
Do I keep some secret key related to the user in the server, and then check this etc.? But, does not this mean keeping a session?
REST => Not Session => Send credentials with every request
Does the above mean, => Authorize the user just like in the authentication ?
Or what are other alternatives?
Thank you for clarifications.
I think that this is the best approach:
REST => Not Session => Send credentials with every request
Take a look on OAuth. The version 1.0 may be useful for you.
Spring Security already have implementations for OAuth in Java.
If with every REST request also comes user credentials again, does this mean that, for any need of authorization after login, I need to check the credentials again from the database?
You have to authenticate user on each request, but whether authentication uses database or not depends on implementation. By the way, you also have to then authorize the request for the authenticated user.
Do I keep some secret key related to the user in the server, and then check this etc.? But, does not this mean keeping a session?
You can have some secret key known only to the user as an alternative to username-password pair and use this secret key for authentication.
The presence of a secret key doesn't mean keeping a session, because it is not necessarily change on a per session basis.
In my project, I authenticate (login) the user, checking his credentials from database server.
Login is not authentication, it's usually a request for a secret key / session key done using username-password pair for authentication

When adding Facebook integration to a web app, how do you handle OAuth token expiration and what user data should be saved?

I'm planning out adding Facebook integration to a web app I'm working on. For the most part, it's proceeding smoothly, but I am confused on the proper way to handle the OAuth token.
The sequence of events presented by Facebook here is:
Ask the user to authorize your application, which sends them to a Facebook window.
This will return an Authorization Code generated by Facebook
You then hit https://graph.facebook.com/oauth/access_token with your Authorization Code, which will give you a time-limited OAuth token.
Using the OAuth token, you can make requests to access the user's Facebook profile.
Facebook's documentation has the following to say about token expiration:
In addition to the access token (the access_token parameter), the response contains the number of seconds until the token expires (the expires parameter). Once the token expires, you will need to re-run the steps above to generate a new code and access_token, although if the user has already authorized your app, they will not be prompted to do so again. If your app needs an access token with an infinite expiry time (perhaps to take actions on the user's behalf after they are not using your app), you can request the offline_access permission.
When they say to re-run the steps above, what steps need to be re-run to get a new OAuth token? What data (Facebook UID, Authorization Code, OAuth token) does it make sense to save to my local database?
I would like to be able to have the user continue to interact with my site, and in response to certain user actions, I would like to be able to prompt to user if they want to post something to their Facebook wall.
The access token is time and session based and is unnecessary data to store and have no use after the user have closed the session.
The facebook uid is the only thing you need to identify the user.
Since the Facebook API sometimes is horrible slow you could store the username aswell.
But for identification, all you need is the uid.
The documentation that facebook provides has been updated since you asked this question. https://developers.facebook.com/docs/authentication/.

What to do with twitter oauth token once retrieved?

I'm writing a web app that will use twitter as its primary log on method. I've written code which gets the oauth token back from Twitter. My plan is now to
Find the entry in my Users table for the twitter username retrieved using the token, or create the entry if necessary
Update the Users.TwitterOAuthToken column with the new OAuth token
Create a permanent cookie with a random guid on the site and insert a record into my UserCookies table matching Cookie to User
when a request comes in I will look for the browser cookie id in the UserCookies table, then use that to figure out the user, and make twitter requests on their behalf
Write the oauth token into some pages as a js variable so that javascript can make requests on behalf of the user
If the user clears his/her cookies the user will have to log in again to twitter
Is this the correct process? Have I created any massive security holes?
Sounds good.
However, I suggest not using the Twitter User Name as the primary index for the User table. As Twitter user names can be changed. I learned this the hard way.
You should be fine using the Twitter User ID (big int) as the primary index as it doesn't change if the user changes their user name.
As for the token its self, you are a-okay with storing it for future use. In fact, you are encouraged to do so.
Could you not just save the oauth_token as cookies instead of the GUID and do the user based lookup on the oauth_token or is that bad practice?