From 7cb42cb1a80854e570b4f19863409ae6cc263680 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 11 Jan 2017 13:12:50 +0000 Subject: [PATCH] passwordauth: prevent authentication bypass via multiple name parameters Calling CGI::FormBuilder::field with a name argument in list context returns zero or more user-specified values of the named field, even if that field was not declared as supporting multiple values. Passing the result of field as a function parameter counts as list context. This is the same bad behaviour that is now discouraged for CGI::param. In this case we pass the multiple values to CGI::Session::param. That accessor has six possible calling conventions, of which four are documented. If an attacker passes (2*n + 1) values for the 'name' field, for example name=a&name=b&name=c, we end up in one of the undocumented calling conventions for param: # equivalent to: (name => 'a', b => 'c') $session->param('name', 'a', 'b', 'c') and the 'b' session parameter is unexpectedly set to an attacker-specified value. In particular, if an attacker "bob" specifies name=bob&name=name&name=alice, then authentication is carried out for "bob" but the CGI::Session ends up containing {name => 'alice'}, an authentication bypass vulnerability. This vulnerability is tracked as OVE-20170111-0001. --- IkiWiki/Plugin/passwordauth.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/IkiWiki/Plugin/passwordauth.pm b/IkiWiki/Plugin/passwordauth.pm index 0cf2a26ea..4e0d36ed4 100644 --- a/IkiWiki/Plugin/passwordauth.pm +++ b/IkiWiki/Plugin/passwordauth.pm @@ -319,12 +319,13 @@ sub formbuilder (@) { if ($form->title eq "signin" || $form->title eq "register") { if (($form->submitted && $form->validate) || $do_register) { + my $user_name = $form->field('name'); + if ($form->submitted eq 'Login') { - $session->param("name", $form->field("name")); + $session->param("name", $user_name); IkiWiki::cgi_postsignin($cgi, $session); } elsif ($form->submitted eq 'Create Account') { - my $user_name=$form->field('name'); if (IkiWiki::userinfo_setall($user_name, { 'email' => $form->field('email'), 'regdate' => time})) { @@ -338,7 +339,6 @@ sub formbuilder (@) { } } elsif ($form->submitted eq 'Reset Password') { - my $user_name=$form->field("name"); my $email=IkiWiki::userinfo_get($user_name, "email"); if (! length $email) { error(gettext("No email address, so cannot email password reset instructions.")); -- 2.39.5