[pve-devel] r6039 - in pve-access-control/trunk: . PVE PVE/API2

svn-commits at proxmox.com svn-commits at proxmox.com
Mon May 30 08:51:40 CEST 2011


Author: dietmar
Date: 2011-05-30 08:51:40 +0200 (Mon, 30 May 2011)
New Revision: 6039

Modified:
   pve-access-control/trunk/ChangeLog
   pve-access-control/trunk/PVE/API2/AccessControl.pm
   pve-access-control/trunk/PVE/AccessControl.pm
Log:
fix CSRF code


Modified: pve-access-control/trunk/ChangeLog
===================================================================
--- pve-access-control/trunk/ChangeLog	2011-05-30 05:20:33 UTC (rev 6038)
+++ pve-access-control/trunk/ChangeLog	2011-05-30 06:51:40 UTC (rev 6039)
@@ -1,3 +1,9 @@
+2011-05-30  Proxmox Support Team  <support at proxmox.com>
+
+	* PVE/AccessControl.pm (assemble_csrf_prevention_token): CSRF
+	token may not depend on cookie, because cookie can be updated from
+	other window.
+
 2011-03-30  Proxmox Support Team  <support at proxmox.com>
 
 	* PVE/API2/AccessControl.pm (create_ticket): also return user name

Modified: pve-access-control/trunk/PVE/API2/AccessControl.pm
===================================================================
--- pve-access-control/trunk/PVE/API2/AccessControl.pm	2011-05-30 05:20:33 UTC (rev 6038)
+++ pve-access-control/trunk/PVE/API2/AccessControl.pm	2011-05-30 06:51:40 UTC (rev 6039)
@@ -156,7 +156,7 @@
 		$username = PVE::AccessControl::authenticate_user($username, $param->{password});
 	    }
 	    $ticket = PVE::AccessControl::assemble_ticket($username);
-	    $token = PVE::AccessControl::assemble_csrf_prevention_token($ticket);
+	    $token = PVE::AccessControl::assemble_csrf_prevention_token($username);
 	};
 	if (my $err = $@) {
 	    syslog('err', "authentication failure; rhost=$clientip user=$username msg=$err");

Modified: pve-access-control/trunk/PVE/AccessControl.pm
===================================================================
--- pve-access-control/trunk/PVE/AccessControl.pm	2011-05-30 05:20:33 UTC (rev 6038)
+++ pve-access-control/trunk/PVE/AccessControl.pm	2011-05-30 06:51:40 UTC (rev 6039)
@@ -100,16 +100,29 @@
 };
 
 sub assemble_csrf_prevention_token {
-    my ($ticket) = @_;
-    return Digest::SHA::sha1_base64($ticket, &$get_csrfr_secret());
+    my ($username) = @_;
+
+    my $timestamp = sprintf("%08X", time());
+
+    my $digest = Digest::SHA::sha1_base64("$timestamp:$username", &$get_csrfr_secret());
+
+    return "$timestamp:$digest"; 
 }
 
 sub verify_csrf_prevention_token {
-    my ($ticket, $token, $noerr) = @_;
+    my ($username, $token, $noerr) = @_;
 
-    my $digest = Digest::SHA::sha1_base64($ticket, &$get_csrfr_secret());
-    return if $digest eq $token;
+    if ($token =~ m/^([A-Z0-9]{8}):(\S+)$/) {
+	my $sig = $2;
+	my $timestamp = $1;
+	my $ttime = hex($timestamp);
 
+	my $digest = Digest::SHA::sha1_base64("$timestamp:$username", &$get_csrfr_secret());
+
+	my $age = time() - $ttime;
+	return if ($digest eq $sig) && ($age > -300) && ($age < $ticket_lifetime);
+    }
+
     die "Permission denied - invalid csrf token\n" if !$noerr;
 
     return undef;
@@ -132,7 +145,7 @@
 
     my $rsa_priv = get_privkey();
 
-    my $timestamp = time();
+    my $timestamp = sprintf("%08X", time());
 
     my $plain = "PVE:$username:$timestamp";
 
@@ -150,11 +163,12 @@
 
 	my $rsa_pub = get_pubkey();
 	if ($rsa_pub->verify($plain, decode_base64($sig))) {
-	    if ($plain =~ m/^PVE:(([A-Za-z0-9\.\-_]+)(\@([A-Za-z0-9\.\-_]+))?):(\d+)$/) {
+	    if ($plain =~ m/^PVE:(([A-Za-z0-9\.\-_]+)(\@([A-Za-z0-9\.\-_]+))?):([A-Z0-9]{8})$/) {
 		my $username = $1;
 		my $timestamp = $5;
+		my $ttime = hex($timestamp);
 
-		my $age = time() - $timestamp;
+		my $age = time() - $ttime;
 
 		if (($age > -300) && ($age < $ticket_lifetime)) {
 		    return wantarray ? ($username, $age) : $username;




More information about the pve-devel mailing list