]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 1426409 - github_secret key has no rate limiting
authorDylan William Hardison <dylan@hardison.net>
Wed, 3 Jan 2018 19:22:04 +0000 (14:22 -0500)
committerDylan William Hardison <dylan@hardison.net>
Thu, 4 Jan 2018 13:13:12 +0000 (08:13 -0500)
Bugzilla.pm
Bugzilla/Config.pm
Bugzilla/Config/Admin.pm
github.cgi

index 9e5177839ad721858aa76b0ade5fdca95c38948e..b7aaadf3f7cff260160ac748800b337615c91719 100644 (file)
@@ -317,7 +317,7 @@ sub github_secret {
     my $cache = $class->request_cache;
     my $cgi   = $class->cgi;
 
-    $cache->{github_secret} //= $cgi->cookie('github_secret') // generate_random_password(16);
+    $cache->{github_secret} //= $cgi->cookie('github_secret') // generate_random_password(256);
 
     return $cache->{github_secret};
 }
@@ -853,7 +853,7 @@ sub check_rate_limit {
                 $action = 'ignore';
             }
             my $limit = join("/", @$limit);
-            Bugzilla->audit("[rate_limit] action=$action, ip=$ip, limit=$limit");
+            Bugzilla->audit("[rate_limit] action=$action, ip=$ip, limit=$limit, name=$name");
             ThrowUserError("rate_limit") if $action eq 'block';
         }
     }
index f93992f915acd72b6c676a96a1caa4f89c9bb274..d050ff9e0901cc2369b1ce12bb3374da22c48f5d 100644 (file)
@@ -193,6 +193,20 @@ sub update_params {
                 $param->{$name} = $item->{'default'};
             }
         }
+        else {
+            my $checker = $item->{'checker'};
+            my $updater = $item->{'updater'};
+            if ($checker) {
+                my $error = $checker->($param->{$name}, $item);
+                if ($error && $updater) {
+                    my $new_val = $updater->( $param->{$name} );
+                    $param->{$name} = $new_val unless $checker->($new_val, $item);
+                }
+                elsif ($error) {
+                    warn "Invalid parameter: $name\n";
+                }
+            }
+        }
     }
 
     # Generate unique Duo integration secret key
index ad24f7112df7870b9827a6c6526d4e07cc19852f..ac1c4ca0ecec1eb9c38d58719456d96db52de6eb 100644 (file)
@@ -12,7 +12,7 @@ use strict;
 use warnings;
 
 use Bugzilla::Config::Common;
-use JSON::XS qw(decode_json);
+use JSON::XS qw(decode_json encode_json);
 use List::MoreUtils qw(all);
 use Scalar::Util qw(looks_like_number);
 
@@ -55,8 +55,9 @@ sub get_param_list {
         {
             name    => 'rate_limit_rules',
             type    => 'l',
-            default => '{"get_bug": [75, 60], "show_bug": [75, 60]}',
+            default => '{"get_bug": [75, 60], "show_bug": [75, 60], "github": [10, 60]}',
             checker => \&check_rate_limit_rules,
+            updater => \&update_rate_limit_rules,
         },
 
         {
@@ -78,11 +79,18 @@ sub check_rate_limit_rules {
         ref($_) eq 'ARRAY' && looks_like_number( $_->[0] ) && looks_like_number( $_->[1] )
     } values %$val;
 
-    foreach my $required (qw( show_bug get_bug )) {
+    foreach my $required (qw( show_bug get_bug github )) {
         return "missing $required" unless exists $val->{$required};
     }
 
     return "";
 }
 
+sub update_rate_limit_rules {
+    my ($rules) = @_;
+    my $val = decode_json($rules);
+    $val->{github} = [10, 60];
+    return encode_json($val);
+}
+
 1;
index b8467e1e03fdd89a33ebad08df339147eac34455..f280f6ac98be8f3dea61b65b6894291e6a5fd82d 100755 (executable)
@@ -13,7 +13,7 @@ use warnings;
 use lib qw(. lib local/lib/perl5);
 
 use Bugzilla;
-use Bugzilla::Util ();
+use Bugzilla::Util qw(remote_ip);
 use Bugzilla::Error;
 use Bugzilla::Constants;
 use Bugzilla::Token qw( issue_short_lived_session_token
@@ -37,8 +37,10 @@ if (lc($cgi->request_method) eq 'post') {
     my $github_secret  = $cgi->param('github_secret') or ThrowCodeError("github_invalid_request", { reason => 'invalid secret' });
     my $github_secret2 = Bugzilla->github_secret      or ThrowCodeError("github_invalid_request", { reason => 'invalid secret' });
 
-    ThrowCodeError("github_invalid_request", { reason => 'invalid secret' })
-      unless $github_secret eq $github_secret2;
+    if ($github_secret ne $github_secret2) {
+        Bugzilla->check_rate_limit('github', remote_ip());
+        ThrowCodeError("github_invalid_request", { reason => 'invalid secret' });
+    }
 
     ThrowCodeError("github_invalid_target", { target_uri => $target_uri })
       unless $target_uri =~ /^\Q$urlbase\E/;
@@ -71,13 +73,18 @@ elsif (lc($cgi->request_method) eq 'get') {
         exit;
     }
 
-    ThrowCodeError("github_invalid_request", { reason => 'invalid state param' })
-      unless $state_param eq $state_cookie;
+    my $invalid_request = $state_param ne $state_cookie;
 
-    my $state_data = get_token_extra_data($state_param);
-    ThrowCodeError("github_invalid_request", { reason => 'invalid state param' } )
-      unless $state_data && $state_data->{type};
+    my $state_data;
+    unless ($invalid_request) {
+        $state_data = get_token_extra_data($state_param);
+        $invalid_request = !( $state_data && $state_data->{type} && $state_data->{type} =~ /^github_(?:login|email)$/  );
+    }
 
+    if ($invalid_request) {
+        Bugzilla->check_rate_limit('github', remote_ip());
+        ThrowCodeError("github_invalid_request", { reason => 'invalid state param' } )
+    }
 
     $cgi->remove_cookie('github_state');
     delete_token($state_param);
@@ -90,9 +97,6 @@ elsif (lc($cgi->request_method) eq 'get') {
         Bugzilla->request_cache->{github_action} = 'email';
         Bugzilla->request_cache->{github_emails} = $state_data->{emails};
     }
-    else {
-        ThrowCodeError("github_invalid_request", { reason => "invalid state param" })
-    }
     my $user = Bugzilla->login(LOGIN_REQUIRED);
 
     my $target_uri = URI->new($state_data->{target_uri});