View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0000698 | SOGo | Web General | public | 2010-07-22 05:44 | 2010-12-28 18:50 |
Reporter | gienger | Assigned To | ludovic | ||
Priority | normal | Severity | major | Reproducibility | always |
Status | resolved | Resolution | fixed | ||
Product Version | 1.3.0 | ||||
Target Version | 1.3.5 | Fixed in Version | 1.3.5 | ||
Summary | 0000698: Security bug: Usernames and passwords appearing in the http cookie | ||||
Description | I just stumbled upon a decrypted session to our sogo host and the browser sends this: POST /SOGo/so/my_user_name/Mail//my_D_name_A_mydomain_D_de/folderINBOX/uids HTTP/1.1 Cookie: 0xHIGHFLYxSOGo=basic%20XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX is the culprit, the XXX is exactly the base64 encoded form of "username:password" as it is used by Basic HTTP auth. This cookie stays stored on the user's browser. From my understanding this is a security no-go, it should be an anonymous random hash code which is only describing an entry in the session table of the web application, so when the session has timed out the cookie has become worthless. This cookie is valid forever, even after logout - more: just by searching the cookie database of the browser you'll get the user account and his password! | ||||
Additional Information | The memcache-daemon should be a nice place storing session cookies to get the relation between the cookie/session id and the username/password... The Cookie is really set by SOGo: set-cookie: 0xHIGHFLYxSOGo=basic%20XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX; path=/SOGo/ | ||||
Tags | No tags attached. | ||||
To get around the issue I wrote an apache module for our installation which catches the "Set-Cookie" of SOGo and creates a session (stored in a postgresql db) and offers a unique cookie key to the browser. Each time the user sends along this cookie the module rewrites it to the "SOGo cookie" method so that the session remains ok for SOGo. It also catches the "Set-Cookie: 0xHIGHFLYxSOGo=discard; ...." to close the session (remove the entry from the db and issue the appropriate cookie deletion line to the browser). This is surely an ugly solution but it works at least for my test userbase. I am not feeling good about storing base64-passwords on the user's browser. I understand that storing the Password on the browser when using basic http auth (for DAV) is also a security risk but normally people do this on THEIR own computers (having installed a CalDAV client). But users from a web session are not aware that the browser stores their password in a cookie. Apart from that the usability of SOGo is perfect for us, I never saw such a smooth and usable web frontend. We have users not missing a locally installed client any more. |
|
We might do something about this but it's not on top of our priorities. When you logout, the login cookie MUST disappear. It does it for me on FF 3.5 and I wonder why it would not work for you. Which browser are you using? Regarding the cookie being passed between the client and the server it's easily worked-around by using SSL as a "cheap" solution for now... |
|
It does disappear, but during a session every malicious javascript program can read out this session key and then it has username and passwort. Plus you can't close a session as an administrator. We are on the way to implement SOGo as a solution for our public university. We want to get rid of the Horde/IMP solution which rans on 16 CPU cores with 64 GB RAM per node. I developed stress tests to test SOGo for 4000 users logged in simultaneously doing as many mailbox reloads as possible. SOGo has passed. That's cool. Our Cyrus IMAP runs on a redundant FibreChannel Storage and handles SOGo load much better than Horde/IMP load. But many of our students are abroad, in the U.S., in Canada ( :-) ), in Africa, in Asia - and they want to use the web interface. And I am not feeling good knowing that the user's password is stored as a cookie on a computer on Kinshasa, Shenzen, Toronto or Atlanta - only because the user forgot to log out. SOGo is our deal to avoid that they're all using Google. We are very reluctant to send out official grade notices and administrative mail to external accounts - we have a strong data protection policy here. So SOGo IS the tool bringing our users back to us. C'est vraiment parfait! |
|
PS: Since Cyrus IMAP 2.3.16 there's a statuscache options. It caches STATUS data so that subsequent IMAP STATUS calls can be answered instantly without looking in storage/mem cache when there is no new mail. Bron Gondwana from fastmail.fm submitted the code. When a user reloads his mailbox instead of "XXX SELECT INBOX" a STATUS call would be cute and when there's no change the Javascript Framework working on the user's browser could just stop reloading new data and just continuing to show the already loaded uids data. |
|
What do you mean by "Plus you can't close a session as an administrator."? Don't you see the "Logout" button then? Also, I don't see how a "malicious javascript program" can read the session key, unless it's a firefox extension (but which could read any cookie). The SOGo cookie is limited to the site where SOGo is accessed (by domain and by path), thus a script running on "badcompany.com" would not have access to those cookies. Also, a script running on "goodcompany.com/my/site" would not have access either to cookies from "goodcompany.com/SOGo/". The only concern you might have for this would be for example for javascript programs to be executed from mails but in that case we do discard javascript code. The only remaining issue on that side is if you run IE, because it offers the wonderful feature of executing JS from CSS stylesheets (via the "behaviour" attribute). But if you want security, you should not use IE at all... |
|
regarding Cyrus, it is an interesting feature indeed. Note that the live-loading code is already doing a better job at caching things. A few improvements are still needed and they are probably going to be implemented in the next few weeks. |
|
You wrote: "What do you mean by "Plus you can't close a session as an administrator."? Don't you see the "Logout" button then?" No I mean that a user calls the helpdesk that he forgot to log off on a machine in <some city> if we could look up if the session is closed. Many internet cafés use IE 6, especially in Africa and China. I am sleeping well when I know that the session cookie is worthless after 60 minutes of inactivity. My little apache module does that... Please don't understand me wrong: I do not want to critizise your work, SOGo is a fantastic tool. We're on the way do deploy it here, but this cookie handling astonished us - really. |
|
Don't worry. I don't take this as criticism but I like to play the devil's advocate when I don't understand everything clearly. A personal bug. |
|
I generally find it good practice to expose as little sensitive information as possible. You never know what kind of bugs will be detected in any of the components (browser, libraries, proxies, …) with which SOGo interacts. Therefore, having an inconspicuous cookie which will not be reused between sessions sounds like a desirable property. [Full disclosure: I do work in the same organization as user gienger] |
|
Btw, wouldn't the CAS autnhentication system be an interesting solution? I think it integrates well with Kerberbos and it solves this very issue... |
|
Hi. I'd just like to add that this is a security issue for me, because, even if the cookie is deleted at the end of the session, it has been written to disk, so it's recoverable. Passwords should never be written to disk. Regards |
|
Hi gienger, do you plan to publish this apache module? It really makes me sad that security is "not on top of [the] priorities." :( However, your module seems to be an appropriate workaround for me... So it would be cool if you released it. Regards Mirko |
|
If this behavior in SOGo would be changed it should be done carefully. Especially caching the access information (usernames/passwords) on the server itself can be a security issue, too. For example: RoundCube can cache this information with a recoverable encryption in the database for the sessions. So caching the access information on the server has to be implemented very carefully. For example: esco |
|
I consider most servers (and server software) to generally be easier to keep secure than all the clients. In our installation, we have a handful of machines and less than a handful of knowledgeable people with access to them; on the other hand, we have over 10k potential SOGo users, many of them not very computer-savvy, on a almost every conceivable platform and sometimes with very outdated software. For us, it is much easier to keep the admins and servers clean than the users and their devices. And if something actually goes wrong, we are in a better position to fix things. I also find it biased to compare one single scripting-language-based webmail security bug in alpha and beta products only to the numerous (and sometimes design-inherent) problems with browsers. I lost count of how many problems have been discovered in browsers which allow access to data that should not be accessible (cookies, sessions, auto-fill caches, …) Therefore, I would prefer to keep passwords, if they need to be stored at all, on the server side. I also think that SOGo would be a better place than an Apache module, because it would automatically be included in the distribution and would include one fewer party having to deal with passwords and secured against their theft. |
|
Don't get me wrong. I fully agree! However, I still would prefer the Apache module over doing nothing or just praying ;) |
|
Hi Mirko, Regarding your comment above (0001565), please note that we implement a lot of things based on the sponsoring we receive. This issue has actually never been reported to us before and we never heard of any actual security breach yet. Therefore and since fixing this is non-trivial, it's indeed not in our top priorities... |
|
Hi wsourdeau, I did not want to criticize your work at all. And I can follow your argumentation that you did not know that this was a problem before. However, I see a consensus of most reporters here that this is an issue that should be solved. I do not doubt that fixing is is "non-trivial". However, I think most users here (at least me :P ) would be happy to here if you would regard this issue important and set it on the agenda. Statements like "not in our top priorities" make me feel a bit uncomfortable and make me fear that there are more vulnarabilities not regarded serious... Don't take me wrong. I can follow your argumentation and I see that you didn't know it before and that there is effort needed to solve it. However, your statements make me feel uncomfortable when I think about our sensible data ;) |
|
Hi Mirko, No offense taken, don't worry. |
|
Regarding this issue in general. Please note that HTTP-Simple is used when authenticating DAV clients as well... |
|
Ok, this indeed sounds better to me ;) So, I can hope that the issue is fixed one day from SOGo side and I do not need to get that workaround? |
|
Contenance messieurs (et mesdames!)! esco is right, it is not a superb idea to store username:password-Pairs on the server but - be honest - most Webmail frontends do so as normally they don't do proxy authentication with a special username to the imap backend (which also leaves the pithole of hacking that special username to be able to authenticate as everyone you wish...). My apache module is not meant to be a SOGo solution, it is a workaround because I felt better with controlling a cluster behind a firewall with minimal setup and security updates applied regularly as opposed to have username:password-pairs stored on web browsers all over the world. As for Mr Sourdeau: You are right, with DAV you are using HTTP Basic Auth and this can also be stored on the browser. But there's a gentle difference: You won't access your calendars nor your address cards by DAV on a public computer which is not controllable by yourself. The typical DAV usage pattern is to have it done by your personal PC or notebook. This is something totally different than a web session from a computer in some parts of the world which are quite often full of viruses and other "thingies" (because nobody cares). The password story is quite bad because of the IMAP backend, normally an IMAP server does not share any token to access mailboxes and functions. This is where software breaks. |
|
I am on vacation until next monday, so on tuesday I will put the little apache module as source code text on a public reachable server - for those who want to experiment. Keep in mind that this is NOT my recommended solution for the future, it is a workaround I made to anonymize the cookie value. I am getting old, so my sleep is important - and like this I can sleep much better ;-) |
|
"For example: This would be a trivial task. The module just would have to set another initial cookie with a symmetric encryption key as value. This cookie will be passed with every request so the apache module can decrypt it with this value. Nice idea, I'll try that on tuesday. If my database is stolen so the culprit cannot decode the username-password pairs. |
|
For those who were interested: My experimental module can be found here: http://southbrain.com/software/sogosession/ It uses a session key and a user key, only known by the user's browser. The system needs this user key to decrypt the session database entry. Without it the data is useless. Keep in mind that i am NOT a software developer and NOT a code hacker (I prefer to organize and plan projects) so code quality may not be that what you expect. YMMV. DB username is "sogo", password is also "sogo" in the default config. To change: Apache directives UniKnSogoSessionPostgresUser and UniKnSogoSessionPostGresPassword. UniKnSogoSessionDatabaseName is the name of the session db, "sogosession" is the default. Be sure to read the NOTICE/README. Update: version 0.11 is actual, even with "memory full" (malloc returns NULL) the original sogo cookie won't get propagated to the browser. |
|
Hi gienger, thanks a lot for the implementation and making this public. I will install this in our SOGo environment, too. esco |
|
Just a little note, a new version has been released, it fixes a strlen() context bug (idiot error by myself). |
|
Instead of storing stuff in the SQL database, I think we should go with the membase (www.membase.org) route (or repcached). |
|
Interesting idea but please don't break up cluster capability (are the proposed membase engines reachable via IP or are they only useful for services on the same host?). Merry christmas you all! |
|
If I understand this problem correctly, SOGo does not store the username/password on the server side (great!) but decodes this from a cookie in every http request (also great, except that it's basicly stored plaintext on the client side). I'm a bit torn about what's worse.. storing all username/passords in memcached on the server side, or each username/password on the client side. I think maybe I prefer the current situation with only storing them on the client side.. at least then we shouldn't risk leaking thousands of passwords at the time.. But, a suggestion for solving this better might be to store the username/password encrypted with a serverside key in a cookie. Then we don't need to worry about clients leaking it's single username/password, and the serverside exposure is not any worse.. I haven't looked at the SOGo codebase yet, so I'm not able to provide a patch now, but would imagine this should be an easy fix without really changing much logic. Just provide a SOGoSecretPassword setting, and use this to encrypt/decrypt all places the password cookie is base64 encoded/decoded. |
|
Implemented in: You MUST now set OCSSessionsFolderURL to a value like: postgresql://sogo:sogo@127.0.0.1:5432/sogo/sogo_sessions_folder and the database table will be created automatically upon next SOGo's startup. |
|
Also in: |
|
Date Modified | Username | Field | Change |
---|---|---|---|
2010-07-22 05:44 | gienger | New Issue | |
2010-07-23 18:27 | gienger | Note Added: 0001225 | |
2010-07-23 18:30 | gienger | Note Edited: 0001225 | |
2010-07-23 18:57 |
|
Note Added: 0001226 | |
2010-07-23 19:08 | gienger | Note Added: 0001227 | |
2010-07-23 19:15 | gienger | Note Edited: 0001227 | |
2010-07-23 19:20 | gienger | Note Added: 0001228 | |
2010-07-23 19:25 |
|
Note Added: 0001229 | |
2010-07-23 19:26 |
|
Note Added: 0001230 | |
2010-07-23 19:35 | gienger | Note Added: 0001231 | |
2010-07-23 19:39 |
|
Note Added: 0001232 | |
2010-07-23 20:15 | Marcel | Note Added: 0001233 | |
2010-07-23 20:18 |
|
Note Added: 0001234 | |
2010-09-22 09:46 | dani | Note Added: 0001508 | |
2010-10-08 06:31 | mirko | Note Added: 0001565 | |
2010-10-08 07:42 | esco | Note Added: 0001567 | |
2010-10-08 09:18 | Marcel | Note Added: 0001568 | |
2010-10-08 11:16 | mirko | Note Added: 0001569 | |
2010-10-08 13:40 |
|
Note Added: 0001571 | |
2010-10-08 14:07 | mirko | Note Added: 0001572 | |
2010-10-08 14:20 |
|
Note Added: 0001574 | |
2010-10-08 14:33 |
|
Note Added: 0001578 | |
2010-10-08 14:34 | mirko | Note Added: 0001579 | |
2010-10-08 16:44 | gienger | Note Added: 0001583 | |
2010-10-08 16:58 | gienger | Note Added: 0001584 | |
2010-10-08 16:58 | gienger | Note Edited: 0001584 | |
2010-10-08 17:00 | gienger | Note Edited: 0001583 | |
2010-10-08 17:08 | gienger | Note Added: 0001585 | |
2010-10-22 12:48 | gienger | Note Added: 0001641 | |
2010-10-22 13:10 | esco | Note Added: 0001642 | |
2010-10-22 13:21 | gienger | Note Edited: 0001641 | |
2010-10-22 13:44 | gienger | Note Edited: 0001641 | |
2010-10-25 08:29 | gienger | Note Edited: 0001641 | |
2010-11-08 10:26 | gienger | Note Added: 0001726 | |
2010-11-19 18:07 | ludovic | Target Version | => 1.3.5 |
2010-11-19 18:07 | ludovic | Description Updated | |
2010-12-24 01:51 | ludovic | Note Added: 0001966 | |
2010-12-24 07:47 | gienger | Note Added: 0001967 | |
2010-12-24 13:07 | janfrode | Note Added: 0001970 | |
2010-12-28 18:44 | ludovic | Note Added: 0001971 | |
2010-12-28 18:44 | ludovic | Status | new => resolved |
2010-12-28 18:44 | ludovic | Fixed in Version | => 1.3.5 |
2010-12-28 18:44 | ludovic | Resolution | open => fixed |
2010-12-28 18:44 | ludovic | Assigned To | => ludovic |
2010-12-28 18:50 | ludovic | Note Added: 0001972 |