]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 314871: (CVE-2009-3989) [SECURITY] Prevent web browsers from seeing CVS/, contrib...
authorMax Kanat-Alexander <mkanat@bugzilla.org>
Mon, 1 Feb 2010 21:25:52 +0000 (13:25 -0800)
committerMax Kanat-Alexander <mkanat@bugzilla.org>
Mon, 1 Feb 2010 21:25:52 +0000 (13:25 -0800)
Patch by Max Kanat-Alexander <mkanat@bugzilla.org> r=LpSolit, a=mkanat

Bugzilla/Install/Filesystem.pm

index 31b0a27762b356fc05d65f180e635152ba161e17..ce9c05f7104130475f2398ef3d28a9338dd02d87 100644 (file)
@@ -45,6 +45,12 @@ our @EXPORT = qw(
     fix_all_file_permissions
 );
 
+use constant HT_DEFAULT_DENY => <<EOT;
+# nothing in this directory is retrievable unless overridden by an .htaccess
+# in a subdirectory
+deny from all
+EOT
+
 # This looks like a constant because it effectively is, but
 # it has to call other subroutines and read the current filesystem,
 # so it's defined as a sub. This is not exported, so it doesn't have
@@ -113,6 +119,8 @@ sub FILESYSTEM {
         'customfield.pl'  => { perms => $owner_executable },
         'email_in.pl'     => { perms => $ws_executable },
 
+        'contrib/README'     => { perms => $owner_readable },
+        'contrib/*/README'   => { perms => $owner_readable },
         'docs/makedocs.pl'   => { perms => $owner_executable },
         'docs/rel_notes.txt' => { perms => $ws_readable },
         'docs/README.docs'   => { perms => $owner_readable },
@@ -177,6 +185,8 @@ sub FILESYSTEM {
                                      dirs => $owner_dir_readable },
          'docs/xml'            => { files => $owner_readable,
                                      dirs => $owner_dir_readable },
+         'contrib'             => { files => $owner_executable,
+                                     dirs => $owner_dir_readable, },
     );
 
     # --- FILES TO CREATE --- #
@@ -241,19 +251,17 @@ EOT
     # Because checksetup controls the .htaccess creation separately
     # by a localconfig variable, these go in a separate variable from
     # %create_files.
-    my $ht_default_deny = <<EOT;
-# nothing in this directory is retrievable unless overridden by an .htaccess
-# in a subdirectory
-deny from all
-EOT
-
     my %htaccess = (
         "$attachdir/.htaccess"       => { perms    => $ws_readable,
-                                          contents => $ht_default_deny },
+                                          contents => HT_DEFAULT_DENY },
         "$libdir/Bugzilla/.htaccess" => { perms    => $ws_readable,
-                                          contents => $ht_default_deny },
+                                          contents => HT_DEFAULT_DENY },
         "$templatedir/.htaccess"     => { perms    => $ws_readable,
-                                          contents => $ht_default_deny },
+                                          contents => HT_DEFAULT_DENY },
+        'contrib/.htaccess'          => { perms    => $ws_readable,
+                                          contents => HT_DEFAULT_DENY },
+        't/.htaccess'                => { perms    => $ws_readable,
+                                          contents => HT_DEFAULT_DENY },
 
         '.htaccess' => { perms => $ws_readable, contents => <<EOT
 # Don't allow people to retrieve non-cgi executable files or our private data
@@ -534,22 +542,13 @@ sub fix_all_file_permissions {
         _fix_perms($dir, $owner_id, $group_id, $dirs{$dir});
     }
 
-    foreach my $dir (sort keys %recurse_dirs) {
-        next unless -d $dir;
-        # Set permissions on the directory itself.
-        my $perms = $recurse_dirs{$dir};
-        _fix_perms($dir, $owner_id, $group_id, $perms->{dirs});
-        # Now recurse through the directory and set the correct permissions
-        # on subdirectories and files.
-        find({ no_chdir => 1, wanted => sub {
-            my $name = $File::Find::name;
-            if (-d $name) {
-                _fix_perms($name, $owner_id, $group_id, $perms->{dirs});
-            }
-            else {
-                _fix_perms($name, $owner_id, $group_id, $perms->{files});
-            }
-        }}, $dir);
+    foreach my $pattern (sort keys %recurse_dirs) {
+        my $perms = $recurse_dirs{$pattern};
+        # %recurse_dirs supports globs
+        foreach my $dir (glob $pattern) {
+            next unless -d $dir;
+            _fix_perms_recursively($dir, $owner_id, $group_id, $perms);
+        }
     }
 
     foreach my $file (sort keys %files) {
@@ -572,8 +571,13 @@ sub _fix_cvs_dirs {
     find({ no_chdir => 1, wanted => sub {
         my $name = $File::Find::name;
         if ($File::Find::dir =~ /\/CVS/ || $_ eq '.cvsignore'
-            || (-d $name && $_ eq 'CVS')) {
-            _fix_perms($name, $owner_id, $owner_gid, 0700);
+            || (-d $name && $_ =~ /CVS$/)) 
+        {
+            my $perms = 0600;
+            if (-d $name) {
+                $perms = 0700;
+            }
+            _fix_perms($name, $owner_id, $owner_gid, $perms);
         }
     }}, $dir);
 }
@@ -587,6 +591,23 @@ sub _fix_perms {
         || warn "Failed to change permissions of $name: $!";
 }
 
+sub _fix_perms_recursively {
+    my ($dir, $owner_id, $group_id, $perms) = @_;
+    # Set permissions on the directory itself.
+    _fix_perms($dir, $owner_id, $group_id, $perms->{dirs});
+    # Now recurse through the directory and set the correct permissions
+    # on subdirectories and files.
+    find({ no_chdir => 1, wanted => sub {
+        my $name = $File::Find::name;
+        if (-d $name) {
+            _fix_perms($name, $owner_id, $group_id, $perms->{dirs});
+        }
+        else {
+            _fix_perms($name, $owner_id, $group_id, $perms->{files});
+        }
+    }}, $dir);
+}
+
 sub _check_web_server_group {
     my ($group, $output) = @_;