From 1e936742d9c61bd7f198e5459f80f4a45df02dc1 Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" Date: Sun, 8 Mar 2009 18:36:55 -0400 Subject: [PATCH] Fix broken secret-detection algorithm, making anonymous users vulnerable. Thanks Jakub Vrana for reporting. Signed-off-by: Edward Z. Yang --- NEWS.txt | 10 ++++++++++ csrf-magic.php | 7 ++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/NEWS.txt b/NEWS.txt index de3b081..42f6fe8 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -1,6 +1,16 @@ [[ news ]] +1.0.2 released 2009-03-XX + + [SECURITY FIXES] + + - Due to a typo, csrf-magic accidentally treated the secret key + as always present. This means that there was a possible CSRF + attack against users without any cookies. No attacks in the + wild were known at the time of this release. Thanks Jakub + Vrána for reporting. + 1.0.1 released 2008-11-02 [NEW FEATURES] diff --git a/csrf-magic.php b/csrf-magic.php index 91f6242..d8697e5 100644 --- a/csrf-magic.php +++ b/csrf-magic.php @@ -212,6 +212,7 @@ function csrf_get_tokens() { // $ip implements a composite key, which is sent if the user hasn't sent // any cookies. It may or may not be used, depending on whether or not // the cookies "stick" + $secret = csrf_get_secret(); if (!$has_cookies && $secret) { // :TODO: Harden this against proxy-spoofing attacks $ip = ';ip:' . csrf_hash($_SERVER['IP_ADDRESS']); @@ -229,7 +230,7 @@ function csrf_get_tokens() { } if ($GLOBALS['csrf']['key']) return 'key:' . csrf_hash($GLOBALS['csrf']['key']) . $ip; // These further algorithms require a server-side secret - if ($secret === '') return 'invalid'; + if (!$secret) return 'invalid'; if ($GLOBALS['csrf']['user'] !== false) { return 'user:' . csrf_hash($GLOBALS['csrf']['user']); } @@ -286,11 +287,11 @@ function csrf_check_token($token) { // that doesn't make me feel good then about the cookie-based // implementation. case 'user': - if ($GLOBALS['csrf']['secret'] === '') return false; + if (!csrf_get_secret()) return false; if ($GLOBALS['csrf']['user'] === false) return false; return $value === csrf_hash($GLOBALS['csrf']['user'], $time); case 'ip': - if (csrf_get_secret() === '') return false; + if (!csrf_get_secret()) return false; // do not allow IP-based checks if the username is set, or if // the browser sent cookies if ($GLOBALS['csrf']['user'] !== false) return false; -- 2.11.4.GIT