diff --git a/acl/t/run-tests.t b/acl/t/run-tests.t index e1756d20f..023f34c83 100644 --- a/acl/t/run-tests.t +++ b/acl/t/run-tests.t @@ -1474,6 +1474,25 @@ subtest 'save_user.cgi create privilege' => sub { delete_user('admin'); }; +subtest 'save_user.cgi rejected module escaping' => sub { + _reset_fixture(); + _seed_user_acl('admin', { create => 1, mode => 2, mods => 'proc' }); + create_user({ name => 'admin', pass => 'x', modules => ['acl', 'proc'] }); + + # Ordinary and hostile module names must remain text in the error page. + for my $module ('cron', '') { + my $r = run_cgi('save_user.cgi', { + name => 'newbie', pass_def => 1, mod => $module, + logouttime_def => 1, minsize_def => 1 }); + my $expected = text('save_emod', html_escape($module)); + like($r->{out}, qr/\Q$expected\E/, 'rejected module is escaped'); + unlike($r->{out}, qr/'; + for my $inputs ({signal => 'TERM', pid => '12345'}, + {signal => $payload, pid => $payload}) { + my ($html, $error) = render_cgi('proc/kill_proc.cgi', $inputs); + is($error, "$main::text{'kill_ecannot'}\n", 'signaling is denied'); + is($heading, main::text('kill_err', + main::html_escape($inputs->{signal}), + main::html_escape($inputs->{pid})), + 'error heading renders submitted values as text'); + is($pid, $inputs->{pid}, 'process lookup receives the original PID'); + } + }; + subtest 'process output and return link' => sub { my @signals; local *main::list_processes = sub { return map { +{user => 'fixture'} } @_ };