]> git.sesse.net Git - www-csrf/commitdiff
Change the return value to be more detailed when something fails. (API break, but...
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Tue, 12 Nov 2013 21:23:07 +0000 (22:23 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Tue, 12 Nov 2013 21:23:07 +0000 (22:23 +0100)
lib/WWW/CSRF.pm
t/02_check.t

index 77d8e797cb05b352fa5247878b48cddb99e6efc1..095073382ec5d9486c50075f0f3933241a3e268d 100644 (file)
@@ -1,13 +1,19 @@
+package WWW::CSRF;
 
 use strict;
 use warnings;
 use Bytes::Random::Secure;
 use Digest::HMAC_SHA1;
+use constant {
+       CSRF_OK => 0,
+       CSRF_MALFORMED_TOKEN => 1,
+       CSRF_INVALID_SIGNATURE => 2,
+       CSRF_EXPIRED => 3,
+};
 
-package WWW::CSRF;
 require Exporter;
 our @ISA = qw(Exporter);
-our @EXPORT_OK = qw(generate_csrf_token check_csrf_token);
+our @EXPORT_OK = qw(generate_csrf_token check_csrf_token CSRF_OK CSRF_MALFORMED_TOKEN CSRF_INVALID_SIGNATURE CSRF_EXPIRED);
 our $VERSION = '1.00';
 
 sub generate_csrf_token {
@@ -41,8 +47,7 @@ sub check_csrf_token {
        my ($id, $secret, $csrf_token, $options) = @_;
 
        if ($csrf_token !~ /^([0-9a-f]+),([0-9a-f]+),([0-9]+)$/) {
-               # Malformed token.
-               return 0;
+               return CSRF_MALFORMED_TOKEN;
        }
 
        my $ref_time = $options->{'Time'} // time;
@@ -50,8 +55,7 @@ sub check_csrf_token {
        my ($masked_token, $mask, $time) = ($1, $2, $3);
        my $max_age = $options->{'MaxAge'};
        if (defined($max_age) && $ref_time - $time > $max_age) {
-               # Timed out.
-               return 0;
+               return CSRF_EXPIRED;
        }
 
        my @masked_bytes = _to_byte_array(pack('H*', $masked_token));
@@ -62,7 +66,7 @@ sub check_csrf_token {
 
        if ($#masked_bytes != $#mask_bytes || $#masked_bytes != $#correct_bytes) {
                # Malformed token (wrong number of characters).
-               return 0;
+               return CSRF_MALFORMED_TOKEN;
        }
 
        # Compare in a way that should make timing attacks hard.
@@ -70,7 +74,11 @@ sub check_csrf_token {
        for my $i (0..$#masked_bytes) {
                $mismatches += $masked_bytes[$i] ^ $mask_bytes[$i] ^ $correct_bytes[$i];
        }
-       return ($mismatches == 0);
+       if ($mismatches == 0) {
+               return CSRF_OK;
+       } else {
+               return CSRF_INVALID_SIGNATURE;
+       }
 }
 
 # Converts each byte in the given string to its numeric value,
index edbbda4254946b4fd5b259e6c5c4b15373a19629..a364560bf353478cd13d3443d586d75e919da785 100644 (file)
@@ -6,21 +6,21 @@ is(check_csrf_token("id", "secret",
                     "5df5e9f17c929a45af5d33624ec052903599958f," .
                     "112233445566778899aabbccddeeff0011223344," .
                     "1234567890"),
-   1,
+   WWW::CSRF::CSRF_OK,
    "check simple token");
 
-isnt(check_csrf_token("id", "secret",
-                      "0000000000000000000000000000000000000000," .
-                      "112233445566778899aabbccddeeff0011223344," .
-                      "1234567890"),
-     1,
-     "check simple invalid token");
+is(check_csrf_token("id", "secret",
+                    "0000000000000000000000000000000000000000," .
+                    "112233445566778899aabbccddeeff0011223344," .
+                    "1234567890"),
+   WWW::CSRF::CSRF_INVALID_SIGNATURE,
+   "check simple invalid token");
 
-isnt(check_csrf_token("id", "secret",
-                      "5df5e9f17c929a45af5d33624ec052903599958f," .
-                      "112233445566778899aabbccddeeff0011223344"),
-     1,
-     "check simple malformed token");
+is(check_csrf_token("id", "secret",
+                    "5df5e9f17c929a45af5d33624ec052903599958f," .
+                    "112233445566778899aabbccddeeff0011223344"),
+   WWW::CSRF::CSRF_MALFORMED_TOKEN,
+   "check simple malformed token");
 
 is(check_csrf_token("id", "secret",
                     "5df5e9f17c929a45af5d33624ec052903599958f," .
@@ -29,25 +29,25 @@ is(check_csrf_token("id", "secret",
                         Time => 1234567895,
                         MaxAge => 10
                     }),
-   1,
+   WWW::CSRF::CSRF_OK,
    "check with maxage");
 
-isnt(check_csrf_token("id", "secret",
-                      "5df5e9f17c929a45af5d33624ec052903599958f," .
-                      "112233445566778899aabbccddeeff0011223344," .
-                      "1234567890", {
-                          Time => 1234567895,
-                          MaxAge => 3
-                      }),
-     1,
-     "check expired with maxage");
+is(check_csrf_token("id", "secret",
+                    "5df5e9f17c929a45af5d33624ec052903599958f," .
+                    "112233445566778899aabbccddeeff0011223344," .
+                    "1234567890", {
+                        Time => 1234567895,
+                        MaxAge => 3
+                    }),
+   WWW::CSRF::CSRF_EXPIRED,
+   "check expired with maxage");
 
-isnt(check_csrf_token("id", "secret",
-                      "5df5e9f17c929a45af5d33624ec052903599958f," .
-                      "112233445566778899aabbccddeeff0011223344," .
-                      "1234567894", {
-                          Time => 1234567895,
-                          MaxAge => 10
-                      }),
-     1,
-     "check falsified timestamp");
+is(check_csrf_token("id", "secret",
+                    "5df5e9f17c929a45af5d33624ec052903599958f," .
+                    "112233445566778899aabbccddeeff0011223344," .
+                    "1234567894", {
+                        Time => 1234567895,
+                        MaxAge => 10
+                    }),
+   WWW::CSRF::CSRF_INVALID_SIGNATURE,
+   "check falsified timestamp");