[OAUTH-WG] Re: Browser-Swapping

Frederik Krogsdal Jacobsen <frederik.krogsdal@criipto.com> Wed, 05 November 2025 11:35 UTC

Return-Path: <frederik.krogsdal@criipto.com>
X-Original-To: oauth@mail2.ietf.org
Delivered-To: oauth@mail2.ietf.org
Received: from localhost (localhost [127.0.0.1]) by mail2.ietf.org (Postfix) with ESMTP id 70BCA835C7A8 for <oauth@mail2.ietf.org>; Wed, 5 Nov 2025 03:35:49 -0800 (PST)
X-Virus-Scanned: amavisd-new at ietf.org
X-Spam-Flag: NO
X-Spam-Score: -1.899
X-Spam-Level:
X-Spam-Status: No, score=-1.899 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: mail2.ietf.org (amavisd-new); dkim=pass (2048-bit key) header.d=criipto-com.20230601.gappssmtp.com
Received: from mail2.ietf.org ([166.84.6.31]) by localhost (mail2.ietf.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id i966UYV0RfOY for <oauth@mail2.ietf.org>; Wed, 5 Nov 2025 03:35:48 -0800 (PST)
Received: from mail-vs1-xe33.google.com (mail-vs1-xe33.google.com [IPv6:2607:f8b0:4864:20::e33]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature ECDSA (P-256) server-digest SHA256) (No client certificate requested) by mail2.ietf.org (Postfix) with ESMTPS id 9CD8C835C79A for <oauth@ietf.org>; Wed, 5 Nov 2025 03:35:48 -0800 (PST)
Received: by mail-vs1-xe33.google.com with SMTP id ada2fe7eead31-5dd6fbe5091so587873137.1 for <oauth@ietf.org>; Wed, 05 Nov 2025 03:35:48 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=criipto-com.20230601.gappssmtp.com; s=20230601; t=1762342548; x=1762947348; darn=ietf.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=KSc8rIDxJK3TR+RCkoqShezxmb57e87O/zXvMtdjkbI=; b=nHzFse4R+r4EVgpz9JEeB1aUWxMTbGtah08KH+UUq0BQmjjwwpmxkqQrtKke7Syotd 0k2nFk4Nuj6DS+1tBsh2A7sh7G3aXzK3Q3VAKxgmnyNFfXqrvfauuwn0nczQWkOjvsvK dF0mhEjsa451EHI+Yx48esL5HSlHiALX09DvoZ6HU72UVfEtfovM/GxZyALvL1FW4jZK m5/DgVFOjYGBpEJ31xyvnBTHhi9KFj5wH7mMc/t/HfuFKJ0pNljOAHiERGoD4jPoD4XY /IaOsgyX50jJ3Z1nNcsNgltYwxZXUYnF2CxAokv+a+N5Ultj7KJIbMal4nS2OxEs4tQO jwXw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762342548; x=1762947348; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=KSc8rIDxJK3TR+RCkoqShezxmb57e87O/zXvMtdjkbI=; b=vQhIbfujZWGgezKToz/Jrr2QNQ5RjlidZxwx2lJ5d48e9VmJFWjbuz07dTKRi/OCwt xnk/jkBRMEjfVo8h6UCWNMJdi7ZXudGNK3wUKIG1HfCJFh/YaBcoenblj9LJlHwd1+BO znXEP0eRbAp9MyPMA+X55WTgz7z/Wg1iFzIqRe6K0wod+nLDnrPlZkdOW2uMPwp6cZWQ n7ObyCWz3IdP05xMFeRBHiN3nC7e+XGQfYJAS2Qc6GyYhdT+Q4RzekqfYQt+Ik6MZZUn OYoD2G7qoYJPNc6hhZDFR4ybi7MzB4OXg+ZtDxahah5KgKh2Mi/p6AN2ur/fS7NriFJm gZRQ==
X-Forwarded-Encrypted: i=1; AJvYcCVMmvxiSRBkWQ3sNbBsv3DZsmPC1Whz9lfYbh9p8Ipo2//XNWZ3o/63pGJYYSokI20hHzNqaA==@ietf.org
X-Gm-Message-State: AOJu0Ywao8rod/rYNmofdQHNuYU0is7hfMXs5ykeGQJoLOVNq9TU5Hzm 3D8mtW6fSHl0tGl0rCnI2aIUbnlKNZfpyPY+cDqP0+oT+AyKq0s9cmu8j27Mr9ylAT6PcastIri TO91qjdImJiFA74mO5Dm10VW+w7Lnd/IYKYA7jT0W5w==
X-Gm-Gg: ASbGnctWiqeo2dmXp3VVktr9AI0OEwjakDWELYKJXT0m+p+zgNa+OlX7TPm105Eq4NM YgisIlE2l6G8ZQcfqTD90bxt4Id3bkOyEMIiZ1B2/wsTERH52LmnyQfjs+rmYcUhd3KFXBSp1Te k5uDWgk47issmaBOtvPC/8adbj/RaGSt0VbYSEbcM9L1wV/IAjU9sQj3RdFOWjfMyo705EBpcjT UQ5iyvffCyPV5Mju2kU5vMYhA77YJFbt+jstwaK2QkinMDsQNS9+9FsE6zkIHk=
X-Google-Smtp-Source: AGHT+IHvqEdnEHw0cN1siq0sY+++QKg3zyfDukaOd4HpQVBZD368XFBxqVZj0HF/hWJ2lrZgvzItzK+xUo2npwgGesU=
X-Received: by 2002:a05:6102:3a06:b0:5db:eeb6:812c with SMTP id ada2fe7eead31-5dd892bc027mr769240137.43.1762342548021; Wed, 05 Nov 2025 03:35:48 -0800 (PST)
MIME-Version: 1.0
References: <F032F35A-D55E-40A7-8589-3DD64BF8F7A0@uni-tuebingen.de> <CAMQcq-ZF5QFBELsycQdyQeH8E2kaeCG4P2b=yNtwh=gJRja5hw@mail.gmail.com> <CAEayHEM2kdXNjo=OGUFVZptxzgS+Qv-1b+UK1CXALiKP5ZKF0w@mail.gmail.com>
In-Reply-To: <CAEayHEM2kdXNjo=OGUFVZptxzgS+Qv-1b+UK1CXALiKP5ZKF0w@mail.gmail.com>
From: Frederik Krogsdal Jacobsen <frederik.krogsdal@criipto.com>
Date: Wed, 05 Nov 2025 12:35:37 +0100
X-Gm-Features: AWmQ_bn5IXTCImpvSq3emuXAyjL3q5rfdHE5_9sWzovM6WrlGHA04EP3hoZcrTY
Message-ID: <CAMQcq-YNpBNMx7EhGiCeFGi_cJnS+e_rMwmxhcXeEr6aixS+Tg@mail.gmail.com>
To: Thomas Broyer <t.broyer@gmail.com>
Content-Type: multipart/alternative; boundary="0000000000008c32dd0642d75976"
Message-ID-Hash: 77O6HKUZMBXOZVDHMQEG47KHFUUIJBHH
X-Message-ID-Hash: 77O6HKUZMBXOZVDHMQEG47KHFUUIJBHH
X-MailFrom: frederik.krogsdal@criipto.com
X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-oauth.ietf.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header
CC: oauth <oauth@ietf.org>
X-Mailman-Version: 3.3.9rc6
Precedence: list
Subject: [OAUTH-WG] Re: Browser-Swapping
List-Id: OAUTH WG <oauth.ietf.org>
Archived-At: <https://mailarchive.ietf.org/arch/msg/oauth/NYjzQPSBgH-rqtjQ-5vp9V6VqOg>
List-Archive: <https://mailarchive.ietf.org/arch/browse/oauth>
List-Help: <mailto:oauth-request@ietf.org?subject=help>
List-Owner: <mailto:oauth-owner@ietf.org>
List-Post: <mailto:oauth@ietf.org>
List-Subscribe: <mailto:oauth-join@ietf.org>
List-Unsubscribe: <mailto:oauth-leave@ietf.org>

On Wed, 5 Nov 2025 at 11:13, Thomas Broyer <t.broyer@gmail.com> wrote:

> It seems to me that your suggestion 3 could be implemented by the client
>> by simply exchanging the code and throwing away the token response when the
>> initial CSRF is detected.
>>
>
> That's what I was thinking as well, but also immediately revoking the
> token, not just throwing it away, to be extra-safe.
>

Sure, if the AS implements RFC 7009, but otherwise I don't think this is
possible for the client to do?


> I also know that in practice, some AS implementers allow multiple uses of
>> the code,
>>
>
> 😱 Do you have names?
>

Quickly searching "authorization code reuse", I got several results on the
first page. E.g. Azure AD B2C allowed this at least until the end of last
year (and maybe still does) [1,2].
Usually the argument for allowing it is something along the lines of
"keeping state in a distributed system is too hard," e.g. [3].
Sometimes the impact is mitigated by using e.g. the OIDC nonce value.

so it may be interesting to look into defining a specific "cancel request"
>> that uses up a code without returning a token.
>> Defining such a request might also make the approach easier to explain.
>> In fact, many OIDC providers already define custom "cancel" requests to
>> mitigate phishing. A "cancel" request might also be useful for OpenID CIBA
>> [1].
>>
>
> I see no reason why the revocation endpoint couldn't support revoking
> authorization codes as well (that would need to be spec'd, and then
> implemented, and deployed; so in the meantime: exchange the code for a
> token, and immediately revoke it, assuming –because that's how it MUST be–
> the authorization code is single-use)
>

I agree that extending the revocation endpoint is probably the way forward
when the client detects CSRF.
In the meantime, exchanging the code and immediately revoking (if
possible), then throwing away the token should be a quick way to mitigate
the attack.
It might be worth mentioning this approach in OAuth 2.1?

Cheers,
Frederik

[1]:
https://learn.microsoft.com/en-us/answers/questions/1179021/how-to-prevent-reuse-of-oauth-authorization-code
[2]:
https://learn.microsoft.com/en-sg/answers/questions/2131783/invalidate-authorization-code-after-use
[3]: https://github.com/kanidm/kanidm/issues/2775