forked from GNUsocial/gnu-social
Provisional OAuth, OpenID token check timing attack patches
This commit is contained in:
parent
d51820adc5
commit
f0620a74c8
@ -374,7 +374,42 @@ class Auth_OpenID_Association {
|
||||
}
|
||||
|
||||
$calculated_sig = $this->getMessageSignature($message);
|
||||
return $calculated_sig == $sig;
|
||||
|
||||
return $this->constantTimeCompare($calculated_sig, $sig);
|
||||
}
|
||||
|
||||
/**
|
||||
* String comparison function which will complete in a constant time
|
||||
* for strings of any given matching length, to help prevent an attacker
|
||||
* from distinguishing how much of a signature token they have guessed
|
||||
* correctly.
|
||||
*
|
||||
* For this usage, it's assumed that the length of the string is known,
|
||||
* so we may safely short-circuit on mismatched lengths which will be known
|
||||
* to be invalid by the attacker.
|
||||
*
|
||||
* http://lists.openid.net/pipermail/openid-security/2010-July/001156.html
|
||||
* http://rdist.root.org/2010/01/07/timing-independent-array-comparison/
|
||||
*/
|
||||
private function constantTimeCompare($a, $b)
|
||||
{
|
||||
$len = strlen($a);
|
||||
if (strlen($b) !== $len) {
|
||||
// Short-circuit on length mismatch; attackers will already know
|
||||
// the correct target length so this is safe.
|
||||
return false;
|
||||
}
|
||||
if ($len == 0) {
|
||||
// 0-length valid input shouldn't really happen. :)
|
||||
return true;
|
||||
}
|
||||
$result = 0;
|
||||
for ($i = 0; $i < strlen($a); $i++) {
|
||||
// We use scary bitwise operations to avoid logical short-circuits
|
||||
// in lower-level code.
|
||||
$result |= ord($a{$i}) ^ ord($b{$i});
|
||||
}
|
||||
return ($result == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,24 @@ class OAuthSignatureMethod {/*{{{*/
|
||||
public function check_signature(&$request, $consumer, $token, $signature) {
|
||||
$built = $this->build_signature($request, $consumer, $token);
|
||||
return $built == $signature;
|
||||
|
||||
// Check for zero length, although unlikely here
|
||||
if (strlen($built) == 0 || strlen($signature) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strlen($built) != strlen($signature)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = 0;
|
||||
|
||||
// Avoid a timing leak with a (hopefully) time insensitive compare
|
||||
for ($i = 0; $i < strlen($signature); $i++) {
|
||||
$result |= ord($built{$i}) ^ ord($signature{$i});
|
||||
}
|
||||
|
||||
return $result == 0;
|
||||
}
|
||||
}/*}}}*/
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user