From: Ian Jackson Date: Sun, 25 Oct 2015 13:37:15 +0000 (+0000) Subject: blinding: Blind cookies and hidden form param X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=cgi-auth-flexible.git;a=commitdiff_plain;h=2342dbc87d04a5be0f80e096928696e04eac26bd blinding: Blind cookies and hidden form param Each time we generate a cookie or a hidden form parameter, generate some random hex digits and xor them with the hex digits in the cookie or parameter value. Our cookies contain decimal digits, and punctuation, too. The decimal digits are simply blinded the same way (which is fine) and the punctuation is left alone. It's the actual values we care about. Signed-off-by: Ian Jackson --- diff --git a/cgi-auth-flexible.pm b/cgi-auth-flexible.pm index 73cc3e5..d5a3876 100644 --- a/cgi-auth-flexible.pm +++ b/cgi-auth-flexible.pm @@ -791,7 +791,8 @@ sub _check_divert_core ($) { Params => { } }); } - my $cooks = $r->_ch('get_cookie'); + my $cooksraw = $r->_ch('get_cookie'); + my $cooks = $r->_unblind($cooksraw); if ($r->{S}{encrypted_only} && !$r->_ch('is_https')) { return ({ Kind => 'REDIRECT-HTTPS', @@ -801,7 +802,8 @@ sub _check_divert_core ($) { } my $meth = $r->_ch('get_method'); - my $parmh = $r->_rp('assoc_param_name'); + my $parmhraw = $r->_rp('assoc_param_name'); + my $parmh = $r->_unblind($parmhraw); my $cookh = defined $cooks ? $r->hash($cooks) : undef; my ($cookt,$cooku) = $r->_identify($cookh, $cooks); @@ -913,7 +915,7 @@ sub _check_divert_core ($) { die unless $cookh eq $parmh; } $r->{ParmT} = $parmt; - $r->{AssocSecret} = $cooks; + $r->{AssocRaw} = $cooks; $r->{UserOK} = $cooku; #print STDERR "C-D-C OK\n"; return undef; @@ -1034,10 +1036,10 @@ sub check_divert ($) { $dbh->commit(); my $cookraw = $r->{_CookieRaw}; - $r->{CookieSecret} = $$cookraw; + $r->{CookieSecret} = $r->_blind($cookraw); if ($cookraw) { $r->{Params}{$r->{S}{assoc_param_name}} = [ - $r->hash($cookraw) + $r->_blind($r->hash($cookraw)) ]; } @@ -1159,6 +1161,39 @@ sub _random ($$) { return $out; } +sub _blind_len ($$) { + my ($r, $str) = @_; + return length($str =~ y/0-9a-f//cdr); +} + +sub _blind_combine ($$$) { + my ($r, $in, $mask) = @_; + my @mask = split //, $mask; + $in =~ s{[0-9a-f]}{ + my $m = shift @mask; + sprintf "%x", hex($m) ^ hex($&); + }ge; + return $in; +} + +sub _blind ($$) { + my ($r, $in) = @_; + return undef unless defined $in; + my $l = $r->_blind_len($in); + my $mask = $r->_random(($l+1)>>1); + $mask = substr $mask, 0, $l; + my $blound = $r->_blind_combine($in, $mask); + return "$blound/$mask"; +} + +sub _unblind ($$) { + my ($r, $in) = @_; + my ($blound,$mask) = ($in =~ m#^(.*)/([0-9a-f]+)$#) or die "$in ?"; + my $l = $r->_blind_len($blound); + $l == length($mask) or die "$in ?"; + return $r->_blind_combine($blound, $mask); +} + sub _random_key ($) { my ($r) = @_; #print STDERR "_random_key\n"; @@ -1340,13 +1375,13 @@ sub check_nonpage ($$) { sub secret_cookie_val ($) { my ($r) = @_; $r->_assert_checked(); - return defined $r->{AssocSecret} ? $r->{AssocSecret} : ''; + return defined $r->{AssocRaw} ? $r->_blind($r->{AssocRaw}) : ''; } sub secret_hidden_val ($) { my ($r) = @_; $r->_assert_checked(); - return defined $r->{AssocSecret} ? $r->hash($r->{AssocSecret}) : ''; + return defined $r->{AssocRaw} ? $r->_blind($r->hash($r->{AssocRaw})) : ''; } sub secret_hidden_html ($) {