github3.py authorisation lost tokens / multiple machines - github-api

I am probably doing something stupid, but...
When attempting to retrieve a token with code like this:
auth = github3.authorize(user, password, scopes, note, two_factor_callback = two_factor_callback)
I'm finding that the API creates a token, which I then store locally, and all is hunky dory.
If however I lose the locally stored token, or move to another machine where the token is not stored locally, I get a failure back from authorize.
It seems that once a token is created for a given note value, it cannot be obtained again, or overwritten with a new one.
For changes of machine, I suspect that the fingerprint parameter in the github API needs to be implemented. A temporary workaround is to salt the note value with something unique to the machine you're on, such as the MAC address, but that's a bit ugly.
For the situation where the token exists, but the local copy of it has been lost (by the user deleting it from the keychain where I've stored it, for example), the only solution seems to be to log on to the github website and manually remove the token!
That's a bit counter-intuitive to me! What am I missing here?
I can see that perhaps github's servers don't store the entire token, so can't return it again - but in that case I'd expect a clean way to be able to regenerate it. Maybe there is one, and I'm missing it?

For the situation where the token exists, but the local copy of it has been lost (by the user deleting it from the keychain where I've stored it, for example), the only solution seems to be to log on to the github website and manually remove the token!
You should be able to access the list of authorizations with the user's username & password. If you can find the existing one, you should be able to delete it.
I can see that perhaps github's servers don't store the entire token, so can't return it again
I suspect they do store it. They just refuse to return it.
but in that case I'd expect a clean way to be able to regenerate it. Maybe there is one, and I'm missing it?
As far as I know, there is no way to regenerate an Authorization Token. GitHub doesn't make the generation algorithm public and there's no way to retrieve a token after it's first generated.

Related

Is JWT safe if someone knows the secret? If not, how can you make JWT secure?

I recently read a lot of articles talking about how JWT can be used for authentication to improve performance by not saving any session related data. Based on my understanding, it signs the data (usually user_id) with a secret to generate a JWT token. Then each client request sends the token. The server just check whether the signature can be verified and trust what's stored in the payload of the JWT.
My concern is that if someone knows your secret, he can easily create a JWT token himself and pretend to be any user in the system. One simple case is that anyone who can see the source code can easily do that. (eg: internal members)
How do you prevent it from happening? One thing I can think of is to use a randomly generated secret at each sever restart. (this may still not be secure if you sever runs a long time without changing the secret)
Many people seem to have issues with regards to the security of a JWT for this reason, and the inability to white-list/black-list people without losing the benefits from using a JWT. In regards to generating a new secret on each server restart, keep in mind that each time you change the secret, you essentially 'logout' every user who currently is logged in, or for whatever other purpose you are using it for. I think common practice is to just make sure the secret remains just that, a secret. A long, randomly generated string that is kept in a file that extremely few people have access is the best way to prevent a current secret from escaping, as far as I know.
Another thing to keep in mind is that the data is in no way hidden from anyone within the JWT. Anyone can see what you have stored so don't store any sensitive data in there. You probably already knew that from your reading, but it is an extremely easy and fatal mistake to accidentally leave sensitive data in the body of the JWT.

Protect remote resources when served with nodejs

This is more of an architecture question involving nodejs as implementation.
I have on a folder not exposed by the webserver files that I want to offer to the user.
The way nodejs should expose the resource to the end user is via a one shot link, that once is consumed is no longer available.
The user through the entire experience should never know the real location of the file.
I'm sure this is a common architecture pattern, but I have never implemented something similar.
Looking at scalability, the resource shouldn't be copy either on HD or RAM, and if possible the solution should not relay on a DB token tracking system.
I don't necessary need a code implementation, but a detail explanation on how I should implement it
Thank you so much
Give user a cookie
Create a temporary association (in db) between cookie and a generated ID for the user (or the hash of it, if you want to be fancy)
Give user the ID
When user requests resource by ID:
Test to see if the ID (or its hash, if you want to be fancy) is in the DB
If it is, give the user the resource and destroy the association between the user and the resource ID
There's a db token tracking system. Hey, that's the only way.
One way to avoid depending on a DB, would be to maybe create a symbolic link in the filesystem (based on the token), that would be removed after a request for it. Would not work satisfactory on windows though.
Example (psuedo):
Create token (guid, or similar)
symlink guid -> actual file
once request is completed, remove symlink
However, I don't think there is a reliable way of knowing if the file was successfully downloaded, so you better prepare for that. Some sort of pingback when the file was completely downloaded is probably the most reliable way that I can think of right now.
For scalability, make sure that the symlink is on a shared file system. Clustered node.js instances on the same server, will be fine though.
If this needs to be restricted to an authenticated user, you could combine the guid with your auth token, and prepend/append it before looking for a file.

Chrome local storage and security

I'm using a local storage value to check whether a user is logged into my Chrome extension.
Can users edit their own local storage values? If I were to use their user ID in my database, I wouldn't want them to be able to log in as something else just by editing that ID, e.g. incrementing by 1.
Should it be something that the user shouldn't be able to see? I also considered using their salt, but I might not want to reveal that to the user.
You are right to be concerned. Generally, client-side code and data can't be trusted because it's in the hands of the attacker. The question is identical to the problem faced with web cookies: a browser can report anything at all as cookie data, so the server can't trust it. You have two general options to get around this problem. One is an HMAC, and the other is public-key signatures. Both require a server, but only the latter can verify without a server.
An HMAC requires that the secret remain inaccessible to the attacker at all times, but it's required for both generation and authentication (that is, that it stay on the server and be verified on the server). You haven't given us enough information to tell whether your extension is appropriate for this use case. Most industrial-strength cookies these days use some variant of an HMAC.
Public-key signatures require that the signing be done in secret (that is, on the server), but after that point the client can verify it without talking to the server.
The big problem that you'll face with any of these schemes is that two people can collude to copy one person's credentials to another machine, or one person can steal another person's credentials. Again, with client-side code you can't really trust anything. But either of these schemes prove that an attacker didn't make up login credentials entirely on his or her own.
Think of this problem as a web cookie problem. However you solve that problem, you can also apply it to chrome.storage.

How to remember users with cookies in a secure way?

So lets say i have a member base website and when the user signs in i put put a cookie (or a session) with a key value pair remembering who the user is. But its just come to my attention which information i should use to remember the user so that its secure. I cant use username=username or user_id = user_id (because my user_id will be 1), because people then can just simply guess what the cookie values are and logged in as that user. So what key/value pair should i use to be able to identify users and still connect their information to the database securely? Thanks.
Ben, there are a few different types of attacks you need to be concerned with. For example simply encrypting the identifier with a private key doesn't prevent someone who can intercept the encrypted value from simply replaying it to your server (and appear to be the user). Some common security risks are detailed here (and in associated links at bottom of this page):
https://www.owasp.org/index.php/Session_hijacking_attack
Session management can be quite complex and depending on the level of security you require, it is not something you want to tackle yourself, because likely your development environment / framework already has a solution that has been vetted moreso than a homebrew solution. Here is a link detailing some things to consider, unfortunately this topic has more to it than a simple Stack Overflow post:
https://www.owasp.org/index.php/Session_Management
If you dont prefer encryption for whatever reason, then a simpler solution could be to use a GUID to identify the user. This way, a hacker would have to launch a denial of service kind-of attack on your application to be able to run through even a very small fraction of the GUIDs.
If you want to do this properly, then you should have a look at http://jaspan.com/improved_persistent_login_cookie_best_practice also.
I'm definitely not an expert in security, but I have recently implemented user management tool and I have done the following.
Don't use encryption, its slow and most of the time for simple implementation its just a waste of time.
Here is what you do need to store on the server - in order to authenticate each request.
UserId (obvious)
CookieHash (made out of userId, some secret private key and crypto randomly generated number)
LastLogin
SessionRenewed (useful for when to cancel someone's session eg. renew cookieHash every 10 min, otherwise log out user)
LastIP
What I store in cookie is following
UserId
CookieHash
How to use this basic security
Simply when user logs in you check username/password etc. (just the usual) If everything is fine then log in user and generate new cookiehash and fill those values given above.
Every request check UserId against its hash. If someone gave UserId = 4 but hash didnt match then automatically drop a session and forward user to login screen. Possible log is good to see how often people try to play around with your hard work.
I hope this helps.
You can just encrypt the user id with a private encryption key that you keep on the server. There are a few things to watch out for with this approach:
Every call to the server will require you to decrypt the cookie to get the id of the user. This will add overhead to each request.
If the key is ever compromised, you will be forced to abandon the current name for the cookie you use and use another encryption key when assigning to the new cookie name; this will cause the user to have to re-login, of course.
While I don't think that these are major hurdles, they might be to you, and you would have to evaluate the impact on your site for yourself.

S3 + DevPay for a user application, do I hardcode my ProductToken?

subject says all, the REST api docs seem to make me think I do (and if I dont my code doesnt work)
Do:
-hard code ProductToken
-ask user for authorization key
DoNot:
-hard code (or use) access key ID
-hard code (or use) secret access key
keep in mind this is for an application that uses devpay, not a website
thanks!
Either hardcode it or store it in an encrypted DB or XML file, as for Secret Key and Key ID, it is better to not hard code your own keys maybe as mentioned above store them in an encrypted file somewhere in your app and once you get the user Keys successfully delete the file that has your own keys or replace your keys with the new user credentials as you wont be needing your keys once the customer has successfully activated your product.
sure its always better to hide the ProductToken from the user rather than asking the user to input it manually because once your Product token goes public people can easily access your buckets and do whatever changes they like and you'll probably lose control of your data flow.

Resources