I'm connecting to Drupal 7 through services and OAuth. All is working fine and I'm able to connect except in one situation:
When a client has a timestamp 10 minutes later (the server is working with punctual UTC+1).
The client tries to fetch token and the server refuses it with message "Unauthorized: Expired timestamp, yours 1341148133, ours 1341147701"
In OAuth.php: timestamp_threshold = 300 (5 minutes).
In function check_timestamp(), line 676 it takes time() (so it will get it in server timezone).
Any solution?
Also what will happens when client and server are in a different timezone?
For the moment the only solution is to avoid check_timestamp($timestamp) at line 648 in check_signature():
/**
* all-in-one function to check the signature on a request
* should guess the signature method appropriately
*/
private function check_signature($request, $consumer, $token) {
// this should probably be in a different method
$timestamp = $request instanceof OAuthRequest
? $request->get_parameter('oauth_timestamp')
: NULL;
$nonce = $request instanceof OAuthRequest
? $request->get_parameter('oauth_nonce')
: NULL;
//$this->check_timestamp($timestamp); // <-- TIMEZONE Errors!
$this->check_nonce($consumer, $token, $nonce, $timestamp);
$signature_method = $this->get_signature_method($request);
$signature = $request->get_parameter('oauth_signature');
$valid_sig = $signature_method->check_signature(
$request,
$consumer,
$token,
$signature
);
if (!$valid_sig) {
throw new OAuthException("Invalid signature");
}
}
Which are the risks?
Thanks,
Miguel
Comments
Comment #0.0
miqmago CreditAttribution: miqmago commentedAdding code
Comment #1
g10 CreditAttribution: g10 commentedThis also fixes the issue when using 2-legged auth in an app and the client device (desktop, mobile…) its clock is not correctly set.
IMHO, the implementation is not correct, according to the oAuth specs ( http://oauth.net/core/1.0/#nonce )
So the only requirement is that the timestamp should be newer then the last timestamp used, not that it should be in a given range of the server time.
Comment #2
miqmago CreditAttribution: miqmago commentedThen I change it to bug.
If I knew where the last timestamp is stored (if it is, if it is not then I will create see how to create a db entry with last timestamp used field) I will try to repair it. I will take a look but don't know when...
Comment #3
g10 CreditAttribution: g10 commentedTimestamps are not being stored, cfr. check_timestamp() method.
Although stated in the oAuth specs as such, it still would cause problems for 2-legged.
Can you tell the difference between client A and B if they both use the same key/secret with 2-legged auth?
As I have implement it (could be faulty), is making one user with a consumer, then using that one key/secret for all the client apps,
as a result it is not possible to differentiate which client is making the call. (As said, I might have done it wrong)
With 3-legged there are distinct consumers, I guess storing the last timestamp for each consumer should work.
Comment #4
miqmago CreditAttribution: miqmago commentedSorry about my ignorance... I don't know if I'm using 2 or 3 legged. I think it is 3 legged, because I create a consumer for each user.
As far as I understand from what you say, maybe would work for 2-legged to store the sid, or better the access token with last timestamp. Then you could differenciate each request.
I don't know if with 2-legged there is a different access token for each device.
Comment #4.0
miqmago CreditAttribution: miqmago commentedClarifying description