How to implement Querystring authentication - authentication

I’m developing a website of a client and they are sending out newsletters to their customers (through the website administration interface)
The newsletters are personal to each of the subscribed recipients/customers.
Each recipient/ customer is also a user with a username/password that enables them to sign in on the website and manage their newsletter subscriptions and participate in the sites community.
This all works like a charm.
Now my client want a “Manage my subscriptions” link in the newsletter email that when pressed automatically signs the recipient/customer in on the website with no need to remember username and password.
This could be easily solved be making a link like this:
http://mysite.com/manage.aspx?user=peter&password=hounddog
Of course information should not be clear text but encrypted in some way.
This however poses a problem since the only way a user can be authenticated on the website if by providing a valid username and password.
In the name of security, passwords are stored as hashed values in the database making it impossible for me to insert the password in the link.
What is the best way to accomplish this without compromising the security?

You will have to compromise your security somewhat, if you want people to be able to login without entering password. Note that even if you had access to the password (as in your example), you would have to embed it in a mail massage which would be transmitted in plaintext.
You can create a Guid associated with each user and message, and append it to the URL, and allow that to login automatically.
You could perhaps isolate the permissions so that a login through a newsletter guid link only allows the user to manage subscriptions, but that a real password-login is still required to participate in the forum. In that case its pretty limited what havoc can be wrecked if someone gets access to a Guid from a mail message.

Could you not insert an encrypted user name bundled with the hash value of the password?
What I mean is, encrypt & encode the user name to always be a particular length or to have a known break character in it then append the passwords hash value. this way, you could break apart the query string easily while still having the user name and password securely encoded. A straight compare of the hash values would be enough, with the unencrypted, decoded user name to allow access.

What about using an encrypted cookie that contains an access token ?
This cookie would be delivered after a successfull authentication by a separate page.
This kind of token can also be part of the URL query string.
Also you might consider using secured https instead of http.

Related

Access token vs username/password for api request

I know this might seem like a trivial question but I can't find the answer for it to at least put my mind at peace.
If a mobile app is communication with a server then typically they sign in and they get an access token that they can use for the remainder of the session with any future request.
WHY not just pass the user name and password over HTTPS with every request instead of the access token. An access token will need to be verified with database and so is the combination of username/password. Why go through the added effort of access token if they do the same thing? I know I am missing something but I can't figure it out
You are right in that an access token is verified pretty much the same way as a username and password. For the period when the access token is valid, it is pretty much equivalent to the username and password. In some cases (depending on your threat model) it may even be ok to send username and password with every request, maybe not from a mobile app, but for example in server to server requests, with appropriate controls.
However, you don't want to send the password in every request from a mobile app primarily because then you would have to store it.
The problem with a password (or with users, actually) is that they are reused. A password is a valuable target, because the same password is likely to be used on multiple services. So you exchange it for a shorter-lived access token, which, if stolen, presents less risk for your user. And you can't easily revoke a password - forcing users to change their passwords is a hassle. Revoking an acces stoken is easy.
Also it's very unlikely, but sometimes there are vulnerabilities in TLS - not very often, but there have been a few in the past years. Such a vulnerability might allow an attacker to decrypt some of the traffic sent over https, or for example there was a vulnerability in openssl a while ago that allowed attackers to extract parts of the server memory, potentially holding whatever the user(s) sent. It's much better if it's just an access token, and not the actual password.
Another point is sometimes (in OAuth flows) your app won't be allowed to even access the actual password. When your user logs in with a 3rd party identity provider (like for example facebook), they would not like your app to receive their facebook password. They just go to facebook, exchange their credentials for an access token, and you only see the token which you can verify with facebook if you want. But you never actually get the user's facebook password. Of course this is only valid when the identity provider is a third party.
I think the answer is all about the security and safety.
IT'S ALWAYS RECOMMENDED to use access tokens instead of username & password, because:
Access tokens (in most services) can be easily generated, blocked, monitored for their usage & statistics from your account, can be set as expirable, can have restricted permissions, and so on... Of course, you can delete it at all. The Username & Password is the master, who can control the access tokens.
Access tokens are safer as I said, and that is the most important thing. If you use Username & password in your web-application (or whatever) and that application is hacked (which happens so frequently), or someone views its source, or even some log-system saves the request parameters - then your user & password can be viewed by 3-rd parties and all your account can be hacked (and probably others too, where you have same user/pw). Access tokens eliminate all these risks.
About speed - I don't think that authorization with USER & PW has any significant advantage in speed.

Can/should IdentityServer4 be used to create a token for user-email verification

I have IdentityServer4 setup for API authentication although I have a use case where I want to verify that a guest (user) is essentially a valid user. A valid user in my case is anyone with a valid email address, so I want to do the following:
send the user an email with a verification token (preferably something which is a mash up of their email address, some salt and an expiry
the user can then enter this token into my app and they are "allowed" to go ahead
I was wondering if IdentityServer4 can/should be used to achieve the above?
Their tools show that you can generate a token although I am very new to this topic so was hoping for some guidance.
No, the tokens Identity Server deals with are access_tokens which are to do with claims-based authentication.
The tokens you need to use for email verification are commonly referred to as User Tokens, or one-time passwords (OTP). You can find a wealth of information on how to generate/consume these using those search terms but if you use the aspnet identity classes such as the UserManager you will find it has some in-built read to use. Or you can register your own UserTokenProvider with the UserManager.
In general you'd do something like this:
Use your UserTokenProvider to get a token (otp) for a specific user. The UserManager will use the security hash of that user and your own 'reason' (e.g. "EmailVerification") to generate the short OTP.
You could then wrap that OTP into an object that includes the email address, a userid maybe, and whatever you like. Safe Base64 encode it (there is a helper function within Identity Server that has this in fact, making sure it doesn't have the superfluous _ at the end which will mess with HTML links), put it in an email to the user
User clicks your link which takes them to your 'verify password' controller, with your mashed up token as payload. You decode it, work out which user it was for, get UserManager to verify the OTP part is still valid.
Job done.
If you want them to enter the OTP into your app directly, while logged in, then you could just skip the whole mash-up part of emailing a link, and email the short OTP directly.

IBM Worklight. Is it possible to store user credentials securely and recover them without user interacton?

There is a common requirement of storing user credentials securely (user id / user password) in the App and use them automatically next time the App starts, but I'm not being able to figure out how to do this without user interaction.
Using JSON Store I need a password to encrypt the information, so if I store user credentials in the JSON Store I will need to ask to the user for the password used to encrypt the information.
A solution I figure out is to store the user id in a JSON Store without encryption and the password in a JSON Store encrypted with the user id as password. May be this solution provide a bit more security than not to encrypt anything but I think is not a complete solution.
As explained in the comments this is a really bad idea.
Is there any solution to store user credentials securely and recover them without user interaction?
You can use the Keychain API on iOS. Android doesn't seem to have an equivalent API.
The most complete solution I figure out is to store the user id in a JSON Store without encryption and the password in a JSON Store encrypted with the user id as password. May be this solution provide a bit more security than not to encrypt anything but I think is not a complete solution.
I would strongly advise against doing that, if you store the encryption key (the user id) in plain text, then the attacker can simply use that to get to the password.
Update (Aug 27, 2014)
You should consider:
Hashing - You could hash values you want to protect. These are one-way functions, so you can't get the password back once you hash it. However, you can verify that the user provided the correct password. For example: First login you store( hash(password) ) then on next logins you compare if hash(password_provided) == stored_password_hash. If it matches, the user provided the same password. You should also use a salt.
You could give the user the ability set a pin using some library like ABPadLockScreen (you could probably find or implement something similar for Android too). You can then use the pin as the PBKDF2 input to generate an encryption key (JSONStore will do this for you when you pass the pin as the password). I would advise in favor of letting users only try a small amount of incorrect pin numbers, especially if the pin is only numeric and short, that way they can't easily guess the pin by trying various combinations. The idea here is that a pin will be easier to remember and type than their password.
FYI - There's a Stack Exchange site similar to StackOverflow but for security questions here.

Secure strategy for staying logged-in when using OpenID

I have a website that uses OpenID to sign in users. The library I'm using, returnes a user profile when the user logges in. This profile contains user's email, name, a link to the avatar and an ID which the OpenID provider has returned.
My strategy for keeping the user logged in is this:
When the user logges in for the first time, I create a hash code based on the OpenID's returned ID
I store this hash code alongside the user's ID in 2 cookies.
When the user comes to my website, I check for these cookies, and if they're available, try to match the ID and the hash code, if it's correct, I log the user in.
Now the problem is this: if somehow this cookie information gets stolen from the user, the hacker can easily log in instead of the user himself. I could create a new hash code for each time the user logges in and update the user's cookeis but it'll make the information of other browsers/computers cookies invalid.
Since the StackOverflow website does not suffer from such problem, I would like to know what should I do to both secure my login strategy and add the functionality to stay signed in for the users.
The standard way to do this is to assign a meaningless session ID and send that as a cookie; in your database, you can store the user's credential information alongside that session ID. When a user logs out, you can invalidate that session ID.
Isn't this a problem with ALL mechanisms for letting the client stay logged in? If you log into your, say, gmail, and I steal your cookies, and put them in my own browser, there is no way to distinguish my browser from your browser and I get access to your gmail. There's no way to stop the kind of attack you're suggesting, I believe (other than the user keeping their computer free of viruses etc. that could steal the cookie)

How to securely set up cookie-based authentication in classic ASP?

What would be the most secure method of using cookies to authenticate users in a classic ASP website?
I don't want to use the ASP Session object as the session cookie times out after a while, and I'd like the user to be able to keep their login to the website active between separate browser runnings.
However, I don't want to just create a cookie containing their user ID as that could be easily forged - so what are my options here? I guess some sort of encryption but I don't really know what the standard methods of doing this is.
Your options here are pretty much limited.
Get your users to log back in again; best security approach.
This obviously applies much wider than just ASP.
The best way would be to hash the password... you should be doing this in any case where you store it in database.
The hash is a cryptographic function - when you run a string through it (eg password) you get out a long code. If the input is the same, the output is always the same.
But (this is the important bit) its mathematically virtually impossible to reverse the process - to start with the hashed value and work out the password, other than brute force (someone hashes dictionary, or random strings and looks for output that matches the hash they have).
So when the user sets up account, they put in their desired password, but you hash this, and store that. Similarly in the cookie, after they login you store the hash, not the password, and this has is compared with the hash in the db.
The downside is you can't send a password reminder since you don't know the password - to you'd have to send a password reset link and have a system to do that.
If you're really paranoid you might double hash, eg when they login the password is hashed once and stored in cookie. Its then hashed again and compared with the password in db (which is also double-hashed).
Don't Do It
Maintaining a user login quote "...between separate browser runnings" is not secure. IMHO, when you close the browser a previous login should be gone. Suppose your visitor was using a community pc at a coffee shop.
If you maintain this login the potential for the next community user to open the browser, navigate to your website and "poof" they are automatically logged in as the previous user.