Ticket #5295 (assigned enhancement)

Opened 3 years ago

Last modified 6 months ago

[patch] Add optional username regexp to registration checks

Reported by: manski Assigned to: hasienda (accepted)
Priority: normal Component: AccountManagerPlugin
Severity: normal Keywords: security precaution user register name check regexp
Cc: thijs, felix.schwarz@agile42.com, rjollos, olemis, AdrianFritz, mmitar@gmail.com Trac Release: 0.11

Description

Today I stumbled upon a big security hole or at least a way to almost render a Trac environment useless in the AccountManagerPlugin. The problem is that the check for existing users when creating a new one in the Registration module is flawed.

The check doesn't check for the usernames "anonymous" and "authenticated". So it's easily possible to register as "anonymous" or "authenticated". While you can't login as "anonymous" you can do so as "authenticated". While this is already a bad thing it gets worse. Since there is the possibility to delete my account one could register as "authenticated" and then delete the account again. Doing so he/she would thereby remove the group "authenticated" from the permessions store. This way all registered user would be demoted to "anonymous" (unless they were given some permissions directly).

Also it's possible to register as an already existing permission group (like "anonymous" and "authenticated") and inherit all of its permissions. Say I've created a group called "developers", added the permission "TICKET_ADMIN" to this group and assigned all the members of my development team to this group. Now they all have the permission "TICKET_ADMIN". However, a user could register with the name "developers" and also gain the permission "TICKET_ADMIN". And that's very bad! (Fortunately the user has to know the name of the permission group which he/she can't find out so easily. But he/she could simply try some common names.)

I've attached a patch to this ticket the fixes this problem. It also !add the possibility for the !admin to define a regular expression for valid usernames. Moreover the patch prohibits usernames containing characters that are harmful for some password stores (this fixes #4682 and #2630).

Attachments

check_username_fix.patch (4.7 kB) - added by manski on 05/28/09 14:12:36.
Patch against r5836 and Trac 0.11.4
ticket-5295.patch (2.9 kB) - added by mitar on 10/10/10 15:03:40.
username_regex.patch (1.2 kB) - added by mitar on 01/27/11 01:06:28.
Username regex patch against r9785

Change History

05/28/09 14:04:40 changed by authenticated

As you can see I (manski) have already register as "authenticated". I've only done this to protect this Trac environment.

05/28/09 14:12:36 changed by manski

  • attachment check_username_fix.patch added.

Patch against r5836 and Trac 0.11.4

05/28/09 14:14:38 changed by manski

A workaround for this problem is:

  • disable the registration module
  • or create users for all permission groups in the password store

(follow-up: ↓ 5 ) 06/10/09 17:59:17 changed by coderanger

Hmm, there is already a simple check for existing groups, that should probably be strengthened rather than invoking some kind of regex as your patch does. Other than explicitly blacklisting "anonymous" and "authenticated" I'm not really sure how best to do that though.

(follow-up: ↓ 6 ) 06/10/09 17:59:46 changed by coderanger

Also, this is at best a nuisance, you cannot gain permissions you shouldn't otherwise have.

(in reply to: ↑ 3 ) 06/16/09 08:17:51 changed by manski

Replying to coderanger:

Hmm, there is already a simple check for existing groups, that should probably be strengthened rather than invoking some kind of regex as your patch does. Other than explicitly blacklisting "anonymous" and "authenticated" I'm not really sure how best to do that though.

Sorry that I've included it. The regexp is optional. (The admin can define at regular expression for valid user names.) The actual check is in the lines above the regexp check.

(in reply to: ↑ 4 ; follow-up: ↓ 7 ) 06/16/09 08:19:07 changed by manski

Replying to coderanger:

Also, this is at best a nuisance, you cannot gain permissions you shouldn't otherwise have.

Well, you can gain permissions of existing Trac groups (as described above).

(in reply to: ↑ 6 ; follow-up: ↓ 8 ) 06/16/09 08:22:14 changed by coderanger

Replying to manski:

Replying to coderanger:

Also, this is at best a nuisance, you cannot gain permissions you shouldn't otherwise have.

Well, you can gain permissions of existing Trac groups (as described above).

Only if those groups have the same permissions as "authenticated".

(in reply to: ↑ 7 ; follow-up: ↓ 9 ) 06/16/09 08:30:41 changed by manski

Replying to coderanger:

Replying to manski:

Replying to coderanger:

Also, this is at best a nuisance, you cannot gain permissions you shouldn't otherwise have.

Well, you can gain permissions of existing Trac groups (as described above).

Only if those groups have the same permissions as "authenticated".

No, I think that exactly the thing that is not checked. If a group has the same rights as "authenticated" the following condition is evaluated as "true":

!python
permission_system = perm.PermissionSystem(env) 
if permission_system.get_user_permissions(user) != \ 
   permission_system.get_user_permissions('authenticated'): 
    error.message = 'Another account with that name already exists.' 
    raise error 

However, if the group has more (oder less) permissions than "authenticated" the condition above will be evaluated as "false" and therefore no error will be raised.

(in reply to: ↑ 8 ) 06/16/09 08:33:17 changed by coderanger

Replying to manski:

Replying to coderanger:

Replying to manski:

Replying to coderanger:

Also, this is at best a nuisance, you cannot gain permissions you shouldn't otherwise have.

Well, you can gain permissions of existing Trac groups (as described above).

Only if those groups have the same permissions as "authenticated".

No, I think that exactly the thing that is not checked. If a group has the same rights as "authenticated" the following condition is evaluated as "true": {{{ !python permission_system = perm.PermissionSystem?(env) if permission_system.get_user_permissions(user) != \ permission_system.get_user_permissions('authenticated'): error.message = 'Another account with that name already exists.' raise error }}} However, if the group has more (oder less) permissions than "authenticated" the condition above will be evaluated as "false" and therefore no error will be raised.

Pretty sure you have that backwards. If you try to register a username and that username has any permissions different from "authenticated", the registration is rejected.

06/26/09 14:15:52 changed by thijs

  • cc set to thijs.

So is there a security hole in this plugin or not?

(follow-up: ↓ 12 ) 07/16/09 04:39:24 changed by olly@survex.com

I think it's "remote denial of service" at worst.

I tested, but couldn't register using the name of the group with TRAC_ADMIN and WIKI_ADMIN privileges on my 0.11.4 trac installation, so the privilege-escalation scenario in the original description doesn't seem to work (as suggested by previous comments).

But (as also mentioned in the description) an attacker probably could register with user name authenticated and then delete that account, so deleting the permissions for group authenticated. which on a typical trac installation with this plugin installed would remove all create and modify rights from normal users - i.e. a remote denial of service. But I've not tested this myself.

(in reply to: ↑ 11 ) 07/16/09 08:31:21 changed by manski

Replying to olly@survex.com:

I tested, but couldn't register using the name of the group with TRAC_ADMIN and WIKI_ADMIN privileges on my 0.11.4 trac installation, so the privilege-escalation scenario in the original description doesn't seem to work (as suggested by previous comments).

Sorry, but that's not correct. These are not groups. These are permissions. Groups are basically usernames without password. You can add a "subject" (this is a user oder group) to a group using the permissions admin panel.

In my example I created a group called "developers" that has the permission TICKET_ADMIN. And if then one registers as "developers" (as just somebody has done on this page to check whether he/she can gain rights through this) the user would gain the TICKET_ADMIN right.

07/16/09 16:37:18 changed by anonymous

You misunderstand me. I have a named group in my trac install with permissions TRAC_ADMIN and WIKI_ADMIN, and I tried to register using the name of that group as my username, but it doesn't let me. I wasn't trying to register with user name TRAC_ADMIN or WIKI_ADMIN (and if I had tried that, it would presumably have worked, not failed. But that's OK, that wouldn't give me any magic powers).

I just tried your exact example - I created a new group "developers" with permission TICKET_ADMIN. Then I logged out and tried to create a new user account called "developers", but I got this error:

Error

Another account with that name already exists.

I can create user "developers" via the users section in the web admin UI, but an attacker wouldn't have access to that (if they did, they could give themselves whatever permissions they want anyway).

07/27/09 15:10:15 changed by felix.schwarz@agile42.com

  • cc changed from thijs to thijs, felix.schwarz@agile42.com.

09/03/09 09:03:45 changed by rjollos

  • cc changed from thijs, felix.schwarz@agile42.com to thijs, felix.schwarz@agile42.com, rjollos.

12/11/09 13:58:24 changed by anonymous

  • cc changed from thijs, felix.schwarz@agile42.com, rjollos to thijs, felix.schwarz@agile42.com, rjollos, olemis.

03/03/10 15:14:52 changed by AdrianFritz

  • cc changed from thijs, felix.schwarz@agile42.com, rjollos, olemis to thijs, felix.schwarz@agile42.com, rjollos, olemis, AdrianFritz.

03/03/10 15:23:34 changed by AdrianFritz

  • summary changed from Registration module is a potential security hole to [Patch & WorkArround] Registration module is a potential security hole.

(follow-up: ↓ 20 ) 05/20/10 17:12:42 changed by d.nedelchev

Or maybe just to allow only all-uppercase group-names (like the permissions itself)? In fact a group here is a set of permissions so it sounds meaningful... All-uppercase subjects are automatically excluded from allowed subjects list (admin). However, (I've just tried it) they are allowed usernames for the registration module (and obviously it should be fixed there)! The only issue I guess will be backward-compatibility with the existing non-all-uppercase group-names like "anonymous", "authenticated" and any custom group since now all-uppercase groups are prohibited in the admin-panel (as well as all-uppercase usernames). What do you think, is it a good or a bad idea?

P.S. I've read in the comments this issue allows a user to obtain only permissions which already have. I've tried it on my local sandbox environment and I would say, this issue actually is NOT a security hole (possibly even not a potential one). However I think it could be made more clean. In any case the Registration module should be fixed to prevent creating all-uppercase usernames.

(in reply to: ↑ 19 ) 05/24/10 18:07:31 changed by manski

I don't really understand what you're saying (partially because you didn't say what Trac version you're using; I'm using Trac 0.11.x).

Replying to d.nedelchev:

Or maybe just to allow only all-uppercase group-names (like the permissions itself)?

What do you mean by this? "Allow" where and what? And again: all-uppercase names are not group names. They are permission/action names. (Just have a look at the note on the bottom of the "Permissions" admin panel.)

The only issue I guess will be backward-compatibility with the existing non-all-uppercase group-names like "anonymous", "authenticated" and any custom group since now all-uppercase groups are prohibited in the admin-panel (as well as all-uppercase usernames).

How would this be an issue? An issue with what?

P.S. I've read in the comments this issue allows a user to obtain only permissions which already have. I've tried it on my local sandbox environment and I would say, this issue actually is NOT a security hole (possibly even not a potential one). However I think it could be made more clean.

I'm not sure how I could produce the problem with "developers" group in the first place. I tried to reproduce the problem today but was unsuccessful - even with the versions/revions noted in the patch. So I seems as if I made an error there (not sure why I came to my conclusion). Existing permission groups can't be "registered" - except for "authenticated" which may not be a "security hole" but a least a big problem as a bad user could bring down the whole Trac environment by exploiting this problem.

09/26/10 03:22:26 changed by hasienda

  • keywords set to security precaution delete.

According to my own investigations I've found as well, that the issue is only related to the "authenticated" group. Still it should be addressed better than now.

10/01/10 23:11:38 changed by hasienda

#7575 provided a use case for the regexp username check suggested here, so it has been closed as a duplicate with reference to this ticket.

10/03/10 22:16:20 changed by hasienda

(In [9247]) AccountManagerPlugin: Fix a small Python doc-string typo, refs #5295.

10/07/10 14:28:10 changed by hasienda

(In [9260]) AccountManagerPlugin: Extend username checks before registration.

We've got some suggestions and even patches to improve checking for invalid usernames on registration attempts. Therefor checks

  • against a list of reserved names (refs #5295)
  • for colon corrupting HtPasswdStore (closes 4682)
  • for characters ' and ? corrupting SvnServePasswordStore (closes 2630)
  • for surrounding whitespace and removes it (closes 7087)

are added now. Thanks to all contributors, especially to manski, for exceptional help by reviewing tickets and bundling related issues.

10/07/10 14:42:36 changed by hasienda

  • status changed from new to assigned.
  • severity changed from critical to normal.
  • summary changed from [Patch & WorkArround] Registration module is a potential security hole to [patch] Add Registration module is a potential security hole.
  • priority changed from highest to normal.
  • owner changed from pacopablo to hasienda.
  • keywords changed from security precaution delete to security precaution user register name check regexp.
  • type changed from defect to enhancement.

The last remaining part is a proposal for adding an admin-configurable regexp for valid usernames.

To properly keep track of this, I change the ticket to reflect this right now.

10/07/10 14:44:54 changed by hasienda

  • summary changed from [patch] Add Registration module is a potential security hole to [patch] Add optional username regexp to registration checks.

Finishing the previously started changes.

10/10/10 15:02:53 changed by mitar

  • cc changed from thijs, felix.schwarz@agile42.com, rjollos, olemis, AdrianFritz to thijs, felix.schwarz@agile42.com, rjollos, olemis, AdrianFritz, mmitar@gmail.com.

I am using following patch for some time now and it works great.

10/10/10 15:03:40 changed by mitar

  • attachment ticket-5295.patch added.

10/10/10 15:36:43 changed by hasienda

Your latest patch is not based on current trunk and doesn't contain new information beyond the previous one done by manski. Thanks for taking care anyway.

Would you dare to test it with latest changes, that already add all improvements with exception of the username-whitelist-regexp feature, please? I'm looking forward to hear your experiences.

10/10/10 15:51:25 changed by mitar

I know, it is an old patch I made some time ago. It is just to explain what has been in production for some time now.

Currently I do not have any (non-production) system where I could test new improvements. I will be doing some new deployments in few months and I can test things then.

11/18/10 01:02:44 changed by hasienda

See #8076 for some more proposed regexp to check for a valid email too.

01/27/11 01:06:28 changed by mitar

  • attachment username_regex.patch added.

Username regex patch against r9785

(follow-up: ↓ 32 ) 01/27/11 01:07:30 changed by mitar

I have just attached a patch which adds a configuration option to limit allowed usernames with a regex. It is made against current trunk (r9785).

(in reply to: ↑ 31 ) 01/28/11 11:12:50 changed by hasienda

Replying to mitar:

I have just attached a patch which adds a configuration option to limit allowed usernames with a regex. It is made against current trunk (r9785).

Thank you for the update on this ticket. At first glance it looks good. I'll have a second look and some testing, if this is not disturbing other things and fits into the overall concept. As we're accumulating more and more sanitizing and validation of various user input, I'm actually rethinking the current code structure. It might be good to do more modularization on this part for a gain in structure and overall readability.

06/28/11 21:46:47 changed by mitar

Could this be included into the core? This is one of two patches I am using in my Debian package.

06/28/11 23:53:59 changed by hasienda

Thanks for the reminder. I did hold it back by now for a reason. I stopped adding more checks after some really critical ones, to have a chance for re-thinking the whole approach.

Meanwhile I'm determined to add a more configurable, flexible way of including additional checks defining a standard check interface (see #2897 and #7577 for details). I might even want to rework existing checks to use that interface.

And I'd like to use ordered extensions by means of the OrderedExtensionOption, or would you consider arbitrary, non-deterministic sequences of check fields an additional feature? Personally I don't think so.

06/29/11 08:04:10 changed by mitar

I think OrderedExtensionOption? is a good idea.

08/23/11 09:35:35 changed by mitar

Any progress on this? For example regex support could be used to enforce using e-mail addresses as usernames.


Add/Change #5295 ([patch] Add optional username regexp to registration checks)




Change Properties
Action