should I hash username in OTP based two factor authentication database? - database

I currently dealing with a ssh two factor authentication plugin.
It can be used like this:
$ ssh localhost
password: [ssh password]
Name: [your name]
OTPCode: [your code]
there is a list of username and OTP Secret in sqlite db.
if the sqlite db leaks, it is dangerous. should I hash the username and add a nick name to distinguish a which one is which. will this design cause any problem or is it neccesary?

To be honest, if someone gets hold of the database in the clear with the secrets in it, they aren't going to be too bothered about hashed/obfuscated usernames. They already have the secret information.
An attacker could realistic generate all the OTPs against all the secrets from the database in a fraction of a second and then try them all for any given username. Moreover if they have sniffed the username in the past and know when they authenticated (For TOTP), they can create all the OTPs for all the secrets in the database for that window and then see which secret corresponds to that user.
Basically if you loose your token's shared secret, loosing the corresponding username is going to be the least of your worries.
Focus on locking down the database or even better getting the authentication mechanism off of the machine.

Related

How to set up a temporally password accessed ressouce?

Context
Developing a platform with contents and some files. Users can create a resource, and set it:
private: only accessible for him
protected: accessible via a password that can expire
public: no security rules to access
Problem
Considering we have that 2 tables:
We want to protect our element table if visibility = 'protected'. So creator should give a password for resource access, and set an expiration date.
Users can set many passwords with a different expiration date.
How can we store that password, with security, and thinking about the user can share a password, close password access, and get his password access to share resources when he needs them.
We talk here about a conception of the solution, don't care about languages or orm.
Potential solution
Cron job
Create a table joining passwords with entities, and when the user sets a password, launch a cron job that will set an attribute like active to false when the expiration date is reached.
Problem: making our app stateful, if cloud-based and the pod crash, cron job fell in void...
Store it in base64
To allow users to get back already set passwords, we have to get symmetric encryption algorithm to encrypt and decrypt the password, but that exposes resources if the database is compromised..
Also creating a table joining passwords with entities here.
No more ideas for the moment... How would you do ?
The best solution should be stateless and don't store passwords in clear.
I can think of other two solutions
A PubSub mechanism, which you can choose to trigger when to execute. For example, when you create a password today and want it to expire tomorrow. you can create a pubsub task that will trigger in a day. The task will remove that password.
A JWT token, which is a token that encoded the information in there, which includes the expiration date. When you verify that token, you will verify the signature to make sure it is not tampered and also if it is still valid. If you need to store secret inside it, you can use RS256.

What could be a decent workflow to a user registration application to store password?

I am developing an application (web\mobile). The user have to register the account using a form on the application (it contains some data as username and password).
These data have to be stored in a database table, these data travel on Internet so I think that it is not a good idea that the password is in clear.
I think that the client have to encrypt the password in some ways and that this crypted password have to be stored in the DB.
What could be a decent workflow for this task?
A common way to do this is to send the password as clear text via a HTTPS connection. HTTPS is a must when anything confidential is sent through internet, not only for passwords.
On the server, calculate a hash. There are many algorithms for this, some more secure than others. A hash function works only for one direction: the password cannot be derived from the hash. Store that hash to the database instead of the password. When a User logs in, calculate a hash from that password, and compare it to the hash stored to the database.

Storing private email addresses in my database

My problem is not that I can't save emails to a database. Anybody can do that. Here is my question:
When a user makes an account on my website, they get an ID, User, Password, and Email address data. For the password I hash it so that if somebody hacks my website they wont see the real passwords. However, isn't having a bunch of email addresses saved, unprotected (like the users) a security risk?
I have never made a login system website before, and want to know if everybody else just leaves the email address unprotected in the database. (In other words, is it common just to save an email address to database as-is?).
Thanks.
Usernames and email address do not have the same sensitivity as passwords.
Passwords should be secured (hopefully with bcrypt) because if Alice has used the same password on Bob's Things as she has on Gmail then any attacker gaining access to the database on Bob's Things will then not be able to gain access to Alice's email account (nor those of the the other 10,000 users that regularly buy Bob's things and reuse passwords).
The email address cannot usually be hashed like passwords. If your system needs to send the user an email, it cannot do this if the email is stored in hashed form.
Plus there is less stuff an attacker can do with just the email address. Yes they could send phishing emails to your users, or they could try and password guess to gain access to accounts, however the complexity of securing the email address regarding its server-side storage is often not worth the effort.
You would be better off ensuring the interface to this database (i.e. your application and supporting infrastructure) is properly secured rather than trying to encrypt the email addresses within the database. Even if they were encrypted, key management then becomes the problem. Bottom line, the best you can do is secure your application against user enumeration if you want to protect people's email addresses from being easily discovered.
Generally:
1 - never save user's credit card number anywhere in your database, however you can save part of it if you really want to.
2 - always salt and hash user's passowrd
3 - no need to encrypt a user's email, if you really concern, encrypt it, not hash it

Is it safe store a username inside a cookie?

I working on security and I 'm storing a session key inside a cookie. I will use it to check if the user is actually connected and if he didn't tried to change some info.
at first I think to just check if the session key is inside the database, but I think it would be more secured to check if the current user has the session key instead of just finding a user that have that key and assume that he must be the one connected.
I know I should use session storage, but since I'm using AngularJS, I don't know how to achieve that, so no need to point out that I should use session instead.
-Would it be safe to put the username inside the cookie?
-Would just using the session key and assume that the user that got the key most be the connected one be a good idea (it would simplify some of my request to the database later on)?
It sounds like essentially what you are trying to achieve by storing the username in a cookie is to make the username a 2nd factor in a 2-factor authentication scheme. The problem is, the username always travels in a cookie alongside the session id and so when one is exposed, the other is too. So no security is gained.
Furthermore, there is no valid security argument to storing username in a client cookie and then trusting that this username is the same one associated with a session. The client can trivially change the value of the cookie before submitting a request. And any attacker that has already managed to have sniffed out the session id from a cookie could probably just have easily read the username cookie too, making a session hijack attack practically the same difficulty. At best, you've achieved no higher security and added unnecessary complexity to your code. At worst, you've betrayed usernames which wouldn't have otherwise have been visible to an attacker. eg. in the case of expired sessions.
OWASP Recommendation:
Session ID Content (or Value)
The session ID content (or value) must be meaningless to prevent information disclosure attacks, where an attacker is able to decode the contents of the ID and extract details of the user, the session, or the inner workings of the web application.
The session ID must simply be an identifier on the client side, and its value must never include sensitive information (or PII). The meaning and business or application logic associated to the session ID must be stored on the server side, and specifically, in session objects or in a session management database or repository. The stored information can include the client IP address, User-Agent, e-mail, username, user ID, role, privilege level, access rights, language preferences, account ID, current state, last login, session timeouts, and other internal session details. If the session objects and properties contain sensitive information, such as credit card numbers, it is required to duly encrypt and protect the session management repository.
It is recommended to create cryptographically strong session IDs through the usage of cryptographic hash functions such as SHA1 (160 bits).
-- https://www.owasp.org/index.php/Session_Management_Cheat_Sheet#Session_ID_Content_.28or_Value.29

Securly Storing OpenID identifiers and OAuth tokens

I am creating a web app that will use OpenID logins and OAuth tokens with Youtube. I am currently storing the OpenID identity and OAuth token/token secret in plain text in the database.
Is it inappropriate to store these values as plain text? I could use a one-way encryption for the OpenID identifier but I don't know if that is necessary. For the OAuth tokens, I would need to use a two-way encryption as my app relies on getting the session token for some uses.
Is it necessary to encrypt the OpenID identity? Could someone use it to gain access to a user's account?
First, there is a registered application that has consumer_key and consumer_secret.
When users authenticate and "allow" your registered application, you get back:
an access_token that is considered the user's "password" and would allow JUST YOUR application to act on the user's behalf.
So, getting just the user's access_token from your database won't help much if they don't also have the consumer_key and consumer_secret for complete access.
The service provider compares all 4 parameters on request. It would be smart to encrypt these 4 parameters before storage and decrypt them before response.
This is just when you need to update or make changes to the user's resource owner on behalf of a user. To keep a user logged-in on your site, use sessions.
The OAuth Token and Secret should both obviously be kept safe in your database, but you can't store them using 1 way encryption the same way you would for a password. The reason being is that you need the token and secret to be able to sign the request.
This would also be the case if you are running an OAuth server, you still need the original token/secret to verify the request.
If you want to you could still encrypt them using a 2 way encryption algorithm such as AES to offer security in case your database or database backups get compromised.
There's two schools of thought here.
The first argument is that: you should treat OAuth tokens like passwords. If anyone were to access your database, obtain all the OpenID/OAuth pairs and run an man-in-the-middle attack, they could impersonate any user on your site.
The second argument is this: by the time someone has access to your database and sufficient access to your network to run an man-in-the-middle attack, you're hosed anyway.
I'd personally err on the side of caution and just encrypt them; it's a standard practice for passwords, so you might as well give yourself just that little extra peace of mind.
Meanwhile, Google has this advice:
"Tokens should be treated as securely as any other sensitive information stored on the server."
source: http://code.google.com/apis/accounts/docs/OAuth.html
And some random guy on the web has specific implementation advice:
If they’re on a regular disk file, protect them using filesystem
permissions, make sure that they’re
encrypted, and hide the password well
If they’re in a database, encrypt the fields, store the key
well, and protect access to the
database itself carefully. *
If they’re in LDAP, do the same.
archived post (original post URL, now a dead link)
OpenID URL shouldn't be encrypted because this is your "open id" literally, everyone should know the value. Besides, the URL needs to be an index in the database and it's always problematic to encrypt the index in the database.
OAuth token/secret should be secret and encryption may improve security if you have to store the token long term. In our OAuth consumer application, token/secret is only stored in session for a short while and we choose not to encrypt them. I think that's secure enough. If someone can peek into our session storage, they probably have our encryption key also.
Yes, these should be symmetrically encrypted (say, AES-256 in CBC mode) at rest in a database. A simple way to encrypt these tokens is using SecureDB's Encryption as a Service RESTful APIs.
Disclosure: I work at SecureDB.

Resources