Subject: [OAUTH-WG] Feedback on OAuth for browser-based Apps

From: Dominick Baier <[email-masked]>
Date: Sun, 21 Jul 2019 23:14:33 -0700

Hey,

Just read the spec - good to see the progress. Some feedback:

I am yet undecided if I like the categorisation of the “Application
Architecture Patterns”. I definitely want to distinguish between
applications only accessing same-site back-end services and “others”. Not
sure if “dynamic application server" and “static application server” should
be handled differently - they are deployment details and should not decide
on the application security architecture. Also not sure how realistic it is
to deploy a typical applications solely from e.g. a CDN. But I don’t have
the right answer wrt to categories right now.

6.1.  Apps Served from a Common Domain as the Resource Server

> OAuth and OpenID Connect provide very little benefit in this
   deployment scenario, so it is recommended to reconsider whether you
   need OAuth or OpenID Connect at all in this case.

I think you are mixing authentication and API access here. Depending on
application scenario it makes a lot of sense to use OIDC - but rely on the
resulting session to control API access.
Unless you want to dive into the details here, I suggest you remove the
mention of OIDC because it is misleading.

6.2.  Apps Served from a Dynamic Application Server

I have a .NET sample for that

https://github.com/leastprivilege/AspNetCoreSecuritySamples/tree/aspnetcore21/BFF
And a blog post
https://leastprivilege.com/2019/01/18/an-alternative-way-to-secure-spas-with-asp-net-core-openid-connect-oauth-2-0-and-proxykit/

9.7 <https://tools.ietf.org/html/draft-ietf-oauth-browser-based-apps-02#section-9.7>.
Content-Security Policy

   A browser-based application that wishes to use either long-lived
   refresh tokens or privileged scopes SHOULD restrict its JavaScript
   execution to a set of statically hosted scripts via a Content
   Security Policy ([CSP2
<https://tools.ietf.org/html/draft-ietf-oauth-browser-based-apps-02#ref-CSP2>])
or similar mechanism.

I would rather say that ANY JS app should use CSP to lock down the browser
features to a minimal attack surface. In addition, if refresh or access
tokens are involved - further settings like disabling inline scripting
(unsafe inline) and eval should be disabled.

Thanks for doing this work!

———
Dominick

---

From: Dominick Baier <[email-masked]>
Date: Tue, 23 Jul 2019 00:28:19 -0700

Forgot one more thing

In 7.1

Browser-based apps MUST use the OAuth 2.0 "state" parameter to
   protect themselves against Cross-Site Request Forgery and
   authorization code swap attacks and MUST use a unique value for each
   authorization request, and MUST verify the returned state in the
   authorization response matches the original state the app created.

Isn’t state optional when PKCE is used?

thanks
———
Dominick

On 22. July 2019 at 08:14:33, Dominick Baier ([email-masked])
wrote:

Hey,

9.7
<https://tools.ietf.org/html/draft-ietf-oauth-browser-based-apps-02#section-9.7>.
Content-Security Policy

———
Dominick

---

From: Neil Madden <[email-masked]>
Date: Tue, 23 Jul 2019 08:44:36 +0100

Technically it could be optional, but it means that a CSRF attempt will only be detected by the AS not by the client. If we consider the possibility of a malicious AS, then this could allow Login CSRF attacks against the client. The client would also have to be sure that the AS actually implements PKCE. So I think it’s safer to leave the recommendation as-is. 

> On 23 Jul 2019, at 08:28, Dominick Baier <[email-masked]> wrote:
> 
> Forgot one more thing
> 
> In 7.1
> 
>> On 22. July 2019 at 08:14:33, Dominick Baier ([email-masked]) wrote:
>> 
>> Hey, 
>> 
>> I am yet undecided if I like the categorisation of the “Application Architecture Patterns”. I definitely want to distinguish between applications only accessing same-site back-end services and “others”. Not sure if “dynamic application server" and “static application server” should be handled differently - they are deployment details and should not decide on the application security architecture. Also not sure how realistic it is to deploy a typical applications solely from e.g. a CDN. But I don’t have the right answer wrt to categories right now.
>> 
>> I think you are mixing authentication and API access here. Depending on application scenario it makes a lot of sense to use OIDC - but rely on the resulting session to control API access. 
>> Unless you want to dive into the details here, I suggest you remove the mention of OIDC because it is misleading.
>> 
>> 
>> 9.7. Content-Security Policy
>>    Security Policy ([CSP2]) or similar mechanism.
>> 
>> 
>> I would rather say that ANY JS app should use CSP to lock down the browser features to a minimal attack surface. In addition, if refresh or access tokens are involved - further settings like disabling inline scripting (unsafe inline) and eval should be disabled.
>> 
> _______________________________________________
> OAuth mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/oauth

---

From: Filip Skokan <[email-masked]>
Date: Tue, 23 Jul 2019 10:08:41 +0200

Wouldn’t that contradict the security topics BCP?

Odesláno z iPhonu

---

From: Dominick Baier <[email-masked]>
Date: Tue, 23 Jul 2019 01:31:27 -0700

Yes it would.

———
Dominick

On 23. July 2019 at 10:08:43, Filip Skokan ([email-masked]) wrote:

Odesláno z iPhonu

Technically it could be optional, but it means that a CSRF attempt will
only be detected by the AS not by the client. If we consider the
possibility of a malicious AS, then this could allow Login CSRF attacks
against the client. The client would also have to be sure that the AS
actually implements PKCE. So I think it’s safer to leave the recommendation
as-is.

Forgot one more thing

In 7.1

thanks
———
Dominick

Hey,

9.7

———
Dominick

---

From: Neil Madden <[email-masked]>
Date: Tue, 23 Jul 2019 10:46:19 +0100

Not sure I follow - the current OAuth security topics BCP allows for using either state or PKCE for detecting CSRF (https://tools.ietf.org/html/draft-ietf-oauth-security-topics-13#section-4.7.1 <https://tools.ietf.org/html/draft-ietf-oauth-security-topics-13#section-4.7.1>), with some caveats for when state is preferred.

I think I prefer the current wording in the browser-based draft, which provides a much clearer unambiguous recommendation.

-- Neil

> On 23 Jul 2019, at 09:31, Dominick Baier <[email-masked]> wrote:
> 
> Yes it would.
> 
> ———
> Dominick
> 
> On 23. July 2019 at 10:08:43, Filip Skokan ([email-masked] <mailto:[email-masked]>) wrote:
> 
>> 23. 7. 2019 v 9:44, Neil Madden <[email-masked] <mailto:[email-masked]>>:
>> 
>>> On 23 Jul 2019, at 08:28, Dominick Baier <[email-masked] <mailto:[email-masked]>> wrote:
>>> 
>>>> Forgot one more thing
>>>> 
>>>> In 7.1
>>>> 
>>>> On 22. July 2019 at 08:14:33, Dominick Baier ([email-masked] <mailto:[email-masked]>) wrote:
>>>> 
>>>>> Hey, 
>>>>> 
>>>>> https://github.com/leastprivilege/AspNetCoreSecuritySamples/tree/aspnetcore21/BFF <https://github.com/leastprivilege/AspNetCoreSecuritySamples/tree/aspnetcore21/BFF>
>>>>> And a blog post
>>>>> https://leastprivilege.com/2019/01/18/an-alternative-way-to-secure-spas-with-asp-net-core-openid-connect-oauth-2-0-and-proxykit/ <https://leastprivilege.com/2019/01/18/an-alternative-way-to-secure-spas-with-asp-net-core-openid-connect-oauth-2-0-and-proxykit/>
>>>>> 
>>>>> 9.7 <https://tools.ietf.org/html/draft-ietf-oauth-browser-based-apps-02#section-9.7>. Content-Security Policy
>>>>>    Security Policy ([CSP2 <https://tools.ietf.org/html/draft-ietf-oauth-browser-based-apps-02#ref-CSP2>]) or similar mechanism.
>>>>> 
>>>>> 
>>>> [email-masked] <mailto:[email-masked]>
>>>> https://www.ietf.org/mailman/listinfo/oauth <https://www.ietf.org/mailman/listinfo/oauth>
>>> [email-masked] <mailto:[email-masked]>
>>> https://www.ietf.org/mailman/listinfo/oauth <https://www.ietf.org/mailman/listinfo/oauth>

---

From: Aaron Parecki <[email-masked]>
Date: Wed, 24 Jul 2019 17:03:14 -0400

> Unless you want to dive into the details here, I suggest you remove the mention of OIDC because it is misleading.

I agree, I removed the mention of OIDC.

> I would rather say that ANY JS app should use CSP to lock down the browser features to a minimal attack surface. In addition, if refresh or access tokens are involved - further settings like disabl…

I'm not sure what to do with this suggestion. It feels like a blanket
recommendation of enabling CSP will likely be ignored since it's too
broad, and recommending disabling inline scripts is overreaching
unless backed up by a specific threat it's protecting against. Did you
have a particular threat in mind?

----
Aaron Parecki
aaronparecki.com
@aaronpk

---

From: Dominick Baier <[email-masked]>
Date: Wed, 24 Jul 2019 23:28:27 -0700

To clarify.

Using CSP is a general best practice for every JS app.

Once tokens are stored in the browser you want to specifically focus on
injection attacks (XSS) - disabling inline scripting is key to that.

———
Dominick

On 24. July 2019 at 23:04:20, Aaron Parecki ([email-masked]) wrote:

> I would rather say that ANY JS app should use CSP to lock down the
browser features to a minimal attack surface. In addition, if refresh or
access tokens are involved - further settings like disabling inline
scripting (unsafe inline) and eval should be disabled.

----
Aaron Parecki
aaronparecki.com
@aaronpk

> I would rather say that ANY JS app should use CSP to lock down the
browser features to a minimal attack surface. In addition, if refresh or
access tokens are involved - further settings like disabling inline
scripting (unsafe inline) and eval should be disabled.

---

From: David Waite <[email-masked]>
Date: Thu, 25 Jul 2019 02:04:56 -0600

> On Jul 24, 2019, at 3:03 PM, Aaron Parecki <[email-masked]> wrote:
> 
<snip>

> have a particular threat in mind?

I would say that browser applications should take measures to harden their applications again code injection and arbitrary code execution. Examples include eliminating inline script (and limiting embeddable objects as much as possible) via CSP, and versioning third party resources via techniques like subresource integrity.  Mechanisms such as augmenting the codebase to make sure all appropriate user input, data storage, and output properly sanitize data may be used - although they may be more expensive to implement and audit.

The AS should likewise take into account an application’s overall security posture when deciding appropriate policies around delegated authorization scopes and token lifetimes.

Best current practices include turning the screws tightly around CSP. But it is (theoretically) possible to accomplish the same with brute-force sanitization, which has been made simpler with framework support. It is still ultimately the AS job to decide which clients have which capabilities.

-DW

---

From: Justin Richer <[email-masked]>
Date: Thu, 25 Jul 2019 11:44:55 +0000

This raises an interesting question that I don’t think we’ve addressed yet: how to appropriately vary token lifetimes and access for different clients.

Previously, an AS could see that a client was using the implicit flow and decide to limit token lifetimes or scopes based on that alone. Similarly, I know of at least some AS implementations that let you limit what scopes you allow under the client credentials grant. The key issue is that if all your clients are using the auth code flow (which I agree they should), then how does an AS tell the difference in capabilities between incoming clients?

Obviously it can do it on a per-client basis still, but now an AS is going to have to know a bit more about the app itself. Perhaps we finally need a few more entries in the “application_type” metadata parameter from OIDC’s extension RFC7591 beyond “native” and “web”? But we at least probably want to point out to AS implementors that this is something they want to consider tracking in their data model for clients.

— Justin

On Jul 25, 2019, at 4:04 AM, David Waite <[email-masked]<mailto:[email-masked]>> wrote:

On Jul 24, 2019, at 3:03 PM, Aaron Parecki <[email-masked]<mailto:[email-masked]>> wrote:

On Mon, Jul 22, 2019 at 2:14 AM Dominick Baier
<[email-masked]<mailto:[email-masked]>> wrote:

<snip>

-DW
_______________________________________________
OAuth mailing list
[email-masked]<mailto:[email-masked]>
https://www.ietf.org/mailman/listinfo/oauth

---

From: Filip Skokan <[email-masked]>
Date: Thu, 25 Jul 2019 14:11:06 +0200

>
> Obviously it can do it on a per-client basis still, but now an AS is going
> to have to know a bit more about the app itself. Perhaps we finally need a
> few more entries in the “application_type” metadata parameter from OIDC’s
> extension RFC7591 beyond “native” and “web”? But we at least probably want
> to point out to AS implementors that this is something they want to
> consider tracking in their data model for clients.
>

I would very much like to see that. native/web possibly in combination with
token_endpoint_auth_method and the client being DCR or "static" is far from
being enough to make a policy decision.

S pozdravem,
*Filip Skokan*

On Thu, 25 Jul 2019 at 13:45, Justin Richer <[email-masked]> wrote:

> This raises an interesting question that I don’t think we’ve addressed
> yet: how to appropriately vary token lifetimes and access for different
> clients.
>
> Previously, an AS could see that a client was using the implicit flow and
> decide to limit token lifetimes or scopes based on that alone. Similarly, I
> know of at least some AS implementations that let you limit what scopes you
> allow under the client credentials grant. The key issue is that if all your
> clients are using the auth code flow (which I agree they should), then how
> does an AS tell the difference in capabilities between incoming clients?
>
> Obviously it can do it on a per-client basis still, but now an AS is going
> to have to know a bit more about the app itself. Perhaps we finally need a
> few more entries in the “application_type” metadata parameter from OIDC’s
> extension RFC7591 beyond “native” and “web”? But we at least probably want
> to point out to AS implementors that this is something they want to
> consider tracking in their data model for clients.
>
> — Justin
>
> On Jul 25, 2019, at 4:04 AM, David Waite <[email-masked]>
> wrote:
>
>
>
>
> I would say that browser applications should take measures to harden their
> applications again code injection and arbitrary code execution. Examples
> include eliminating inline script (and limiting embeddable objects as much
> as possible) via CSP, and versioning third party resources via techniques
> like subresource integrity.  Mechanisms such as augmenting the codebase to
> make sure all appropriate user input, data storage, and output properly
> sanitize data may be used - although they may be more expensive to
> implement and audit.
>
> The AS should likewise take into account an application’s overall security
> posture when deciding appropriate policies around delegated authorization
> scopes and token lifetimes.
>
> Best current practices include turning the screws tightly around CSP. But
> it is (theoretically) possible to accomplish the same with brute-force
> sanitization, which has been made simpler with framework support. It is
> still ultimately the AS job to decide which clients have which capabilities.
>
> -DW

---

From: Justin Richer <[email-masked]>
Date: Thu, 25 Jul 2019 16:50:10 +0000

I also think it would be useful, but a problem is that things like “application type” are usually a stand in for a whole bunch of different attributes that we actually care about. That’s what happened with web/native and why, to my knowledge, nobody really uses those in lieu of things like public/confidential and redirect URI locations instead for policy decisions. If we do enumerate these, we would also need to enumerate all of the things it means.

I tried to shy away from “application type” style switches in XYZ’s straw man, and instead opt for recipes of applying the different options to different kinds of clients. I don’t know how long that will hold up though.

— Justin

On Jul 25, 2019, at 8:11 AM, Filip Skokan <[email-masked]<mailto:[email-masked]>> wrote:

I would very much like to see that. native/web possibly in combination with token_endpoint_auth_method and the client being DCR or "static" is far from being enough to make a policy decision.

S pozdravem,
Filip Skokan

On Thu, 25 Jul 2019 at 13:45, Justin Richer <[email-masked]<mailto:[email-masked]>> wrote:
This raises an interesting question that I don’t think we’ve addressed yet: how to appropriately vary token lifetimes and access for different clients.

— Justin

<snip>

-DW

---

From: Leo Tohill <[email-masked]>
Date: Thu, 25 Jul 2019 15:01:48 -0400

> I agree, I removed the mention of OIDC.

If that means you'd leave the OAuth prohibition, it's still misleading or
confusing.  OIDC is of course an extension of or layer over OAuth.  If you
prohibit OAuth, you prohibit OIDC. You don't mean it that way, but that's
the way it reads.

On Thu, Jul 25, 2019 at 12:51 PM Justin Richer <[email-masked]> wrote:

> I also think it would be useful, but a problem is that things like
> “application type” are usually a stand in for a whole bunch of different
> attributes that we actually care about. That’s what happened with
> web/native and why, to my knowledge, nobody really uses those in lieu of
> things like public/confidential and redirect URI locations instead for
> policy decisions. If we do enumerate these, we would also need to enumerate
> all of the things it means.
>
> I tried to shy away from “application type” style switches in XYZ’s straw
> man, and instead opt for recipes of applying the different options to
> different kinds of clients. I don’t know how long that will hold up though.
>
> — Justin
>
> On Jul 25, 2019, at 8:11 AM, Filip Skokan <[email-masked]> wrote:
>
> I would very much like to see that. native/web possibly in combination
> with token_endpoint_auth_method and the client being DCR or "static" is far
> from being enough to make a policy decision.
>
> S pozdravem,
> *Filip Skokan*
>
>
>> Obviously it can do it on a per-client basis still, but now an AS is
>> going to have to know a bit more about the app itself. Perhaps we finally
>> need a few more entries in the “application_type” metadata parameter from
>> OIDC’s extension RFC7591 beyond “native” and “web”? But we at least
>> probably want to point out to AS implementors that this is something they
>> want to consider tracking in their data model for clients.
>>
>> — Justin
>>
>> I would say that browser applications should take measures to harden
>> their applications again code injection and arbitrary code execution.
>> Examples include eliminating inline script (and limiting embeddable objects
>> as much as possible) via CSP, and versioning third party resources via
>> techniques like subresource integrity.  Mechanisms such as augmenting the
>> codebase to make sure all appropriate user input, data storage, and output
>> properly sanitize data may be used - although they may be more expensive to
>> implement and audit.
>>
>> The AS should likewise take into account an application’s overall
>> security posture when deciding appropriate policies around delegated
>> authorization scopes and token lifetimes.
>>

---

From: n-sakimura <[email-masked]>
Date: Sun, 28 Jul 2019 21:31:19 +0000

Agreed.

On the related issue, issue of exporting the access token that a confidential client got to a public client is there as it was discussed in the Friday’s Oauth WG meeting. Though I did not make any comment on Friday as we were running out of time, I think that is a bad idea as the AuthZ server has issued it assuming that it is kept by a confidential client.

Hybrid response type was made because of the view that the public client should get less privilege.

If we are getting rid of Implicit flow, this aspect need to be addressed.

Having said that: if SPA is using the code flow, is it not acting as a public client without a client secret?

Nat

From: OAuth [mailto:[email-masked]] On Behalf Of Justin Richer
Sent: Thursday, July 25, 2019 8:45 PM
To: David Waite <[email-masked]>
Cc: OAuth WG <[email-masked]>
Subject: Re: [OAUTH-WG] Feedback on OAuth for browser-based Apps

— Justin

-DW