[dw-free] Verify that bad-password checking is implemented & enabled
[commit: http://hg.dwscoalition.org/dw-free/rev/bed7ce2ec73a]
http://bugs.dwscoalition.org/show_bug.cgi?id=446
Add some basic password checking.
Patch by
janinedog.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=446
Add some basic password checking.
Patch by
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Files modified:
- bin/upgrading/en.dat
- cgi-bin/LJ/CreatePage.pm
- cgi-bin/LJ/Widget/CreateAccount.pm
- cgi-bin/ljprotocol.pl
- htdocs/changepassword.bml
- htdocs/inc/common-passwords
- htdocs/stc/widgets/createaccount.css
-------------------------------------------------------------------------------- diff -r ef89676071eb -r bed7ce2ec73a bin/upgrading/en.dat --- a/bin/upgrading/en.dat Tue Mar 31 04:43:49 2009 +0000 +++ b/bin/upgrading/en.dat Tue Mar 31 04:54:38 2009 +0000 @@ -2215,8 +2215,6 @@ optional=(optional) password=Password -password.max30=Passwords may not be longer than 30 characters. - pingback.ljping.comment.text=User <lj user="[[poster]]"> referenced to your post from <a href="[[sourceURI]]">[[subject]]</a> saying: [...] [[context]] [...] pingback.option.disabled=Disabled @@ -3469,7 +3467,23 @@ widget.createaccount.error.password.bad= widget.createaccount.error.password.blank=You must enter a password. +widget.createaccount.error.password.common=Password must not be based on a common word. + +widget.createaccount.error.password.likeemail=Password must not be similar to your email address. + +widget.createaccount.error.password.likename=Password must not be similar to your displayed name. + +widget.createaccount.error.password.likeusername=Password must not be similar to your username. + +widget.createaccount.error.password.needsmoreuniquechars=Password must contain at least 4 unique characters. + +widget.createaccount.error.password.needsnonletter=Password must contain at least one non-letter character (digit or symbol). + widget.createaccount.error.password.nomatch=Passwords do not match. + +widget.createaccount.error.password.toolong=Password must not be longer than 30 characters. + +widget.createaccount.error.password.tooshort=Password must be at least 6 characters. widget.createaccount.error.username.inuse=Sorry, this username is already in use. diff -r ef89676071eb -r bed7ce2ec73a cgi-bin/LJ/CreatePage.pm --- a/cgi-bin/LJ/CreatePage.pm Tue Mar 31 04:43:49 2009 +0000 +++ b/cgi-bin/LJ/CreatePage.pm Tue Mar 31 04:54:38 2009 +0000 @@ -66,4 +66,82 @@ sub verify_username { return $error; } +sub verify_password { + my $class = shift; + my %opts = @_; + + return undef unless LJ::is_enabled( 'password_check' ); + + my ( $password, $username, $email, $name ); + my $u = $opts{u}; + if ( LJ::isu( $u ) ) { + $password = $u->password; + $username = $u->user; + $email = $u->email_raw; + $name = $u->name_raw; + } + + $password = $opts{password}; + $username = $opts{username}; + $email = $opts{email}; + $name = $opts{name}; + + # password must exist + return LJ::Widget::CreateAccount->ml( 'widget.createaccount.error.password.blank' ) + unless $password; + + # at least 6 characters + return LJ::Widget::CreateAccount->ml( 'widget.createaccount.error.password.tooshort' ) + if length $password < 6; + + # no more than 30 characters + return LJ::Widget::CreateAccount->ml( 'widget.createaccount.error.password.toolong' ) + if length $password > 30; + + # only ascii characters + return LJ::Widget::CreateAccount->ml( 'widget.createaccount.error.password.asciionly' ) + unless LJ::is_ascii( $password ); + + # not the same as the username or the reversed username + if ( $username ) { + return LJ::Widget::CreateAccount->ml( 'widget.createaccount.error.password.likeusername' ) + if lc $password eq lc $username || lc $password eq lc reverse $username; + } + + # not the same as either part of the email address + if ( $email ) { + $email =~ /^(.+)@(.+)\./; + return LJ::Widget::CreateAccount->ml( 'widget.createaccount.error.password.likeemail' ) + if lc $password eq lc $1 || lc $password eq lc $2; + } + + # not the same as the displayed name or the reversed displayed name + if ( $name ) { + return LJ::Widget::CreateAccount->ml( 'widget.createaccount.error.password.likename' ) + if lc $password eq lc $name || lc $password eq lc reverse $name; + } + + # at least 4 unique characters + my %unique_chars = map { $_ => 1 } split( //, $password ); + return LJ::Widget::CreateAccount->ml( 'widget.createaccount.error.password.needsmoreuniquechars' ) + unless scalar keys %unique_chars > 4; + + # contains at least one digit or symbol + return LJ::Widget::CreateAccount->ml( 'widget.createaccount.error.password.needsnonletter' ) + if $password =~ /^[A-Za-z]+$/; + + # isn't similar to a common password + my @common_passwords = grep { $_ } split( /\r?\n/, LJ::load_include( 'common-passwords' ) ); + foreach my $comm_pass ( $LJ::SITENAMESHORT, @common_passwords ) { + # you can have a common password in your password if your password is greater in length + # than the sum of the common password's length plus the ceiling of half of its length + next if length $password > ( ( length $comm_pass ) + POSIX::ceil( ( length $comm_pass ) / 2 ) ); + + return LJ::Widget::CreateAccount->ml( 'widget.createaccount.error.password.common' ) + if $password =~ /$comm_pass/i; + } + + return undef; +} + 1; diff -r ef89676071eb -r bed7ce2ec73a cgi-bin/LJ/Widget/CreateAccount.pm --- a/cgi-bin/LJ/Widget/CreateAccount.pm Tue Mar 31 04:43:49 2009 +0000 +++ b/cgi-bin/LJ/Widget/CreateAccount.pm Tue Mar 31 04:54:38 2009 +0000 @@ -387,27 +387,14 @@ sub handle_post { $post->{password1} = LJ::trim($post->{password1}); $post->{password2} = LJ::trim($post->{password2}); - if ($post->{password1} ne $post->{password2}) { - $from_post{errors}->{confirmpass} = $class->ml('widget.createaccount.error.password.nomatch'); + if ( !$post->{password1} ) { + $from_post{errors}->{password} = $class->ml( 'widget.createaccount.error.password.blank' ); + } elsif ( $post->{password1} ne $post->{password2} ) { + $from_post{errors}->{confirmpass} = $class->ml( 'widget.createaccount.error.password.nomatch' ); } else { - my $checkpass = LJ::run_hook("bad_password", { - user => $user, - email => $email, - password => $post->{password1}, - }); - - if ($checkpass) { - $from_post{errors}->{password} = $class->ml('widget.createaccount.error.password.bad') . " $checkpass"; - } - } - if (!$post->{password1}) { - $from_post{errors}->{password} = $class->ml('widget.createaccount.error.password.blank'); - } elsif (length $post->{password1} > 30) { - $from_post{errors}->{password} = LJ::Lang::ml('password.max30'); - } - - unless (LJ::is_ascii($post->{password1})) { - $from_post{errors}->{password} = $class->ml('widget.createaccount.error.password.asciionly'); + my $checkpass = LJ::CreatePage->verify_password( password => $post->{password1}, username => $user, email => $email ); + $from_post{errors}->{password} = $class->ml( 'widget.createaccount.error.password.bad' ) . " $checkpass" + if $checkpass; } # age checking to determine how old they are @@ -467,7 +454,7 @@ sub handle_post { $post->{'recaptcha_challenge_field'}, $post->{'recaptcha_response_field'} ); - $from_post{errors}->{captcha} = $class->ml('widget.createaccount.error.captcha.invalid') unless $result->{'is_valid'} eq '1'; + $from_post{errors}->{captcha} = $class->ml('widget.createaccount.error.captcha.invalid') unless $result->{'is_valid'} eq '1'; } else { $from_post{errors}->{captcha} = $class->ml('widget.createaccount.error.captcha.invalid'); } diff -r ef89676071eb -r bed7ce2ec73a cgi-bin/ljprotocol.pl --- a/cgi-bin/ljprotocol.pl Tue Mar 31 04:43:49 2009 +0000 +++ b/cgi-bin/ljprotocol.pl Tue Mar 31 04:54:38 2009 +0000 @@ -2514,7 +2514,7 @@ sub login_message return $msg->("not_validated") if ($u->{'status'} eq "N" and not $LJ::EVERYONE_VALID); return $msg->("must_revalidate") if ($u->{'status'} eq "T" and not $LJ::EVERYONE_VALID); - my $checkpass = LJ::run_hook("bad_password", { 'u' => $u }); + my $checkpass = LJ::CreatePage->verify_password( u => $u ); return $msg->("bad_password", { 'pre' => "$checkpass " }) if $checkpass; return $msg->("old_win32_client") if $req->{'clientversion'} =~ /^Win32-MFC\/(1.2.[0123456])$/; diff -r ef89676071eb -r bed7ce2ec73a htdocs/changepassword.bml --- a/htdocs/changepassword.bml Tue Mar 31 04:43:49 2009 +0000 +++ b/htdocs/changepassword.bml Tue Mar 31 04:54:38 2009 +0000 @@ -134,33 +134,21 @@ body<= } } } - if ($newpass1 ne $newpass2) { + + if ( !$newpass1 ) { + push @errors, $ML{'.error.blankpassword'}; + } elsif ( $newpass1 ne $newpass2 ) { push @errors, $ML{'.error.badnewpassword'}; } else { - if ($newpass1 eq "") { - push @errors, $ML{'.error.blankpassword'}; - } elsif (length $newpass1 > 30) { - push @errors, $ML{'.error.characterlimit'}; - } else { - my $checkpass = LJ::run_hook("bad_password", - { - 'u' => $u, - 'password' => $newpass1, - }); - if ($checkpass) { - push @errors, BML::ml('.error.badcheck', {'error' => $checkpass}); - } - } + my $checkpass = LJ::CreatePage->verify_password( password => $newpass1, u => $u ); + push @errors, BML::ml( '.error.badcheck', { error => $checkpass } ) + if $checkpass; } # don't allow changes if email address is not validated, unless they # have a bad password or got the reset email if ($u->{'status'} ne 'A' && !$u->prop('badpassword') && !$authu) { push @errors, $ML{'.error.notvalidated'}; - } - - unless (LJ::is_ascii($newpass1)) { - push @errors, $ML{'.error.nonascii'}; } if (@errors) { diff -r ef89676071eb -r bed7ce2ec73a htdocs/inc/common-passwords --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/htdocs/inc/common-passwords Tue Mar 31 04:54:38 2009 +0000 @@ -0,0 +1,13 @@ +password +test +blink182 +qwerty +letmein +abc123 +monkey +myspace1 +password1 +123456 +12345678 +1234 +12345 diff -r ef89676071eb -r bed7ce2ec73a htdocs/stc/widgets/createaccount.css --- a/htdocs/stc/widgets/createaccount.css Tue Mar 31 04:43:49 2009 +0000 +++ b/htdocs/stc/widgets/createaccount.css Tue Mar 31 04:54:38 2009 +0000 @@ -57,4 +57,6 @@ span.appwidget-createaccount #username_e .create-form span.formitemFlag { display: block; width: 330px; + font-weight: bold; + color: #f00; } --------------------------------------------------------------------------------