From: Steinar H. Gunderson Date: Tue, 12 Nov 2013 21:23:07 +0000 (+0100) Subject: Change the return value to be more detailed when something fails. (API break, but... X-Git-Url: https://git.sesse.net/?p=www-csrf;a=commitdiff_plain;h=c767e0803a6b9f2a85f07578a35dd331b88dd1fd Change the return value to be more detailed when something fails. (API break, but this is fine, since there is no release yet.) --- diff --git a/lib/WWW/CSRF.pm b/lib/WWW/CSRF.pm index 77d8e79..0950733 100644 --- a/lib/WWW/CSRF.pm +++ b/lib/WWW/CSRF.pm @@ -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, diff --git a/t/02_check.t b/t/02_check.t index edbbda4..a364560 100644 --- a/t/02_check.t +++ b/t/02_check.t @@ -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");