bibledit / old

Older code for Bibledit
10 stars 7 forks source link

User login / session management broken #94

Closed alerque closed 8 years ago

alerque commented 8 years ago

Something is badly broken about the way user sessions are being tracked. If I login to the Bibledit Cloud site for my project, then open a private/incognito tab in my browser and go to the site, it is showing me as being logged in. Logging out from inside the private session (which doesn't share any cookies, session info, etc. with the rest of the browser) it also logs me out of the regular session. However it's tracking sessions this should not be possible.

teusbenschop commented 8 years ago

This behaviour is by design. No cookies are used for tracking users. Nothing is stored on the user's computer that leaves traces of visits to Bibledit Cloud, apart from the history of course that the browser may keep. Instead of cookies, the Cloud tracks the browser's signature plus IP address.

alerque commented 8 years ago

What problem were you trying to solve by re-inventing this wheel?

teusbenschop commented 8 years ago

The way Bibledit tracks sessions now was a solution to a problem caused by the ISP of a shared linux hosting account, which caused Bibledit to remain logged out for several hours in a row, at regular occasions. Back in the days that Bibledit-Web was the most recent version, and was written in PHP, it uses PHP's session built-in standard session tracking mechanism. Bibledit caused a lot of session data to be generated on the server. Each AJAX request (and there were many thousands of them from one days' translating with workbenches) somehow generated a session file, a new session file, on the server. The ISP had the habit of deleting old session files once a day. It may have been that the thousands and thousands of small session files started to exhaust inodes on the server. So the ISP started to run a daily script of removing all those session files. The script took a few hours to run every day, and during those hours it somehow disabled PHP's session tracking mechanism. So in order to bypass this problem, I had created the current session mechanism, written then in PHP, and written now in C++. I have found it to be working remarkably well, and to be very stable. Since it differs from the standard session mechanisms, and securely stored data in the Cloud, it will give more security, in particular in countries sensitive to the nature of the work.

teusbenschop commented 8 years ago

I think the problem is caused by the private/incognito tab of the browser. It obviously sends the same signature to the server as a normal tab does. Which means that a private / incognito tab is not as private as one wishes it to be: The server sees it as the same tab as a normal tab. I am closing this issue because it is not caused by Bibledit but by the browser.

alerque commented 8 years ago

Actually this is something that incognito mode should be able to do, the only reason it isn't working is that BE is circumventing the normal security mechanisms built into most HTTP traffic handling. As a result this is happening across more than just my browser, it's happening across computers and even survives reboots and wiping user accounts. It's wide open security hazard and annoyance to anybody actually running a secure network in that it cannot be made to work properly.

There are proper ways to work around the problems you ran into with PHP's session management, this just isn't how any of this is designed to work.

teusbenschop commented 8 years ago

Okay, if it is so serious, then I am reopening the issue.

Two factors that mitigate the issues are as follows:

  1. There is a "Logout" items in the menu: It erases the stored signatures on the server.
  2. There is an idle timeout automatic logout on the server (but I think the time-out period is now set to be very long).
teusbenschop commented 8 years ago

Actually this is something that incognito mode should be able to do, the only reason it isn't working is that BE is circumventing the normal security mechanisms built into most HTTP traffic handling.

Which one of the normal security mechanisms built into most HTTP traffic handlers are you suggesting would be a safe one to be used as a replacement of the current security mechanism?

alerque commented 8 years ago

Honestly a session tracking cookie is probably the best option. It really only becomes secure when combined with SSL, but even without it is more secure that the current implementation.

Think about the threat model here. In very broad terms there are three attack surfaces: the local computer, the remote server, and the network.

The problems you ran into with PHP sessions handling could have been solved by properly configuring the server. Writing temp files for every request that comes in is a broken configuration (and an easy DDOS attack surface). In fact writing anything at all for every poll request from BE is going to be problematic. Mostly this is because polling every few seconds or minutes is a backwards architecture, but even if we fix that we should still be careful about when we have to write to disk. Of course we're not dealing with PHP any more so it's issues (which have largely been fixed since the versions that were current when you ran into trouble) aren't germane.

The important things that should be dealt with first are:

  1. Making sure the client and server start their communication with a TLS handshake and all subsequent communication stays on that channel.
  2. Once they've established a secure way to talk to each other, agree on a session key unique to that session. Of course this is only passed across the secure channel from 1 so it can't be hijacked.

After that when we choose to expire the session, whether we keep meta data about the session state client side and/or server side, etc. are all implementation details.

alerque commented 8 years ago

By the way, it's become apparent why I've had so many problems with sessions getting hijaacked with the current mechanism. Since I'm running everything through a proxy server to get HTTPS functionality, BE sees the traffic all coming from one IP address: that of the proxy server. That kills half the finger printing mechasim. That half wasn't secure anyway given that the network is public and anybody in the chain can surf and inject traffic on my ip address. The second half falls because modern browsers are doing more and more to NOT send private identifiably information to third parties. This means browser fingerprinting is a less and less efective way to identify unique users. As browsers are increasingly secure, the data points used to make a fingerprint are fewer and fewer. Next throw in a few users using privacy addons that block server from seeing even a user agent and you have a perfect storm that enables things like a Chrome on Windows user in a separate physical location ending up logged in as an admin account from Firefox on Mac --- because both parties enabled a browser privacy extension. Something that should have made things better for them (even if user agent string blocking is kind of security theatre) exposed the fact that there was basically no functional security on BE at all.

  1. The default configuration sends credentials in plain text across a known tapped line.
  2. My modified proxy setup means that any user can connect as any other if they know or can guess the user agent string and a few other details. Users using privacy protections that make them more anonymous online are MORE at risk of makeing their sessions hijaackable.

Basically the only way to setup a BE instance that isn't wide open right now is to completely firewall it from the world and only allow access through a VPN network and trust all your users and their machines, plus make sure they all use different browsers to avoid accidental hijaaking.

Okay, I'm done ranting now. I think.

teusbenschop commented 8 years ago

Thank you, Caleb, for all the information. Yes, I understand the reasons for what you are saying.

I am now working on implementing TLS, as the first step, and will then proceed with the cookies, and once done that should provide a basic and standard secure connection.

Whatever comes after that can be seen and discussed then.

alerque commented 8 years ago

I added some notes about downgrade attacks to the roll-out discussion on the user group.

teusbenschop commented 8 years ago

In the case of e.g. clusters of Bibledit Cloud hosting, where one service runs on port xxxx and another one on port yyyy and another one on port zzzz, the cookies does not provide isolation per port number, see https://tools.ietf.org/html/rfc6265:

   Cookies do not provide isolation by port.  If a cookie is readable by
   a service running on one port, the cookie is also readable by a
   service running on another port of the same server.  If a cookie is
   writable by a service on one port, the cookie is also writable by a
   service running on another port of the same server.  For this reason,
   servers SHOULD NOT both run mutually distrusting services on
   different ports of the same host and use cookies to store security-
   sensitive information.

But the administrator of the cluster of Bibledit Cloud services can take measure to mitigate this issue, for example, by using subdomains, and perhaps there's other ways also.

And of course, if three translation teams run on the same cluster, one on port aaa, one team on port bbb, and one on port ccc, then these teams cannot be considered to be "mutually distrusting" because all teams do favour Bible translation, and still the outside enemy is blocked, no matter the ports the cluster of Clouds use.

alerque commented 8 years ago

I don't think this applies to the use case you describe. In this case the trust entity is the server, not the client. The cookies may be technically valid for any instance on the same domain name no matter the port, but the BE instance will only have valid records for it's own clients. In this case it isn't the users having to trust other teams of the administrator having to trust the users, it is the users having to trust that the server administrator can be trusted for all software on the domain. The thing is, even if cookies did track the port, this trust vector wouldn't be any different. As long as all teams trust the administrator, we aren't introducing any other vectors that need to be trusted that we already are by any of the teams using anything the administrator installs. This "weakness" is only exploitable by malicious software available on the same server, and if we end up with malicious versions of BE itself we have bigger problems that port-crossover.

alerque commented 8 years ago

BTW, we should probably only extend cookie lifetimes for page requests generated by actual navigation, AJAXy requests or anything polling on a timeout shouldn't generate disk write events on the server which would happen in the event of extending cookie validity.

teusbenschop commented 8 years ago

OK, yes, in our case it's the server that needs to be trusted, I see that this is the case.

As for extending cookie validity, I had made a note not to extend that with every HTTP request, but perhaps once a day to send a new cookie, only one, to the browser with updated expiry information. By default the Max-Age is now set to about 30 days to start off with, to get the most important bits in place first, and perhaps that should be made configurable later.

teusbenschop commented 8 years ago

User sessions are now tracked through the cookie that the browser sends. The old system, where the server reads the browser's signature, no longer works. It looks at the relevant cookie only.