Re: [OAUTH-WG] Implementation questions around refresh token rotation

Torsten Lodderstedt <> Sat, 10 October 2020 10:10 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id E7A0E3A1381 for <>; Sat, 10 Oct 2020 03:10:21 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -2.097
X-Spam-Status: No, score=-2.097 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HTML_MESSAGE=0.001, MIME_QP_LONG_LINE=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: (amavisd-new); dkim=pass (2048-bit key)
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id EoNv5PVtonmj for <>; Sat, 10 Oct 2020 03:10:17 -0700 (PDT)
Received: from ( [IPv6:2a00:1450:4864:20::636]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 7A24E3A1380 for <>; Sat, 10 Oct 2020 03:10:17 -0700 (PDT)
Received: by with SMTP id u8so16652687ejg.1 for <>; Sat, 10 Oct 2020 03:10:17 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=google; h=content-transfer-encoding:from:mime-version:subject:date:message-id :references:cc:in-reply-to:to; bh=lBbtVOm7Iv9ao5h5cR05rJJfCtBdYgO8vgzwFAczzVM=; b=HxM9DzcAJDFdW6ARO2GGLibqLWNSZZvvdOvH0B+3LTBHKzRUo+Vrq2emOVK0WqbINy 8gECpMrGnWpoP/yokUHCy5I+G33tXUAq7kDaRqbZCKusJ5x2G5kkJRmQBmQwSxIbsMRJ 14AU4l7q5LPftbG2BJthjBRVsggk9VF/ChZc0dUEtRCMNo38YKp35TD4fSEKHbLTy8Es IpUwkzx9QECKfOz7AjVPM5hu6pwqt/R7/Jv+x67LyPJfOT+dWZeLygu1XLJlPuCzAq7L +2ibxjy8vurrHV0jGXnZdDeybQ4yrXW5oS6ftDSpI1qkf3JfPA2vJCVJabjBzvtzKKMm VJcg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20161025; h=x-gm-message-state:content-transfer-encoding:from:mime-version :subject:date:message-id:references:cc:in-reply-to:to; bh=lBbtVOm7Iv9ao5h5cR05rJJfCtBdYgO8vgzwFAczzVM=; b=lJxmF51duyqkRfhxqYbJZUuiSOLI9P+a1KBVs5zKrntCPuNDI2tj90HX0m8KBrDcR0 lzramNG9aD1WNFyeYcf7PpiN/+tHEaiUN87zkT1L2tL596Ns1bx/QhKFO21I2Eh7mWPx wj8yIv9aq2ZqC2gX1cBnX6dWKLVyi3lG+eHm4ytPsMAwwAeIeCJ28d9NYU0KKK6/RQSY 0EruQ5VKzM9kkN0v9hr8oYfwxUQHlrR6Ldj6w2b/MSmQ2e8ms7TTUxx/5ZZS9MHhH0Rf ZTXoehX3FRkv8QBCY/epUgcJ/IqT1r9Qb0ZQm0xVdubKaRP7j8cFNmn+ACX21Fb58PHz KvOw==
X-Gm-Message-State: AOAM531Iewp7P1Cw21uBpq2SwnKrYvPYBOdsxuCbqTg7ljFwHQ5rAqS3 ZCrXBAXlC2K0ASCjVzapHxxOhWifZ6nwJh6S
X-Google-Smtp-Source: ABdhPJzEw/2SNgTNidg4SUHzOofbGfMfuGdFLXx96KrcmPhkAJZkLNhuHri6PDIG0r6vdcAA5QLeog==
X-Received: by 2002:a17:906:1e15:: with SMTP id g21mr18059781ejj.131.1602324615562; Sat, 10 Oct 2020 03:10:15 -0700 (PDT)
Received: from ?IPv6:2003:eb:8f1e:2ab3:509:1ac7:83:8202? ( [2003:eb:8f1e:2ab3:509:1ac7:83:8202]) by with ESMTPSA id g20sm8198886ejz.88.2020. (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 10 Oct 2020 03:10:14 -0700 (PDT)
Content-Type: multipart/signed; boundary="Apple-Mail-5B33CACB-F6BB-4A76-B9D6-D46BCBFE7EBC"; protocol="application/pkcs7-signature"; micalg="sha-256"
Content-Transfer-Encoding: 7bit
From: Torsten Lodderstedt <>
Mime-Version: 1.0 (1.0)
Date: Sat, 10 Oct 2020 12:10:13 +0200
Message-Id: <>
References: <>
Cc: Aaron Parecki <>, OAuth WG <>
In-Reply-To: <>
To: Neil Madden <>
X-Mailer: iPad Mail (18A393)
Archived-At: <>
Subject: Re: [OAUTH-WG] Implementation questions around refresh token rotation
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: OAUTH WG <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Sat, 10 Oct 2020 10:10:22 -0000

> Am 07.10.2020 um 09:20 schrieb Neil Madden <>:
>>> On 6 Oct 2020, at 23:05, Aaron Parecki <> wrote:
>> Hi all, I have a couple questions for those of you who have implemented refresh token rotation...
>> Have you included the option of a grace period on refresh token use, allowing multiple uses within some time window? I'm wondering because a grace period where a refresh token may be used more than once would work around the problem that has been brought up, of a mobile app accidentally using a refresh token more than once during normal operation because different threads are unable to coordinate between themselves. However that also kind of defeats the purpose since attacks within that grace period would be hard to detect. I'm looking for an idea of where people have landed on that issue in practice.
> Right. We’ve avoided adding a grace period for this reason. An attacker in a position to steal a refresh token is also presumably in a position to see when the legitimate client uses it and then sneak in just afterwards within the grace period. You could maybe only allow grace period refreshes from the same IP address but I’m not sure that would always hold in the flaky mobile network scenarios (eg refresh fails on 2G due to disconnect then client switches to Wifi hotspot and retries). 

We did not implement a grace period for the same reason. Refresh token rotation is a countermeasure against refresh token theft and replay for public client. A grace period to some degree limits it effectiveness against exactly this attack.

best regards,

>> If you have implemented a grace period, then how do you handle expiring the additional refresh tokens that have been granted? For example, if RT "R1" is used twice, resulting in new ATs "A1.1", "A1.2" and new RTs "R1.1" and "R1.2", what happens if "R1.2" is then later used? Would you invalidate "R1.1" at that point? If so, why, and if not, why not?
>> It would be most interesting to hear practical experience from people who have already built refresh token rotation into a system.
>> Thanks!
>> ---
>> Aaron Parecki
>> _______________________________________________
>> OAuth mailing list
> _______________________________________________
> OAuth mailing list