Attachment #506031: Patch for 3.6.3 for bug #621591

View | Details | Raw Unified | Return to bug 621591
Collapse All | Expand All

(-)Bugzilla/Install/Localconfig.pm (-2 / +11 lines)
Line     Link Here 
 Lines 205-211    Link Here 
205
    },
205
    },
206
    {
206
    {
207
        name    => 'site_wide_secret',
207
        name    => 'site_wide_secret',
208
        default => sub { generate_random_password(256) },
208
        # 64 characters is roughly the equivalent of a 384-bit key, which
209
        # is larger than anybody would ever be able to brute-force.
210
        default => sub { generate_random_password(64) },
209
        desc    => <<EOT
211
        desc    => <<EOT
210
# This secret key is used by your installation for the creation and
212
# This secret key is used by your installation for the creation and
211
# validation of encrypted tokens to prevent unsolicited changes,
213
# validation of encrypted tokens to prevent unsolicited changes,
 Lines 323-329    Link Here 
323
    my @new_vars;
325
    my @new_vars;
324
    foreach my $var (LOCALCONFIG_VARS) {
326
    foreach my $var (LOCALCONFIG_VARS) {
325
        my $name = $var->{name};
327
        my $name = $var->{name};
326
        if (!defined $localconfig->{$name}) {
328
        my $value = $localconfig->{$name};
329
        # Regenerate site_wide_secret if it was made by our old, weak
330
        # generate_random_password. Previously we used to generate
331
        # a 256-character string for site_wide_secret.
332
        $value = undef if ($name eq 'site_wide_secret' and defined $value
333
                           and length($value) == 256);
334
        
335
        if (!defined $value) {
327
            push(@new_vars, $name);
336
            push(@new_vars, $name);
328
            $var->{default} = &{$var->{default}} if ref($var->{default}) eq 'CODE';
337
            $var->{default} = &{$var->{default}} if ref($var->{default}) eq 'CODE';
329
            if (exists $answer->{$name}) {
338
            if (exists $answer->{$name}) {
(-)Bugzilla/Install/Requirements.pm (+6 lines)
Line     Link Here 
 Lines 288-293    Link Here 
288
        version => '1.999022',
288
        version => '1.999022',
289
        feature => ['mod_perl'],
289
        feature => ['mod_perl'],
290
    },
290
    },
291
    {
292
        package => 'Math-Random-Secure',
293
        module  => 'Math::Random::Secure',
294
        version => '0.05',
295
        feature => ['rand_security'],
296
    },
291
    );
297
    );
292
298
293
    my $extra_modules = _get_extension_requirements('OPTIONAL_MODULES');
299
    my $extra_modules = _get_extension_requirements('OPTIONAL_MODULES');
(-)Bugzilla/Util.pm (-1 / +48 lines)
Line     Link Here 
 Lines 551-559    Link Here 
551
    return $crypted_password;
551
    return $crypted_password;
552
}
552
}
553
553
554
# If you want to understand the security of strings generated by this
555
# function, here's a quick formula that will help you estimate:
556
# We pick from 62 characters, which is close to 64, which is 2^6.
557
# So 8 characters is (2^6)^8 == 2^48 combinations. Just multiply 6
558
# by the number of characters you generate, and that gets you the equivalent
559
# strength of the string in bits.
554
sub generate_random_password {
560
sub generate_random_password {
555
    my $size = shift || 10; # default to 10 chars if nothing specified
561
    my $size = shift || 10; # default to 10 chars if nothing specified
556
    return join("", map{ ('0'..'9','a'..'z','A'..'Z')[rand 62] } (1..$size));
562
    my $rand;
563
    if (Bugzilla->feature('rand_security')) {
564
        $rand = \&Math::Random::Secure::irand;
565
    }
566
    else {
567
        # For details on why this block works the way it does, see bug 619594.
568
        # (Note that we don't do this if Math::Random::Secure is installed,
569
        # because we don't need to.)
570
        my $counter = 0;
571
        $rand = sub {
572
            # If we regenerate the seed every 5 characters, our seed is roughly
573
            # as strong (in terms of bit size) as our randomly-generated
574
            # string itself.
575
            _do_srand() if ($counter % 5) == 0;
576
            $counter++;
577
            return int(rand $_[0]);
578
        };
579
    }
580
    return join("", map{ ('0'..'9','a'..'z','A'..'Z')[$rand->(62)] } 
581
                       (1..$size));
582
}
583
584
sub _do_srand {
585
    # On Windows, calling srand over and over in the same process produces
586
    # very bad results. We need a stronger seed.
587
    if (ON_WINDOWS) {
588
        require Win32;
589
        # GuidGen generates random data via Windows's CryptGenRandom
590
        # interface, which is documented as being cryptographically secure.
591
        my $guid = Win32::GuidGen();
592
        # GUIDs look like:
593
        # {09531CF1-D0C7-4860-840C-1C8C8735E2AD}
594
        $guid =~ s/[-{}]+//g;
595
        # Get a 32-bit integer using the first eight hex digits.
596
        my $seed = hex(substr($guid, 0, 8));
597
        srand($seed);
598
        return;
599
    }
600
601
    # On *nix-like platforms, this uses /dev/urandom, so the seed changes
602
    # enough on every invocation.
603
    srand();
557
}
604
}
558
605
559
sub validate_email_syntax {
606
sub validate_email_syntax {
(-)mod_perl.pl (-2 / +11 lines)
Line     Link Here 
 Lines 46-51    Link Here 
46
use Bugzilla::Template ();
46
use Bugzilla::Template ();
47
use Bugzilla::Util ();
47
use Bugzilla::Util ();
48
48
49
# For PerlChildInitHandler
50
eval { require Math::Random::Secure };
51
49
my ($sizelimit, $maxrequests) = ('', '');
52
my ($sizelimit, $maxrequests) = ('', '');
50
if (Bugzilla::Constants::ON_WINDOWS) {
53
if (Bugzilla::Constants::ON_WINDOWS) {
51
    $maxrequests = "MaxRequestsPerChild 25";
54
    $maxrequests = "MaxRequestsPerChild 25";
 Lines 64-71    Link Here 
64
my $server = Apache2::ServerUtil->server;
67
my $server = Apache2::ServerUtil->server;
65
my $conf = <<EOT;
68
my $conf = <<EOT;
66
$maxrequests
69
$maxrequests
67
# Make sure each httpd child receives a different random seed (bug 476622)
70
# Make sure each httpd child receives a different random seed (bug 476622).
68
PerlChildInitHandler "sub { srand(); }"
71
# Math::Random::Secure has one srand that needs to be called for
72
# every process, and Perl has another. (Various Perl modules still use
73
# the built-in rand(), even though we only use Math::Random::Secure in
74
# Bugzilla itself, so we need to srand() both of them.) However, 
75
# Math::Random::Secure may not be installed, so we call its srand in an
76
# eval.
77
PerlChildInitHandler "sub { eval { Math::Random::Secure::srand() }; srand(); }"
69
<Directory "$cgi_path">
78
<Directory "$cgi_path">
70
    AddHandler perl-script .cgi
79
    AddHandler perl-script .cgi
71
    # No need to PerlModule these because they're already defined in mod_perl.pl
80
    # No need to PerlModule these because they're already defined in mod_perl.pl
(-)template/en/default/setup/strings.txt.pl (+1 lines)
Line     Link Here 
 Lines 62-67    Link Here 
62
    feature_mod_perl          => 'mod_perl',
62
    feature_mod_perl          => 'mod_perl',
63
    feature_moving            => 'Move Bugs Between Installations',
63
    feature_moving            => 'Move Bugs Between Installations',
64
    feature_patch_viewer      => 'Patch Viewer',
64
    feature_patch_viewer      => 'Patch Viewer',
65
    feature_rand_security     => 'Improve cookie and token security',
65
    feature_smtp_auth         => 'SMTP Authentication',
66
    feature_smtp_auth         => 'SMTP Authentication',
66
    feature_updates           => 'Automatic Update Notifications',
67
    feature_updates           => 'Automatic Update Notifications',
67
    feature_xmlrpc            => 'XML-RPC Interface',
68
    feature_xmlrpc            => 'XML-RPC Interface',

Return to bug 621591