• Resolved maltfield

    (@maltfield)


    Does this plugin use OAuth to connect to Stripe?

    I’m a bit concerned that this plugin might use OAuth to connect to Stripe. If poorly implemented, OAuth could be much less secure than using Restricted API Keys.

    If you are using OAuth, then:

    1. Where are the access tokens, refresh tokens, and any other applicable tokens being stored?
    2. Is there any data that is stored on any server other than servers owned by me and servers owned by Stripe?
    3. Is there any data that is passed-through (not stored, but in-transit) any servers other than servers owned by me and servers owned by Stripe?

    If use of this plugin might involve any data that is stored or passed in-transit through any third party servers (other than my wordpress server and Stripe’s servers), then I need you to

    1. Enumerate all of this type of data
    2. Enumerate all of the third party servers
    • This topic was modified 1 year, 1 month ago by maltfield.
Viewing 13 replies - 1 through 13 (of 13 total)
  • Plugin Author Clayton R

    (@mrclayton)

    Hi @maltfield

    Does this plugin use OAuth to connect to Stripe?

    Yes, when connecting to live mode, you are required to use the Connect process, which is a form of OAuth.

    1. The WordPress options table
    2. No, Stripe stores your payment and customer information. Some data is stored in your WordPress tables. There are no other locations where information is stored.
    3. No

    There are no 3rd party servers where data is stored. The only servers that this plugin communicates with are Stripe’s servers via the Stripe API.

    Kind Regards

    Thread Starter maltfield

    (@maltfield)

    Does this plugin pass any of the OAuth tokens through any third party servers?

    There are no 3rd party servers where data is stored. The only servers
    that this plugin communicates with are Stripe’s servers via the Stripe
    API.

    I know you said that the tokens are *stored* in the wordpress options table. This is great.

    But, unfortunately, I recently learned that another woocommerce payment gateway for Stripe (Stripe Payment Plugin for WooCommerce by WebToffee) uses the plugin developer’s server (verify-stripe.webtoffee.com) to refresh the OAuth tokens, and then send the new refresh/access tokens back to the wordpress server.

    Even though the tokens are stored *only* on my wordpress server (they are *not* stored on WebToffee’s servers), they are still *seen* by a third party (besides [1] my server and [2] Stripe). This is obviously a security risk, and I don’t know how common this sort of implementation is.

    So I need you to be clear and address not just where the tokens are stored, but also where the tokens *touch*.

    Does this plugin implement OAuth by having *any* OAuth tokens transit through *any* server other than [a] the wordpress server where this plugin is installed and [b] Stripe’s servers?

    • This reply was modified 1 year, 1 month ago by maltfield.
    • This reply was modified 1 year, 1 month ago by maltfield.
    • This reply was modified 1 year, 1 month ago by maltfield.
    • This reply was modified 1 year, 1 month ago by maltfield.
    • This reply was modified 1 year, 1 month ago by maltfield.
    • This reply was modified 1 year, 1 month ago by maltfield.
    Plugin Author Clayton R

    (@mrclayton)

    to refresh the OAuth tokens, and then send the new refresh/access tokens back to the wordpress server.

    Reading through that support thread, that’s an odd explanation to me. There shouldn’t be any need to “refresh” any tokens because they don’t expire if the oAuth process is done correctly. There is no reason why a 3rd party server would need to perform any kind of token refresh, so I would be very cautious of any solution doing that.

    You had mentioned in previous support requests that the use of oAuth was a no go for you and your organization. For that reason, I don’t think our solution is going to be the right one for you since the Connect flow is required in the live environment.

    Kind Regards

    Thread Starter maltfield

    (@maltfield)

    You had mentioned in previous support requests that the use of oAuth was a no go for you and your organization.

    It’s not a total “no-go” (we’ve had to change our requirements because I can’t find any reputable plugins that support Restricted API Keys), but it does add additional work for us to audit the implementation. And that’s what I’m doing now.

    Can you please answer the question? Not just for my benefit, but for other users as well. It would be good to have a clear confirmation from the plugin author that your plugin does not pass any oauth transactions through a third party server.

    Does this plugin implement OAuth by having *any* OAuth tokens transit through *any* server other than [a] the wordpress server where this plugin is installed and [b] Stripe’s servers?

    • This reply was modified 1 year, 1 month ago by maltfield.
    • This reply was modified 1 year, 1 month ago by maltfield.
    Thread Starter maltfield

    (@maltfield)

    There shouldn’t be any need to “refresh” any tokens because they don’t expire if the oAuth process is done correctly.

    Best-practice of OAuth is to use (one-time-use) Refresh Keys (and short-lived Access Tokens). It’s not a requirement for our org, but it would be good to have this documented.

    Can you confirm that your plugin’s OAuth Access Token for Stripe has no expiration?

    • This reply was modified 1 year, 1 month ago by maltfield.
    • This reply was modified 1 year, 1 month ago by maltfield.
    Plugin Author Clayton R

    (@mrclayton)

    @maltfield Here is how the process works. Using this information, you can make a decision on whether this is the right solution for you or not.

    1. Admin clicks the Connect button which redirects the user to the Stripe hosted https://connect.stripe.com/ domain.
    2. Admin enters their authentication information and Stripe verifies the credentials.
    3. After credential validation, Stripe redirects the browser to https://stripeconnect.paymentplugins.com. It is here that the single use token from Stripe is exchanged for a secret key and publishable key. These keys are not stored anywhere; they are created and added as part of the redirect to the WordPress site. It must be done this way and our team worked internally with Stripe’s engineering team to develop this process.
    4. Browser then redirects back to the WordPress dashboard where the secret key and publishable key or stored in the WordPress options table. A refresh token isn’t used in this authentication scheme. The secret key and publishable key generated during the authentication process are just like the restricted keys you can manually create. They do not expire. The difference between these keys and restricted keys is they are never visible or accessible via the stripe.com dashboard. They are never revealed by Stripe.

    You can audit the plugin code and see that no other API is ever called by this plugin beyond connect.stripe.com and api.stripe.com.

    Kind Regards,

    Thread Starter maltfield

    (@maltfield)

    Thanks for the fast response 🙂

    After credential validation, Stripe redirects the browser to https://stripeconnect.paymentplugins.com.
    It is here that the single use token from Stripe is exchanged for a
    secret key and publishable key. These keys are not stored anywhere; they
    are created and added as part of the redirect to the WordPress site. It
    must be done this way and our team worked internally with Stripe’s
    engineering team to develop this process

    Yeah, so this has the same issue. Sorry for my ignorance, but I don’t see anything about OAuth that says a third party would need to be involved like this. Why couldn’t you replace the stripeconnect.paymentplugins.com part with my-wordpress-site.com/wp-content/woo-stripe-payment/handle-oauth.php?

    It seems unnecessary to the OAuth spec and an additional security risk for my non-expiring Access Tokens to pass through your infrastructure 🙁

    I know you say Stripe forces you to do this, so it’s not your fault. It’s theirs. Can you perhaps direct me to the Stripe documentation that says why the OAuth access tokens must pass through a third party?

    • This reply was modified 1 year, 1 month ago by maltfield.
    Plugin Author Clayton R

    (@mrclayton)

    Why couldn’t you replace the…

    Because that is not how Stripe implemented their connect flow internally. They require a connect redirect url to be configured and that url is a predefined value. Stripe doesn’t allow a redirect to a dynamic url.

    Can you perhaps direct me to the Stripe documentation that says why the OAuth access tokens must pass through a third party?

    Here is Stripe’s OAuth reference documentation. https://docs.stripe.com/connect/oauth-reference

    Here is where it discusses Stripe’s requirement to use a predefined uri. https://docs.stripe.com/connect/oauth-reference#redirect-uri

    Kind Regards,

    Thread Starter maltfield

    (@maltfield)

    Thanks. That has been extremely elucidating.

    So my understanding is that Stripe is abusing the wrong OAuth flow for this use-case 🙁

    If they implemented the “Client Credentials Flow”, then there would be no need to have a third party with a “predefined uri” of any kind.

    • This reply was modified 1 year, 1 month ago by maltfield.
    Plugin Author Clayton R

    (@mrclayton)

    So my understanding is that Stripe is abusing the wrong OAuth flow for this use-case 

    That is not my interpretation of Stripe’s implementation but if you have concerns then I would recommend reaching out to Stripe’s support team and expressing that to them. They are very good about looking into customer feedback.

    Kind Regards

    Thread Starter maltfield

    (@maltfield)

    I do plan to reach out to Stripe, but first I need to understand the situation a bit better. Thank you for your help so-far.

    So as far as I can tell, the issue here is that Stripe is using the wrong OAuth Flow.

    Currently it appears that Stripe is using an “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):

    This isn’t the appropriate flow for this plugin. And, as documented above, it exposes your users (and you too!) to unnecessary risk.

    The appropriate OAuth Flow that you *should* be using here uses the “Client Credentials” Grant, as documented in RFC 6749 Section 4.4 (Client Credentials Grant):

    The Client Credentials Flow is Machine-to-Machine. There is no need to have any redirect_uri of any kind (static or dynamic), and there is no need to include a third party’s servers in the OAuth flow at all.

    Can you think of any reason why Stripe opted for the less-appropriate Authorization Code Grant here — which exposes you and your users to unnecessary security risk?

    Edit: If you really want to include the User Agent, another OAuth flow would be the Implicit Flow — which also does not require leaking the access token to an intermediary. This is documented in RFC 6749 Section 4.2 (Implicit Grant):

    • This reply was modified 1 year, 1 month ago by maltfield.
    • This reply was modified 1 year, 1 month ago by maltfield.
    • This reply was modified 1 year, 1 month ago by maltfield.
    • This reply was modified 1 year, 1 month ago by maltfield.
    • This reply was modified 1 year, 1 month ago by maltfield.
    Thread Starter maltfield

    (@maltfield)

    This article (Common OAuth Vulnerabilities) by Doyensec is also 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.

    That explains a lot! As it makes sense that you’d want to expose the token to a third party if you *don’t* want to expose it back to us. But, again, this makes no sense for Stripe Connect — where you (the third party) delete the token and then just pass it right back down to us.

    Clearly, Stripe is using the wrong OAuth Flow here.

    Thread Starter maltfield

    (@maltfield)

    Hi,

    Can you please state what OAuth Flow you use for Stripe Connect with this application?

    After much research and back-and-forth with Stripe Support, they said admitted that some OAuth flows expose the OAuth bearer tokens with a third party (which is a security risk) and some other OAuth flows do not.

    They said that merchants cannot control which OAuth flow is used, and it depends on what was implemented by the developer. Stripe support asked me to ask the developer which OAuth flow they use in their implementation of Stripe Connect.

    Can you please tell us which specific OAuth flow you use for Stripe Connect in this application?

    Thank you

Viewing 13 replies - 1 through 13 (of 13 total)

The topic ‘Does this plugin use OAuth?’ is closed to new replies.