Andrzej Wójcik (Tigase) opened 7 years ago
|
|
I've assigned this task to version |
|
An input from my discussion with %bmalkow about this topic:
As I discussed this with Bartosz, he pointed out that keeping a password in the pain text is not a good idea, because it may be recovered from the database by the attacker who hacked database server. It would be best to only keep a salted version of the password in the database. However, this could slow down authorization of users which try to log in using PLAIN authentication (XMPP client with SASL-PLAIN or any HTTP API access which required authentication). Moreover, this change would force user to change it's password whenever we would like to introduce new authorization scheme (ie. SCRAM-SHA256) From my opinion, we would keep a hashed version of the password in the database as well to reduce overhead needed by PLAIN based authentication, but Bartosz does not agree as he states it will not be good for security reasons. Either way, it would not solve the issue with forcing the user to change the password to use new authentication schemes. (Not yet known).
As this is an option of the application server, then the application server should be responsible for that. I suppose that we should consider renaming this value to At that time it would be worth to consider the possibility to introduce a new feature - a password per device. In this case, XMPP clients or use could create alternative
It would be best to keep generated salted version in the database. This way we would reuse it. We can (as suggested by Bartosz) keep only salted version instead of password or store it in a new database column to speed up authentication using SCRAM.
If we fix the previous point, then we can add support for caching salted passwords in our XMPP clients.
I would suggest creating a separate credentials table with following columns: %kobit %bmalkow %wojtek I'm waiting for your input on this topic. Version |
|
As for point no. 5, Bartosz suggested to check supported mechanisms on per user basis during GET_FEATURES request, but it would require access to a database which is not a good idea. |
|
Thank you for bringing up the topic, all the discussion and all the details. I am very much in favor of adding more security related features and improve Tigase. I think, the most important thing, when we plan to work on stuff like this, is to look at it from the end-user perspective and consider different and most common use-cases. When you plan improvements like this, please keep in mind our existing customers, so they are implemented in the way to best benefit them:
So, I will be more focusing on the topic from the business point of view down below. But before I dive to the topic, I would like to bring to your attention one important thing. We can (maybe we should) make available some features for our software only (server and clients). I mean, as long as we preserve compatibility with third-party, XMPP compliant clients, we do not have to worry too much that some stuff won't work with these clients. Of course I am not in favor in intentionally disabling some stuff for not our software (clients or servers). I mean we can implement in our software whatever we want and whatever is good for us and we do not have to worry about others. We just need to make sure other XMPP software can be used with standard features. Andrzej Wójcik wrote:
Plain text passwords are very bad PR for software vendors. So, this is enough of a reason to disable it. Moreover, I do not know a single person, business, technical or just a completely non-technical average user who would be OK with keeping his passwords in plain-text format in DB, nowadays. Therefore, even though, I strongly believe users should have options to choose from, I do not see much point to keep the functionality of storing plain-text passwords in DB. The only use-case I can think of is tests. This might be handy for running tests. Does Tsung support any other than plain authentication anyway? %wojtek As for the last point - changing authentication scheme. This does not happen often. Even less often as our business customers tend to stick with version they bought and installed years ago. And if we could implement it in such a way to make the switch optional, then this would not be a problem at all. And forcing users to change their password once a year (or just reenter the same password) is not that big of deal. What we really need here is password recovery function if something goes wrong on either end-user or the server end.
Bartosz is our expert in security stuff so we should rely on his opinions on this matter.
Yes, indeed, but I do not think it is a big problem, especially if we implement what is proposed down below:
It was implemented this way to reduce load on the XMPP server and kind of distribute CPU load between XMPP and DB. I agree, however, than this could/should be moved back to the application server.
Instead of renaming, I suggest we create a separate DB table with all the fields we need. This will give us more flexibility and also we keep more compatibility with previous versions.
I like this idea very much. However, we should think of, which use-case of the above this would benefit and how:
Ok, I am in favor of going this route. If we, as already suggested, have a separate table for stuff like this, we can keep lots of things and keep both, plain-text password, hashed, salted, etc... and load from DB whatever is best in particular case.
I am not so sure about this kind of cache. Ok, I understand the client side, this makes sense. But I am not sure about benefits on the serve side. Do you mean cache in memory or in DB?
Please note, I am not saying "No". I am just thinking how much improvement we can get from this and in what cases.
Yes, I agree, this is excellent idea. This would be also used for per-device passwords, etc....
Well, my question is: how much time would we need to get it done? I believe this is worth considering for 8.0.0. But... we should not delay 8.0.0 release for much longer. |
|
%kobit Some comments: Artur Hefczyc wrote:
I totally agree. My idea with password per device is kind following this path. We will not break authentication descibed in RFC but we would extend it as it was intended to be extended.
OK. So for sure we want to remove plaintext based passwords from database. But I think we still need to have SASL-PLAIN enabled by default as it is required by RFC.
Sure, but we need a way to upgrade people with existing installations and it would be good not to break it. We supported integration with other software on the database level and in some cases passwords were used from external database - which stored passwords in plaintext.
We have a task for that which was delayed all the time -> #1753
Yes, we could easily convert passwords to the new version if they were stored in plaintext on in an encrypted form MD5.
We could add a HTTP API page as a begining. For now I would like to have an API ready for 8.0.0 and management UI and adhoc scripts for administrative tasks could be added in 8.1.0. At least this was my idea.
Most of IoT devices which have network connectivity (ethernet/wifi) are capable of running simple HTTP server which could be used to configure basic settings initially, ie. username/jid and password? But this is just an idea..
I was considering storing this data in the separate database table on the server side and we would load this "cached" version instead of loading password which we already need to do. So it would be no downside to doing so.
Yes, I already took this into account. So on this single change will be able to build solution in 8.0.0 (partially, only what is needed) and extend it in 8.1.0/
I have nothing on my todo list, so I can take it on right now and I think in a week it would be finished. At least basic part. In basic part I mean, changed schema (tables and procedures), changed API and adjusted to use new procedures. Maybe I would add this password recovery feature as well during 1 week. (1 week so 7 days I assume) |
|
+1
+1
I know, but if we do this all stuff described here, this task must be part of it.
+1
I am more in favor of doing this kind of XMPP way: A new device connected to the network, scans the network looking for "Tigase XMPP Hubs" (Tigase XMPP Server, potentially with some IoT specific stuff). Once found, it connects to the hub as anonymous user (possible publishing it's information to some PubSub node). Then we have kind of an admin interface connected to the HUB (HTTP API page or a mobile client or some other client with extra functionality) which shows all the new devices connected as anonymous users. The interface would allow to assign login credentials and specific functions and other stuff to this new devices. In other words we would have one central point to maintain and manage all the devices.
Ok, understand, this makes sense and seems like an improvement indeed.
Ok, in such a case let's do this, unless there are objections from Bartosz or Wojciech. Approved from my side. |
|
Artur Hefczyc wrote:
%kobit AFAIR it supports only PLAIN and Anonymous, but PLAIN will still be available so there shouldn't be a problem. |
|
SASL-PLAIN will works with any kind of password encoding. If password will be encoded with PBKF2-SHA1 then the only available methods are SASL-PLAIN and SASL-SCRAM-SHA-1(-PLUS). If password will be encoded with PBKDF2-SHA256, then it will be SASL-PLAIN and SASL-SCRAM-SHA-256(-PLUS). So SASL-PLAIN is available all the time (at least from technical point of view). Storing hashed copy of password for faster processing is not good idea (well… depends on what kind of hash will be used). But to improving performance only SHA1/SHA256 seems to have sense. In that case security will be lower (do you remember Rainbow Tables?). Conversion between PLAIN or MD5 (does anyone uses it?) to SCRAM-SHA1 (or from SCRAM SHA1 to SHA256) may be done silently during login, but user must bo forced to use SASL-PLAIN, then received plain password we can encode to new form. When I'm thinking about new auth data structure, I have in mind credentials data encoded per user. Each user credential (lets skip multiple passwords for now) has own type (pbkf, md5, plain, …) and encoded credential data. In that case we are able to offer only usable SASL mechanisms for user. Of course, if user inform us about his username in <stream:stream from="…">. In other case offered will be mechanisms defined as allowed for domain or for database. I'm still thinking about per-device-password, and I'm not sure how it should works. We can extend our client to sen device_id during login process, but we cannot o that with other clients. So, how login process should looks like when client is Adium or Psi? |
|
Bartosz Malkowski wrote:
Good point.
Could you please elaborate on this more? At least on the last part. What hash method would you suggest to improve both performance and security?
Why security is lower in this case? Rainbow tables - no idea what you are talking about. Some links? Again, what would you suggest to improve both: performance and security?
Indeed, good point.
I agree this seems the best option. And it also opens new opportunities. We had customers in the past who asked us if we can block out of the box all the XMPP clients except their own custom clients. We did not offer this out of the box and they had to implement custom authentication protocols. But with this change we could be more flexible.
Or some other default with maybe some fallback mechanism.
Not every feature has to work with all XMPP clients. Feature like this is probably more for non-standard XMPP installation, where Tigase would be integrated with third-party systems. Think of Tigase integration with Fastmail for example. |
|
The task is finished in implementation part but I need to write a few words in the documentation about this change and to describe it. |
|
And we need testing for this new stuff. |
|
Artur Hefczyc wrote:
Unit tests are already in place and TTS-NG has new tests to cover this functionality in basics. Authentication, password change, password reset using email, etc. There are no adhoc commands to list or create custom username-password pairs but API for that is in place and we can extend it in version 8.1 easily. And old API is marked as deprecated and may be removed in future versions. |
|
Excellent. |
|
This work is done and tests are passing. I've created separate task #6238 for the creation of notes for this change and merging this notes to the documentation of Tigase XMPP Server, so that anyone upgrading Tigase XMPP Server to the new version will be aware of this changes. Artur, I think that we can close this task if you do not wish to make some additional verification of this change? I think that this mechanism is covered in test cases and we will test it either way during the upgrade of our installations. |
|
Ok, let's upgrade our installations asap then. |
Type |
Task
|
Priority |
Normal
|
Assignee | |
RedmineID |
6212
|
Version |
tigase-server-8.0.0
|
Spent time |
323h 45m
|
During work on #4814 I've found out that our current authentication mechanism is complicated and not easy to maintain. I've identified following issues:
This is not a good idea for security reasons.
If we want to support this feature it should be done on the application level. The database is just for storage, not for processing.
Right now we do not have a cache for a salted version of the password, salt, and iterations number, which forces us to calculate this salted version during each authentication of a user. This process requires around few thousands of hmac operations which are rather fast but in total create a huge overhead.