Basic authentication vs GET parameters - security

I would like to create a secret page protected by a password.
To access the secret page, the user shouldn't have to manually input anything. Instead, there should be a secret link that contains the password which would lead directly to the secret page. We assume that this secret link is shared exclusively among trusted parties.
I thought of two options:
https://user:secretpassword#www.example.com/secret
https://www.example.com/secret?user=user&password=secretpassword
Requests being made exclusively over HTTPs, is one more secure than the other?

They are really both equally insecure, even if communicated over https.
The problem is that you can't keep your users from being able to see the username and password in the link. And if users can see it, there's really no way to keep it safe.
Also, depending on the web server configuration, these usernames and passwords could end up in server logs etc.
The only way to make sure the HTTP request is coming from your web application, is to authenticate the users and protect the page with appropriate access controls.

Related

Why is express-session connect.sid value is visible on client?

I was playing around with express-session and reading their documentation and it seems like on the client side, the cookie with the name connect.sid stores the session ID. My understanding of security is limited but isn't this a vulnerability if the session ID is so easily accessible?
Cookies are private to the target client. This is no different for socket.io or for a google login. If the server wants to protect them, then you run the connection over https and it's end-to-end encrypted and the only one who has access to those cookies is the client itself. This is how browsers do login and identification of a previously authenticated client.
Also a socket.io sessionID does not need to be a secret. It doesn't authorize anything. It just identifies a client as the same client as previous. If the application wants that client to be authenticated and secure, then that needs to happen some different way. There is no authentication whatsoever associated with a socket.io cookie.
If you're using an express-session and you want it to be secure, then you need to use end-to-end https. That protects the session cookie in transit. Yes, if your client is compromised and someone steals the session cookie and uses it before it expires, they can possibly hijack the session. But, that's why you use https so there is no way to grab the session cookie from somewhere in the middle of the transport. So, what needs to be secure is the client itself. And, that's the same requirement as every single web site that uses authentication. This is the architecture of the web, nothing new for socket.io or express-session.
So what would happen if somehow your computer is hacked and the hacker obtains access to the client's browser, and hence the cookies & session ID as well? Then they wouldn't be hijacking the session while it's in transporting
First off, you can expire your cookies quickly (like within 5 minutes of inactivity). You will see banking websites do this.
Then, you have much bigger problems if the computer itself has been compromised. The attacker can implant keyloggers or other spyware and can steal your actual login credentials, not only for your website, but also for email and other things like that.
There are higher levels of security than just a username and password for login. For example, you can require a physical piece of hardware that either plugs into your USB port or requires you to enter a code (that is constantly changing) from the device. I've worked for companies that required such a device in order to login to the company network from outside the corporate LAN. This is one form of what is referred to as "two-factor" authentication.
If you look at websites like banks, they will typically do some sort of detection of the login computer and if it looks like an unfamiliar computer (missing other cookies, different IP address, different user agent, different screen resolution, etc...) then they require additional login steps such as sending a code to your phone that you have to enter before you can get logged in. Or, they require you to answer additional personal questions before letting you in. They may also notify the account holder that a new computer was used for login. If that wasn't you, go change/resecure your account credentials.
Would you suggest setting up a re-route of my entire website from HTTP to HTTPS to solve this?
Yes. Any site interested in security should require access over https.
There is a lot written about this topic on the web. You can start by reading articles here: https://www.google.com/search?q=best+practices+for+securing+login

Node Server, is a database necessary for basic authentication if using oauth?

I'm learning Node, doing authentication stuff at the moment with passport.
Say my server has 2 pages, a public home page with various login options, then a super-secret page(and perhaps more) that is only accessible after authenticating.
If I'm only going to be using 3rd party strategies, is there any reason to have a database?
I know that you'd obviously need one for local user's id and pass, but if the server exclusively relies on 3rd party authentication, would session persistence be enough things to work? Or are there still various things that you would need to save for some reason (apart from logging) ?
Could you do without a database, sure... but in this case what is the point in authenticating at all? All you would be proving is that the user has a Google account which anyone can set up for free in a matter of minutes.
If your content is super secret then chances are you want to have a database of users (email addresses and the like) that have permission to see the content. By authenticating through OAuth you will be given an access token that will allow you to fetch the authenticated users email address. This can then be looked up against your user table to see if the user is registered and if your app enforces it, check whether the user has access to the page requested.
OAuth is proving that this person is the owner of the Google/Facebook/Twitter/Github Account. You can use this knowledge to sign someone in against a database of "local accounts" based on email used at sign up, assuming you validate the email on sign up locally.

How to secure my REST-API?

I have an api build with node.js & express.js. For now I have a unsecured api where anyone can GET,POST,PUT,DELETE records.
I am facing following problem. My rest api should not authenticate users but applications. E.g. my mobile application should have a valid token to access the api. Same for web application.
Another user case: my api will be used by another application that only uses one single rest call. So somewhere in the code I don't know in an application I don't know (for most part) a rest call on my api will be triggered. How can I secure such access, since no cookies or sessions are involved?
My first thought was, create a user and a password. Each api call (via https) must contain the credentials. Password may be hashed. However I read this
Usernames and passwords, session tokens and API keys should not appear
in the URL, as this can be captured in web server logs and makes them
intrinsically valuable.
from https://www.owasp.org/index.php/REST_Security_Cheat_Sheet
Any suggestions on this? I read about oauth but this involves redirections and I cannot imagine how this would work with a mobile app e.g. on android.
You can use RSA encryption for this, have a look at ursa module for node.
A simplified process of using this is... Arrange you client applications to encrypt a secret password with a public key and on the server side decrypt it with a private one, check if the secret is what you expect and act accordingly...
There are plenty of articles about using rsa in applications, I am sure you will be able to pick up a more definite explanation of how to work it if you just google.
EDIT
I have just bumped into this post which has a more detailed write-up on this question.
There is a question of how applications get to know a username/password in the first place, but if you are OK with the general idea (which is safe, as long as you consider the environment in which the application runs to be safe), then you don't need to worry about username/passwords in URLs: simply use https instead of https.
https is encrypted so that only the 2 endpoints (the client and your API) can read even the URL. Any router/proxy/server in between sees only encrypted data and has no means of accessing your username/passwords.
Instead of a username/password, btw, just use an "Access Token", which is a long (read: hard to guess) string, and assign one access token per application. In your end, you keep the list of valid tokens in a DB, and authenticate against that. You can even attach expiry dates to those strings, if you wish so.
Adding access token as part of an https:// url is common practice.

Plain English explanation for usage of OAuth in conjunction to an internal user management

I'm new to OAuth, and although I have scanned through many documents, I don't seem to have yet a good architecture / design to a secure web application, answering most/all of OWASP Top Ten
My newbie questions are
Why can't I just rely purely on OAuth? why do a user needs credential in my own application?
If I do, do I need hash / salt anything if I save it? I don't store any passwords, but what about tokens?
I still need to persist the users so they won't login everytime, (like in OS) - do I
Somehow use the OAuth token (save it? does it make even sense)?
Or use the plain old httpOnly secure cookie (if so, what happens if they log out of the Oauth provider? shouldn't I in this case ignore my cookie and let them log out?
How do I implement logging out? I can't force them to log out of the OAuth provider, and if I only delete the httpOnly cookie / invalidate their session locally, is that enough? and security issues?
How do I implement single sign on? I don't want the user, after approving to click again "log in using Facebook / Twitter / Google" I want an effect similiar to SO (page refreshes and "welcomes you back" what are the best practices to do that? Why does SO refreshes the page (I assume it has to do with the fact it needs to be client side, but I don't fully understand how it works to even know what to ask)
I guess I have a lot to learn, but reading on so many potential security issues, and having to master so many different topics seems like a good potential for me missing something that someone later will exploit.
Is using a framework such as Spring Security, or using Lift's built in user management going to save me all this headache? or do I have to know exactly what I am doing to avoid things like Session Fixation, Cross Site Request Forgery, Cross site scripting, Rainbow tables and other things I only remotely get...
Why can't I just rely purely on OAuth?
From a service providers perspective, OAuth is a means of controlling access of third party applications to the business logic. The end user does not have to give out his password to the third party app, and the access can be controlled. For example, the provider could restrict the access to only parts of the service for limited amount of time.
If you write a third party application, there is no strict need for you to have your "own" user artifacts. You can rely on the users that authenticate your application.
You could require that user's have an account with a provider such as Facebook or Twitter and not implement any password stuff yourself.
(You probably need some sort of artifact to represent a user, it should in this case contain information about how that user authenticates your application, for instance an OAuth token, or an OpenID URL).
If I do, do I need hash / salt anything if I save it? I don't store
any passwords, but what about tokens?
Just to clarify, in OAuth a token is typically both a key and a secret, and they are needed in cleartext to sign requests (there are differences here depending on which version of OAuth you use). So you can store them encrypted, as long as it is reversible for you.
I still need to persist the users so they won't login everytime, (like in OS) - do I
somehow use the OAuth token (save it? does it make even sense)?
Yes this makes sense, a token represents your applications access to a specific user's data. Save the token if you want to keep a "session" alive.
How do I implement logging out? I can't force them to log out of the OAuth provider, and if I only delete the httpOnly cookie / invalidate their session locally, is that enough? and security issues?
There is no concept of "logging" out of OAUth, a token either has an expiration time or not. You can of course "log out" by simply choosing to forget the token. The next time you will have to redo the authentication. You cannot force users to invalidate an access token, unless the provider has an API for that.
You could save the token in a cookie, but I would use other unique identifiers for the session you want to keep alive. You can persist the details of the tokens server side. The information you store in your cookie shold make it possible to retrieve the token you need.
How do I implement single sign on? I don't want the user, after approving to click again "log in using Facebook / Twitter / Google" I want an effect similiar to SO (page refreshes and "welcomes you back" what are the best practices to do that? Why does SO refreshes the page (I assume it has to do with the fact it needs to be client side, but I don't fully understand how it works to even know what to ask)
If you save a token in a database, save an ID for that token in a nice secure cookie. When a user goes to your service, use the information in the cookie to make a call from your service, to the service provider, to check if the token is still valid. If so, you have established enough trust for you to "log in" the user in your application without having to go through the pain of the OAuth process again.
And as a side not, StackOverflow uses OpenID and not OAuth for user authentication. OAuth can be used for the same purpose but is mainly a specification for application authorization.
I hope this helped, and don't sell yourself short. This site is for posting questions, not for appearing all-knowing.

Secure Way of storing Passwords to APIs without OpenID?

I asked a similar question here a while back but all the answers were offering OpenID which is nice but it doesn't work with services that require authentication that don't use it (such as EventBrite).
Say I want to create an app that lists your events from event brite, and their analytics (which eventbrite includes). Any person can sign up for this service to list their events. But since EventBrite doesn't have OpenID to authenticate, I need to somehow get the user login and password to EventBrite.
Some possible solutions are:
Store credentials in YAML like this. Easily hackable.
Have user enter in credentials into a form on my site, I save the credentials to my database, and use them to login to EventBrite. Easily hackable.
Have user enter in credentials and I pass them directly to EventBrite without saving, and I save the response header Cookies to the database, and when they expire, have them login again. Is this easily hackable?
This hypothetical service also wants to automatically check events (say via cron), so it doesn't depend on the user going to my site via the browser. So cookies or credientials need to be stored somewhere.
The thing is, after asking this similar question about confidentiality and security it sounds like you should never build an application that does what I'm describing. There's got to be some way building something like this is okay.
What is that way? What am I missing? Is it okay to go with #3 and save the cookies (but still needing the user to submit their email/password via a form which I send to Eventbrite)? What is an acceptable solution to the problem?
There isn't a secure way to do this. You can employ workarounds, but that's about it.
Storing passwords in YAML or XML in cleartext is definitely out
In fact, even encrypting and storing passwords is wrong. Your application would need a way to decrypt the passwords, so the attacker can also decrypt the passwords.
The recommended way to store passwords is Salt + Hash, but because it becomes unrecoverable, it is useless in your case.
Because of 2 & 3, no matter where you store the users credentials, you are vulnerable.
Storing the cookies instead of the passwords is a better idea. But again, this involves the password going through your website, which isn't good.
Given your situation, storing the cookie is a better approach. Use HTTPS throughout, even on your website. Its less than ideal though, and you and your users should be aware of it.
Eventbrite has recently release new documentation describing how to implement OAuth2.0 for cross-site user authentication.
I would recommend using our javascipt-based OAuth2.0 widget, which stores the user's authentication tokens in their browser's localStorage by default.
Since the auth tokens are stored in the user's browser, and are prevented from being accessed by other domains, it's not likely that there would be any security leaks.
The need for email and password combos are completely avoided in this authentication scheme.
Most sites only support direct login with the original cleartext password, so you have to get, store and provide that too. And I would never ever trust you with that.
The problem with your concept is that you require the password to be given to a third party. The solution is not to involve a third party, for example my browser is pretty good at storing and filling in passwords for me automatically (my hard-drive is password protected too). And they are dozens of other password wallet apps too. I wouldn't gain anything by subscribing, using your service.
Before going into such a business, consider you are going to be the #1 target. Facebook, Google are incredibly paranoid about security, spending a lot of time, money and effort to keep the logins safe. Do you have the same resources? Then you are a better target. Also by hacking your service, they immediately get multiple accounts, passwords of your users, also seeing who is always reusing its password.
For working with the Eventbrite API, I'd recommend ensuring that all connections are over SSL, and that you authenticate using a user_key rather than a username and password.
More information about authentication for the Eventbrite API is here: http://developer.eventbrite.com/doc/auth/
After logging in, users can find their user_key here: http://www.eventbrite.com/userkeyapi
This should prevent username and password information from being intercepted over the wire, or read from a local data store.

Resources