Opened 15 years ago
Closed 12 years ago
#5295 closed enhancement (fixed)
[patch] Add optional username regexp to registration checks
Reported by: | Sebastian Krysmanski | Owned by: | Steffen Hoffmann |
---|---|---|---|
Priority: | normal | Component: | AccountManagerPlugin |
Severity: | normal | Keywords: | security precaution user register name check regexp |
Cc: | Thijs Triemstra, felix.schwarz@…, Ryan J Ollos, Olemis Lang, Adrian Fritz, Mitar | 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 (3)
Change History (48)
comment:1 Changed 15 years ago by
Changed 15 years ago by
Attachment: | check_username_fix.patch added |
---|
Patch against r5836 and Trac 0.11.4
comment:2 Changed 15 years ago by
A workaround for this problem is:
- disable the registration module
- or create users for all permission groups in the password store
comment:3 follow-up: 5 Changed 15 years ago by
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.
comment:4 follow-up: 6 Changed 15 years ago by
Also, this is at best a nuisance, you cannot gain permissions you shouldn't otherwise have.
comment:5 Changed 15 years ago by
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.
comment:6 follow-up: 7 Changed 15 years ago by
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).
comment:7 follow-up: 8 Changed 15 years ago by
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".
comment:8 follow-up: 9 Changed 15 years ago by
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.
comment:9 Changed 15 years ago by
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 errorHowever, 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.
comment:10 Changed 15 years ago by
Cc: | Thijs Triemstra added; anonymous removed |
---|
So is there a security hole in this plugin or not?
comment:11 follow-up: 12 Changed 15 years ago by
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.
comment:12 Changed 15 years ago by
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.
comment:13 Changed 15 years ago by
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).
comment:14 Changed 15 years ago by
Cc: | felix.schwarz@… added |
---|
comment:15 Changed 15 years ago by
Cc: | Ryan J Ollos added |
---|
comment:16 Changed 15 years ago by
Cc: | Olemis Lang added |
---|
comment:17 Changed 15 years ago by
Cc: | Adrian Fritz added |
---|
comment:18 Changed 15 years ago by
Summary: | Registration module is a potential security hole → [Patch & WorkArround] Registration module is a potential security hole |
---|
comment:19 follow-up: 20 Changed 15 years ago by
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.
comment:20 Changed 15 years ago by
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.
comment:21 Changed 14 years ago by
Keywords: | security precaution delete added |
---|
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.
comment:22 Changed 14 years ago by
#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.
comment:23 Changed 14 years ago by
(In [9247]) AccountManagerPlugin: Fix a small Python doc-string typo, refs #5295.
comment:24 Changed 14 years ago by
(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.
comment:25 Changed 14 years ago by
Keywords: | user register name check regexp added; delete removed |
---|---|
Owner: | changed from John Hampton to Steffen Hoffmann |
Priority: | highest → normal |
Severity: | critical → normal |
Status: | new → assigned |
Summary: | [Patch & WorkArround] Registration module is a potential security hole → [patch] Add Registration module is a potential security hole |
Type: | defect → 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.
comment:26 Changed 14 years ago by
Summary: | [patch] Add Registration module is a potential security hole → [patch] Add optional username regexp to registration checks |
---|
Finishing the previously started changes.
comment:27 Changed 14 years ago by
Cc: | Mitar added |
---|
I am using following patch for some time now and it works great.
Changed 14 years ago by
Attachment: | ticket-5295.patch added |
---|
comment:28 Changed 14 years ago by
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.
comment:29 Changed 14 years ago by
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.
comment:30 Changed 14 years ago by
See #8076 for some more proposed regexp to check for a valid email too.
comment:31 follow-up: 32 Changed 14 years ago by
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).
comment:32 Changed 14 years ago by
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.
comment:33 Changed 13 years ago by
Could this be included into the core? This is one of two patches I am using in my Debian package.
comment:34 Changed 13 years ago by
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.
comment:36 follow-up: 37 Changed 13 years ago by
Any progress on this? For example regex support could be used to enforce using e-mail addresses as usernames.
comment:37 Changed 12 years ago by
Replying to mitar:
Any progress on this? For example regex support could be used to enforce using e-mail addresses as usernames.
Finally, yes, I've made this a part of current t-h.o migration planning.
comment:38 Changed 12 years ago by
(In [11829]) AccountManagerPlugin: Allow for optional case-less username duplicate checking, refs #5295.
Option username_dup_case
enables more thoroughly testing for a username
duplicate when validating new usernames.
This is the implementation of an idea, how to improve user registration checks at trac-hacks.org, mentioned by Ryan Ollos.
comment:39 Changed 12 years ago by
(In [11839]) AccountManagerPlugin: Make case-less username duplicate checking mandatory, refs #5295.
The longer I thought about it, the more I've been convinced, that a username
differing only by character case is spelling trouble for any environment.
I remembered having such problems when switching ignore_auth_case
to True
for a Trac instance some time ago and couldn't think of a use-case anyway,
so I made case-less checks mandatory.
Even better, pulling the obsoleted new option now is fighting feature bloat: With 25+ options AccountManager is not exactly easy to configure, so every dispensed option is a blessing.
Additionally I hope, that a highlighted username improves error messages.
comment:40 follow-up: 43 Changed 12 years ago by
Yes. I don't like how ignore_auth_case
works in Trac, where it forces lower case. ignore_auth_case
should still be case preserving. Just that it does not matter the case when authenticating.
I think this should be how account manager should also behave. Everything else is just a problem waiting to happen.
Also Trac permission system, which sees groups and users as same, so if some user register with an username same as a group name ...
It is not just enough to prevent registration in this case. Because for example, in one my case, I have external authentication source. And that source do not have access to Trac groups to be able to prevent registration. So I just hope nobody will notice that.
There should be some better system solution to this.
comment:41 Changed 12 years ago by
(In [11917]) AccountManagerPlugin: Add interface for configurable user registration procedure, refs #874, #2707, #2897, #4651, #5295, #7577, #8076.
The current user registration process lacks flexibility, as can be witnessed by the history of one of the oldest still pending tickets for this plugin: #874.
comment:42 Changed 12 years ago by
(In [11923]) AccountManagerPlugin: Finish registration check rewrite, refs #874, #2707, #2897, #4651, #5295, #7577, #8076.
Now moving check execution into AccountManager, and _create_user()
is gone,
replaced by more clearly structured and modularized code.
Registration checking for requests from the admin panel is re-activated and minor improvements related to RegistrationError processing done too.
Note: The test, that detected admin requests to skip additional checking of
existing permissions for each new username, has been done differently.
In the future each check has to decide on its own, like this is done in the
UsernamePermCheck
now.
comment:43 Changed 12 years ago by
Replying to mitar:
Yes. I don't like how
ignore_auth_case
works in Trac, where it forces lower case.ignore_auth_case
should still be case preserving. Just that it does not matter the case when authenticating.
While I see your point, this would be exceptionally cumbersome in reality, because IPasswordStore
s are not at all designed to guess the username in any way. So we would need to harvest - potentially multiple - store(s) for all available users on every authentication request/login, just to be able to pass the password to every candidate. Do you think this wont be critical performance-wise?
comment:44 Changed 12 years ago by
(In [11960]) AccountManagerPlugin: Add configurable regular expression registration checks, refs #5295 and #8076.
Credits
- for the email check part: suggested and drafted by T. Christ
- for the username check part:
- suggested and darfted by Sebastian Krysmanski
- further developed by M. Mitar
Thank you all for inspiring contributions.
I release this in the hope, that it's gonna get better than just the sum
of the single patches. Surely it will, because we're using flexibility
provided by the IAccountRegistrationInspector
interface now.
And while case-insensitive matching was deemed preferable this is no longer
hard-coded but added to Python regexp by prepending (?i)
, so you've really
full control over your new configurable regexp-driven checks.
And now README.update has caught up with recent changes and new features too.
comment:45 Changed 12 years ago by
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
(In [12398]) AccountManagerPlugin: Releasing version 0.4, pushing development to acct_mgr-0.5dev.
Availability of that code as stable release closes #874, #3459, #4677, #5295, #5691, #6616, #7577, #8076, #8685, #8770, #8791, #8990, #9052, #9079, #9090, #9139, #9246, #9252, #9547, #9618, #9676, #9843, #9852, #9940, #10023, #10028, #10123, #10142, #10204, #10276, #10397, #10412, #10594, #10625 and #10644.
Some more issues have been worked-on, yet without confirmed resolution,
refs #5464 (for JiraToTracIntegration
), #8927 and #10134.
And finally there are some issues and enhancement requests showing progress, but known to require more work to resolve them satisfactorily, refs #843, #1600, #5964, #8217, #8933.
Thanks to all contributors and followers, that enabled and encouraged a good portion of this development work.
As you can see I (manski) have already register as "authenticated". I've only done this to protect this Trac environment.