From 2d240fc34121252fe87b216b025ee1a671e7239a Mon Sep 17 00:00:00 2001
From: Holger Just <h.just@finn.de>
Date: Mon, 28 Nov 2011 16:49:34 +0100
Subject: [PATCH] [#709] Fix cache poisoning vector if credential caching is
 enabled.

The cache did not distinguish between cached credentials for read and write
access. As it does not check permissions again if there is a cache hit, users
with authorization for either reading or writing could poison the cache and
subsequently authorize themselves for both access types.

Original fix is by Jean-Philippe Lang, http://www.redmine.org/issues/9567
---
 extra/svn/Redmine.pm | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/extra/svn/Redmine.pm b/extra/svn/Redmine.pm
index b73c853de..7ff93ed73 100644
--- a/extra/svn/Redmine.pm
+++ b/extra/svn/Redmine.pm
@@ -438,10 +438,12 @@ sub is_member {
 
   my $pass_digest = Digest::SHA1::sha1_hex($redmine_pass);
 
+  my $access_mode = request_is_read_only($r) ? "R" : "W";
+
   my $cfg = Apache2::Module::get_config(__PACKAGE__, $r->server, $r->per_dir_config);
   my $usrprojpass;
   if ($cfg->{RedmineCacheCredsMax}) {
-    $usrprojpass = $cfg->{RedmineCacheCreds}->get($redmine_user.":".$project_id);
+    $usrprojpass = $cfg->{RedmineCacheCreds}->get($redmine_user.":".$project_id.":".$access_mode);
     return 1 if (defined $usrprojpass and ($usrprojpass eq $pass_digest));
   }
   my $query = $cfg->{RedmineQuery};
@@ -484,10 +486,10 @@ sub is_member {
 
   if ($cfg->{RedmineCacheCredsMax} and $ret) {
     if (defined $usrprojpass) {
-      $cfg->{RedmineCacheCreds}->set($redmine_user.":".$project_id, $pass_digest);
+      $cfg->{RedmineCacheCreds}->set($redmine_user.":".$project_id.":".$access_mode, $pass_digest);
     } else {
       if ($cfg->{RedmineCacheCredsCount} < $cfg->{RedmineCacheCredsMax}) {
-        $cfg->{RedmineCacheCreds}->set($redmine_user.":".$project_id, $pass_digest);
+        $cfg->{RedmineCacheCreds}->set($redmine_user.":".$project_id.":".$access_mode, $pass_digest);
         $cfg->{RedmineCacheCredsCount}++;
       } else {
         $cfg->{RedmineCacheCreds}->clear();
-- 
GitLab