maltfield

joined 2 years ago
[–] maltfield@lemmy.ml 1 points 2 months ago (1 children)

That's bad.

OAuth supports several types of flows. If I'm not mistaken (I've learned a bit more about OAuth since yesterday) you're describing the Authorization Code Flow -- as documented in RFC 6749 (The OAuth 2.0 Authorization Framework), Section 4.1 (Authorization Code Grant):

That RFC defines many other types of flows that do not require sharing the access keys with a third party, such as the Client Credentials Flow, as documented in RFC 6749 Section 4.4 (Client Credentials Grant):

The only reason you'd want to use the Authorization Code Flow is if the third party needs your access token for some reason, or if you want to hide the access key from the user agent.

The problem here is that Stripe is using the wrong flow (the third party doesn't need the access token, as they claim they never save it anyway). And if keyCloak only supports that one flow, that's would be a problem too (in this case).

[–] maltfield@lemmy.ml 2 points 2 months ago* (last edited 2 months ago)

Upon further reading of RFC 6749, it appears that OAuth does require this -- sometimes.

It depends on the OAuth Flow. In this case, Stripe uses the “Authorization Code” Grant.

This is documented in Stripe’s OAuth reference documentation here:

curl https://connect.stripe.com/oauth/token \
  -u sk_test_MgvkTWK1jRG3olSRx9B7Mmxo: \
  -d “code”=”ac_123456789” \
  -d “grant_type”=”authorization_code”

Authorization Code Grants are defined in RFC 6749 (The OAuth 2.0 Authorization Framework), Section 4.1 (Authorization Code Grant):

To better understand why the OAuth Authorization Code Grant requires sharing the access token with a thrid party server, I found this article (Common OAuth Vulnerabilities) by Doyensec very elucidating:

It says that the Authorization Code Flow is supposed to be used when you don’t want to share the tokens with the user agent.

The Authorization Code Flow is one of the most widely used OAuth flows in web applications. Unlike the Implicit Flow, which requests the Access Token directly to the Authorization Server, the Authorization Code Flow introduces an intermediary step. In this process, the User Agent first retrieves an Authorization Code, which the application then exchanges, along with the Client Credentials, for an Access Token. This additional step ensures that only the Client Application has access to the Access Token, preventing the User Agent from ever seeing it.

But this doesn't make sense for this use-case. It appears Stripe is needlessly putting us at risk by choosing the Authorization Code Grant.

[–] maltfield@lemmy.ml 1 points 2 months ago

Stripe Connect does not support Client Credentials flow.

Can you please tell me what is the name of the "flow" that Stripe Connect is using here?

[–] maltfield@lemmy.ml 1 points 2 months ago (3 children)

I figured out the root technical cause. It's because Stripe doesn't allow the redirect during the OAuth flow to be dynamic. It must be a predefined value that's hard-coded into the app.

For security purposes, Stripe redirects a user only to a predefined URI.

That's why Stripe forces you to expose your access tokens to the developer's servers.

I'd still appreciate if someone with more experience with OAuth than me knows if this is common. Seems like a very bad design decision to require users to transmit their bearer tokens through the developer's servers.

[–] maltfield@lemmy.ml 1 points 2 months ago* (last edited 2 months ago)

It’s called the Client Credentials flow (RFC 6749, Section 4.4).

Finally someone directs me to the actual RFC. Except that section is titled "Client Credentials Grant"

Why do I see this sometimes called a "Grant" and sometimes called a "Flow"?

What's the definition and difference of each?

[–] maltfield@lemmy.ml 1 points 2 months ago* (last edited 2 months ago)

Thanks, but I don't think this is the case here. The Authentication provider is Stripe (or, at least, it's a stripe.com domain name). The 3rd party is the app developer's server.

Stripe's infra is already PCI compliant.

I'm not sure how a hardware security token would be relevant here. The end result must be something-you-know access token. Initial setup is done with 2FA, sure. But I don't think the server can store (or emulate) a passkey. The issue here isn't how I authenticate with Stripe. It's after that -- when Stripe gives the tokens to the third party (the dev's server) and then the third party gives the token to my server. I don't understand why Stripe doesn't just let the devs implement it so Stripe gives the tokens directly to my server.

 

Why does Stripe require OAuth tokens to pass through a third party server?

Can someone who understands OAuth better than me explain to me why Stripe REQUIRES that their OAuth Access Keys get shared with a third party?

I've tried RTFM, but my biggest hangup is that the OAuth docs appear describe a very different situation than mine. They usually describe a user agent (web browser) as the client. And they talk about "your users" as if I have a bunch of users that I'm going to be fetching access keys for.

Nah, this is server <--> server. I have a server. Stripe has a server. I am one user. All I need is ONE API key for ONE account. But I'm forced to use OAuth. It doesn't seem appropriate, and it's especially concerning that the "flow" requires the (non-expiring!) Access Token to be shared with a third party server. Why?!?

I recently learned that Stripe has been pushing OAuth (branded as "Stripe Connect") to its integration apps as the "more secure" solution, compared to Restricted API Keys. In fact, we've found that most integrations we've encountered that use Stripe Connect are less secure than using Restricted API Keys because the (private!) tokens are shared with a third party!

I've been using Stripe to handle credit card payments on my e-commerce website for years. Recently, we updated our wordpress e-commerce website and all its plugins. And then we discovered that all credit card payments were broken because our Stripe Payment Gateway plugin stopped allowing use of Restricted API Keys. Instead they only support "Stripe Connect" (which, afaict, is a marketing term for OAuth). This change forced us to do a security audit to make sure that the new authentication method met our org's security requirements. What we found was shocking.

So far we've started auditing two woocommerce plugins for Stripe, and both have admitted that the OAuth tokens are shared with their (the developer's) servers!

One of them is a "Stripe Verified Partner", and they told us that they're contractually obligated by Stripe to use only "Stripe Connect" (OAuth) -- they are not allowed to use good-'ol API Keys.

They also told us that Stripe REQUIRED them to include them in the OAuth flow, such that their servers are given our (very secret!) OAuth Access Keys!

The benefit of normal API Keys, of course, is that they're more secure than this OAuth setup for (at least) two reasons:

  1. I generate the API keys myself, and I can restrict the scope of the keys permissions

  2. I store the key myself on my own server. It's never transmitted-to nor stored-on any third party servers. Only my server and Stripe's servers ever see it.

Can someone shine a light onto this darkpattern? I understand that standardization is good. OAuth Refresh Keys add security (this service doesn't use them). But why-oh-why would you FORCE OAuth flows that share the (non-expiring) Access Tokens with a third party? And why would you claim that's more secure than good-ol-API-keys?

Does OAuth somehow not support server<-->server flows? Or is it a library issue?

What am I missing?

 

Why does Stripe require OAuth tokens to pass through a third party server?

Can someone who understands OAuth better than me explain to me why Stripe REQUIRES that their OAuth Access Keys get shared with a third party?

I've tried RTFM, but my biggest hangup is that the OAuth docs appear describe a very different situation than mine. They usually describe a user agent (web browser) as the client. And they talk about "your users" as if I have a bunch of users that I'm going to be fetching access keys for.

Nah, this is server <--> server. I have a server. Stripe has a server. I am one user. All I need is ONE API key for ONE account. But I'm forced to use OAuth. It doesn't seem appropriate, and it's especially concerning that the "flow" requires the (non-expiring!) Access Token to be shared with a third party server. Why?!?

I recently learned that Stripe has been pushing OAuth (branded as "Stripe Connect") to its integration apps as the "more secure" solution, compared to Restricted API Keys. In fact, we've found that most integrations we've encountered that use Stripe Connect are less secure than using Restricted API Keys because the (private!) tokens are shared with a third party!

I've been using Stripe to handle credit card payments on my e-commerce website for years. Recently, we updated our wordpress e-commerce website and all its plugins. And then we discovered that all credit card payments were broken because our Stripe Payment Gateway plugin stopped allowing use of Restricted API Keys. Instead they only support "Stripe Connect" (which, afaict, is a marketing term for OAuth). This change forced us to do a security audit to make sure that the new authentication method met our org's security requirements. What we found was shocking.

So far we've started auditing two woocommerce plugins for Stripe, and both have admitted that the OAuth tokens are shared with their (the developer's) servers!

One of them is a "Stripe Verified Partner", and they told us that they're contractually obligated by Stripe to use only "Stripe Connect" (OAuth) -- they are not allowed to use good-'ol API Keys.

They also told us that Stripe REQUIRED them to include them in the OAuth flow, such that their servers are given our (very secret!) OAuth Access Keys!

The benefit of normal API Keys, of course, is that they're more secure than this OAuth setup for (at least) two reasons:

  1. I generate the API keys myself, and I can restrict the scope of the keys permissions

  2. I store the key myself on my own server. It's never transmitted-to nor stored-on any third party servers. Only my server and Stripe's servers ever see it.

Can someone shine a light onto this darkpattern? I understand that standardization is good. OAuth Refresh Keys add security (this service doesn't use them). But why-oh-why would you FORCE OAuth flows that share the (non-expiring) Access Tokens with a third party? And why would you claim that's more secure than good-ol-API-keys?

Does OAuth somehow not support server<-->server flows? Or is it a library issue?

What am I missing?