Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
The current code for user_validate_name()
still uses ereg()
and eregi()
and the unit test for it is a bit bulky, so I decided to clean it up a little.
I ran into this piece of code:
if (strpos($name, '@') !== FALSE && !eregi('@([0-9a-z](-?[0-9a-z])*.)+[a-z]{2}([zmuvtg]|fo|me)?$', $name)) {
return t('The username is not a valid authentication ID.');
}
Which checks for a valid domain if the username contains a '@'.
What's the purpose of this piece of code? If it checks for a valid OpenID, it will fail miserably because OpenID's may contain more characters than Drupal allows at the 'user' part.
So, my question is: can this check be dropped from user_validate_name()
? Or must we create a separate check for such user names?
Comment | File | Size | Author |
---|---|---|---|
#60 | fix-user_validate_name.patch | 1.55 KB | jbrown |
#58 | user_validate_name-dont-require.patch | 601 bytes | jbrown |
#55 | user-strlen.patch | 563 bytes | lyricnz |
#53 | user_validate-D6.patch | 2.7 KB | Gábor Hojtsy |
#52 | user_validate-D6.patch | 2.74 KB | sbandyopadhyay |
Comments
Comment #1
Damien Tournoud CreditAttribution: Damien Tournoud commentedI don't pretend to understand that strange regexp, but it seems that there is no need to validate the server part because the authentication scheme don't use that anymore (it was used for Drupal Distributed Authentication, which is deprecated in favor of OpenID).
So feel free to drop that part.
One remark about the patch: the
strlen()
there should be adrupal_strlen()
, because we are in an unicode context.Comment #2
MrHaroldA CreditAttribution: MrHaroldA commentedOne remark about the patch: the strlen() there should be a drupal_strlen(), because we are in an unicode context.
I was just about to comment on this ;)
Also the test cases have to be expanded with a lot more weirdo chars like
chr(0)
orchr(128)
and various weirdo UTF8 chars, etc (quoting chx).Comment #3
Damien Tournoud CreditAttribution: Damien Tournoud commentedand various weirdo UTF8 chars... or even invalid UTF8 characters for that matter.
Comment #4
MrHaroldA CreditAttribution: MrHaroldA commentedI've attached a patch that removes the 'authentication ID' check and replaces all remaining all
ereg()s
withpreg_match()
. I've also added a check on control characters.I'm still not sure how to handle
'foo' . chr(128) . 'bar'
and if it's allowed in usernames... This is a handy table for those pesky 128(+) chars...Suggestions?
Comment #5
catchPatch is goods so far.
I'm wondering if we could incorporate allowing apostrophes into this cleanup, since it's currently just an omission. Patch and discussion here: http://drupal.org/node/165226
Comment #6
MrHaroldA CreditAttribution: MrHaroldA commentedI've added apostrophe support(+test) and a small change in
check_plain()
as proposed in http://drupal.org/node/165226 in the new version of the patch.I've chosen to use
ENT_COMPAT
(Will convert double-quotes and leave single-quotes alone (default)) instead ofENT_NOQUOTES
(Will leave both double and single quotes unconverted) because we still don't allow double quotes...Comment #7
Damien Tournoud CreditAttribution: Damien Tournoud commentedI don't understand at all why we are not using ENT_NOQUOTES in
check_plain()
?It looks like this sort of things should not even be required. I guess some part of the code may call
check_plain()
two times, and it fails because that function is not reentrant.Comment #8
MrHaroldA CreditAttribution: MrHaroldA commentedAttached a patch with
ENT_NOQUOTES
.This goes well beyond my knowledge of Drupal so I can't predict the impact of it...
Comment #9
catchWorks for me. Will leave it at needs review for a second set of eyes but I think this is ready. Side note, patch isn't rolled from root of the Drupal directory, it's easier to apply that way.
Comment #10
MrHaroldA CreditAttribution: MrHaroldA commentedI've used this command in the root of my D7 installation:
harold@pi:/var/www/d7$ cvs diff -up modules/user includes > /var/www/user.patch
as explained in http://drupal.org/patch/createWhat am I doing wrong?
Comment #11
Damien Tournoud CreditAttribution: Damien Tournoud commented@MadHarold, the patch is perfectly rolled from the root directory, there is nothing wrong about it.
Comment #12
catchwhoops. Nothing wrong. user_100.patch wasn't rolled from root (or at least was prompting me for filenames), user_101.patch is completely fine. Sorry for the noise :(
Comment #13
NaheemSays CreditAttribution: NaheemSays commentedTesting the patch in #8:
Applied the patch to todays dev tarball - applies cleanly.
created a number of accounts - those with or without apostrophe are created correctly. Those with quotation marks (") give an error of an illegal character.
All that is left is for a "policy decision" - either patch is comment or comment comment 8 should go in.
Moved to RTBC as I am the second pair of eyes as requested by Catch.
Comment #14
Dries CreditAttribution: Dries commentedI've asked the security team to have a quick at this patch as well.
Comment #15
pwolanin CreditAttribution: pwolanin commentedWell, there are some XSS vectors that succeed due to injected quotes closing an img path or attribute, so I'm not that comfortable with this. Clearly check_plain() should not be called multiple time on the same text - but that's a separate issue.
Comment #16
Heine CreditAttribution: Heine commentedUsing ENT_NOQUOTES allows values to 'run out' of attribute values:
Consider:
Now, suppose $somevalue is 'foo" onerror="javascript:evil_js()" '
You'll get:
Comment #17
NaheemSays CreditAttribution: NaheemSays commentedWould this analysis also apply for the original (otherwise almost identical) patch in comment 6 that uses ENT_COMPAT instead of ENT_NOQUOTES?
Comment #18
Heine CreditAttribution: Heine commentedIn HTML 4, attributes may be delimited by either single or double quotes. Single quotes may be used unencoded in attribute values when the value is surrounded by double quotes and vv. As check_plain has no information about which quotes are used to embed something we need to play it safe and cater to both delimiters.
Comment #19
Heine CreditAttribution: Heine commentedOr in clear words; check_plain should not be modified.
Comment #20
NaheemSays CreditAttribution: NaheemSays commentedIs there another sane approach that can be used to allow apostrophes in usernames?
(this issue does not deal directly with that issue, the the failed segments of the patch are those that have been imported from the other issue mentioned in comments 5 and 6.)
Comment #21
Heine CreditAttribution: Heine commentedOf course there is. Investigate the causes of double encoding and fix them.
For instance: blog_link escapes the username
Then theme_links escapes the title and attributes again (in l()):
Comment #22
NaheemSays CreditAttribution: NaheemSays commentedI assume this patch is still useful without changing things to ENT_NOQUOTES, or to ENT_COMPAT, as they were added later on to the patch.
Attached patch is the same as above, but I have manually removed the bit for changing the ENT_QUOTES bit. I have kept in the bit allowing apostrophe's. I say let's assume the places where they do not work properly are bugs (they do work in most places).
Comment #23
Damien Tournoud CreditAttribution: Damien Tournoud commentedThe patch in #22 can go in this way. Making check_plain() reentrant will require a new issue.
Comment #24
Damien Tournoud CreditAttribution: Damien Tournoud commentedI introduced a discussion about making check_plain() reentrant in #275308.
Comment #25
Dries CreditAttribution: Dries commentedCommitted to CVS HEAD. Thanks.
Comment #26
NaheemSays CreditAttribution: NaheemSays commentedComment #27
Damien Tournoud CreditAttribution: Damien Tournoud commentedSome tests are failing. Please keep that issue open on 7.x so we can figured out why.
Comment #28
Damien Tournoud CreditAttribution: Damien Tournoud commentedDries: Looks like an incomplete version of the patch was committed. Only the user.test hunks were committed, not the user.module ones.
Comment #29
Damien Tournoud CreditAttribution: Damien Tournoud commentedBumping to critical by convention (tests are failing...).
Comment #30
Damien Tournoud CreditAttribution: Damien Tournoud commentedWhile we are at it, here is the user.module hunk plus some small cleanups for the new username validation tests, that make test descriptions cleaner and remove a spurious '%s' in the test description.
Comment #31
catchLooks good, works good too.
Comment #32
Dries CreditAttribution: Dries commentedCommitted to CVS HEAD. Thanks Damien, and sorry for messing up.
Comment #33
Damien Tournoud CreditAttribution: Damien Tournoud commentedOk, let's consider inclusion in the Drupal 6.x branch.
Comment #34
Freso CreditAttribution: Freso commentedHere's a port. I've excluded the user.test bit, as well as other things that actually changed functionality and/or strings.
Comment #35
webchickWhy can't we just trim() username? I realize this is already in the 7.x version; I didn't get a chance to review that patch before it was committed. It also shouldn't be a tab character or any other whitespace. trim() takes care of that.
Comment #36
NaheemSays CreditAttribution: NaheemSays commentedFollowup issue for fixing instances of the username being check_plain'ed twice:
http://drupal.org/node/276174
Comment #37
NaheemSays CreditAttribution: NaheemSays commentedPatch in comment 34 applies cleanly, works as expected and is a port of what is in HEAD so setting to RTBC
As for comment 35, I would guess the proper place to trim would be upon input - before the validation function.
Comment #38
Damien Tournoud CreditAttribution: Damien Tournoud commentedWhile I completely agree with Angie's comment in #35, this is another issue.
However, two hunks were excluded from the patch in #34, that we should consider including again:
I'm putting on review the opportunity to add those back in.
Comment #39
NaheemSays CreditAttribution: NaheemSays commentedI have re-ported the patch from comment 30 - without any functional changes that were introduced to the port to drupal 6 in comment 34.
Comment #40
Freso CreditAttribution: Freso commented@nbz: You're implementing a new feature though: allowing apostrophes.
Drupal 6 is in feature and string freeze both. The patch in #34 didn't change alter or add or remove any feature, even if #38 thinks it should contain more of the 7.x code. I'm still not sure about this though, as it will change the behaviour. So I'm leaving it for Gábor/Dries to decide on how much of it should be back ported.
Comment #41
Heine CreditAttribution: Heine commentedNot supporting a single quote in a username is a bug, not a lacking feature.
Comment #42
NaheemSays CreditAttribution: NaheemSays commented@ #40 - I see where you are coming from, but from the mailing lists it seems Drupal 6 may get an extended life cycle (by virtue of delaying Drupal 7 code freeze date), and IMO allowing apostrophe's is a vital functionality, the lack of which bordering close to being a bug.
Not having explicit approval (yet) from Dries or Gabor for this additional functionality should not be a blocker for RTBC status. IMO the code review should be to make sure that it all works as expected without any caveats. nce the patch has been set RTBC, the branch maintainer can make up his mind about whether this should be allowed or not.
EDIT - not having this feature in core means that me (and potentially others who have migrated users from other systems that allow apostrophes) will run a patched core install, which may have security vulnerabilities. That should be considered a bug, not in the released software, but procedure.
Comment #43
NaheemSays CreditAttribution: NaheemSays commentedWe have two patches here - comment 34 without the changes allowing apostrophes in usernames, and comment 39 with the changes allowing apostrophes.
Can somebody please review (and maybe help in the other issue (#276174: Do not check_plain() usernames more than once) too so that I can find out exactly where the other checkplain takes place)?
Once both of these patches are RTBC, the maintainer can decide if he wished to allow or not allow this bug fixing functionality.
Comment #44
Freso CreditAttribution: Freso commentedPatch in comment #34 (without new features and string change) was RTBC'd (in comment 37), so we're just short of a review of the patch in comment #39 (adding features and changing a string) before we can let Gábor-Dries decide on what to go with.
Comment #45
NaheemSays CreditAttribution: NaheemSays commentedPatch in comment 39 still works, but with an offset of 14 lines in hunk 3. Should I reroll?
(and is some kind soul willing to review?)
Comment #46
jcruz CreditAttribution: jcruz commentedsubscribe
Comment #47
NaheemSays CreditAttribution: NaheemSays commentedupdated patch from comment 39 - I just removed hunk three as all that did was change a string to inform that apostrophes are allowed.
In this patch, apostrophes are still allowed, but that is now "by stealth" so as not to break string freeze.
(This will need to be applied at the same time as #276174: Do not check_plain() usernames more than once to fix the theming errors for usernames in blog.module.)
Comment #48
Sophia CreditAttribution: Sophia commentedSubscribe... we have lots of members imported from phpBB with an ' in their username. Would be lovely if that worked for them :)
Comment #49
NaheemSays CreditAttribution: NaheemSays commentedPatch in comment 47 still applies, but with an offset of 2 lines.
For those subscribing - it would be helpful if the patch was reviewed and set to rtbc if its working as expected.
Comment #50
Sophia CreditAttribution: Sophia commentedWell, we have been testing it for half a year now, and it works perfectly. How can I set it to rtbc? It works flawlessly... and we are about to patch the updated core again. Personally I think it is ready to be implemented :)
Comment #51
NaheemSays CreditAttribution: NaheemSays commented"How can I set it to rtbc"
you just choose the option. At that stage, the maintainer of the Drupal 6 branch can then agree or disagree with the change. til then it is nothing and will not be committed even if the maintainer likes it.
I have also been using this patch for a long time too and think it is ready, but since I rolled it, made some changes etc... it would not be good for me toset it to rtbc.
fwiw, the last version does not break any strings - it just adds the feature "silently" and this will be compatible with Drupal 7 since that already has the patch.
Comment #52
sbandyopadhyay CreditAttribution: sbandyopadhyay commentedThis issue has been floating around now for nearly two years.
user_validate_name in D7 has been fixed for more than 21 months already.
The backport to D6 has been around for 18 months. It's been tested fairly extensively as the last few posts show, and I've just re-checked it myself as well. As such, I'm marking RTBC.
Let's try to get it into the next D6 update, especially since this patch also fixes #526590: user_validate_name not allowing military email addresses as username. As noted there, a username that happens to be a military email address causes an outright rejection -- that's a pretty shocking bug at this point, so I'm also marking this as critical.
And finally, I'm re-rolling the same patch in #47 to help speed things along.
Let's get this done, please.
Comment #53
Gábor HojtsyGreat, thanks for all the testing, committed the patch with one small change. Left the initial strlen() intact (with the code style changes applied). The version in the patch did not allow for username "0" (the number zero) which is otherwise allowed before the patch. I'd suggest porting this change back to D7 as not to break backwards compatibility with D6 userbases.
Comment #54
lyricnz CreditAttribution: lyricnz commentedWhen $user->name == "0", this causes problems elsewhere (which we could fix, of course - but I'd like some consensus on whether this should be a valid user name before going in either direction).
#845472: Robustly determine when strings are empty
Comment #55
lyricnz CreditAttribution: lyricnz commentedOkay, I've asked around, and the general consensus seems to be that "0" should be a valid username. That being the case, here's a patch against D7 that implements the same check as D6 has. I'll deal with the impact of this in #845472 (for both D7 and D6).
Comment #57
kscheirer-1 to patch in #55.
I'm in favor of not allowing 0 as a name and giving one less edge case to contrib authors to worry about. Core doesn't even handle this properly yet (#845472: Robustly determine when strings are empty), acknowledging we don't support this case is the easiest solution.
I know, technically, we could. Is it worth the pain to patch things in core and contrib to support this? Is there any site that actually wants a user named 0?
Comment #58
jbrown CreditAttribution: jbrown commentedHere is what D7 does at the moment:
Enter nothing in the Username field and you get 'Password field is required.'.
The only way to get the 'You must enter a username.' string (from user_validate_name() ) is to enter a 0 in the Username field.
The forms layer is already validating that a string has been entered. user_validate_name() is attempting to repeat this logic and screwing it up.
The 'required' check should just be removed from user_validate_name().
'0' is a perfectly valid string. We shouldn't let the failings of PHP dictate what is and what isn't a valid username.
See also http://drupal.org/node/845472#comment-3276796
Comment #60
jbrown CreditAttribution: jbrown commentedIt seems that user_validate_name() is tested directly, instead of through the form.
Updated patch fixes the empty check in user_validate_name() and sets the username form item to validated so that user_validate_name() can report the error the way it wants.
Comment #61
lyricnz CreditAttribution: lyricnz commentedLooks fine
Comment #62
sunheh, that's a giant hack :)
If it's just for getting around the default #required error message, then postpone this change on #742344: Allow forms to set custom validation error messages on required fields.
Actually, #required should already handle exactly the case for that empty username, so I'm not sure why this code contains custom validation for the very same empty condition at all.
But again, if it's just to have a fancier validation error message, then aforementioned issue is required for this patch.
Powered by Dreditor.
Comment #63
jbrown CreditAttribution: jbrown commentedI think the idea is that user_validate_name() should be the authority on what is a valid username. This function is tested directly, not through the form.
See #58
Comment #64
sunReading through the entire issue, now I understand where you're coming from.
Comment #65
jbrown CreditAttribution: jbrown commentedAgreed on all points!