From 31a7758d04ff4fee9c4451f5864e2e66c6256624 Mon Sep 17 00:00:00 2001 From: "Kyle J. McKay" Date: Mon, 15 Feb 2021 03:05:04 -0700 Subject: [PATCH] editproj.cgi: implement protected edit fields Some fields on the editproj page may contain sensitive information. Up until now, all project fields have always been displayed when the edit project link is selected -- even those fields that are not otherwise visible anywhere else. The notification email addresses and JSON POST urls may be considered sensitive information that should not just be blindly available to anyone who clicks the "edit" link on a project page. Solve this problem by making fields that contain sensitive information, specifically the ones in the $Girocco::Config::protect_fields hash, not visible or editable until the project's admin password has been entered. At the same time, enforce an editing time limit, specifically the $Girocco::Config::project_edit_timeout value, when editing so that very stale pages cannot just be submitted even if they contain the correct password. Currently the list of users allowed to push is *NOT* considered a sensitive field. That may need to be revisited at some point. Signed-off-by: Kyle J. McKay --- cgi/editproj.cgi | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/cgi/editproj.cgi b/cgi/editproj.cgi index 4807002..48ac557 100755 --- a/cgi/editproj.cgi +++ b/cgi/editproj.cgi @@ -80,11 +80,21 @@ sub format_epoch_ts { } my $y0 = $cgi->param('y0') || ''; -if (($y0 eq 'Update' || $y0 eq 'Restart Mirroring') && $cgi->request_method eq 'POST') { - # submitted, let's see +my $tok = $cgi->param('token') || ''; +my $protok = 0; +if (($y0 eq 'Update' || $y0 eq 'View All' || $y0 eq 'Restart Mirroring') && $cgi->request_method eq 'POST') {{ my $ts = "" . format_epoch_ts() . ""; - $gcgi->err_prelude("

Project update failed at $ts.

\n"); - if ($proj->cgi_fill($gcgi) and $proj->authenticate($gcgi) and $proj->update) { + $gcgi->err_prelude("

Project update failed at $ts.

\n") unless $y0 eq 'View All'; + # Check for token validity + if (!check_timed_token($tok, "projedit", $proj->{name}, $Girocco::Config::project_edit_timeout)) { + $gcgi->err("Session has timed out or is invalid, please try again."); + } + # submitted, let's see + $proj->cgi_fill($gcgi) || $y0 eq 'View All' or last; + if ($proj->authenticate($gcgi)) { + $protok = 1; + $y0 eq 'View All' and last; + $proj->update or last; print "

Project successfully updated at $ts.

\n"; if ($proj->{clone_failed}) { $proj->clone; @@ -95,7 +105,7 @@ if (($y0 eq 'Update' || $y0 eq 'Restart Mirroring') && $cgi->request_method eq ' exit; } } -} +}} # $proj may be insane now but that's actually good for us since we'll let the # user fix the invalid values he or she entered @@ -142,11 +152,14 @@ print < EOT if ($Girocco::Config::project_passwords) { + my $vab = ''; + $protok || !%{$Girocco::Config::protect_fields} or + $vab = '  '; print <Admin password: (forgot password?) + class="ctxaction">(forgot password?)$vab New admin password (twice):
(leave empty to keep it the same)

@@ -211,7 +224,9 @@ print ' '; -$gcgi->print_form_fields($Girocco::Project::metadata_fields, \%h, @Girocco::Config::project_fields); +$gcgi->print_form_fields($Girocco::Project::metadata_fields, + $protok?{}:$Girocco::Config::protect_fields, + \%h, @Girocco::Config::project_fields); print <Enable status update emails: