#khalil-paymentintent-id

1 messages ยท Page 1 of 1 (latest)

rigid urchin
#

Hey @boreal fable. It's fine to send those, it's kinda required since the id is inside the client_secret already.

But really there's no reason to send the pi_123 client-side, what you really want is the client_secret

boreal fable
#

Got it- I just noticed that the payment id is the first part of the secret. So then, my next question becomes why would I not just the pi_123? For more context, what I need is for the client to tell my server to check that I have inventory available right before executing the payment. Hence, I want the client to send to the server which payment id it wants to be validated

#

I could send the client secret back to the server and do a split to extract the payment id, but it seems unnecessary (and assumes a knowledge about client secret structure that stripe can change in the future)

rigid urchin
#

I mean you should never do any of this

#

1/ you shouldn't trust data from the client, anyone could change it for another PI
2/ you definitely should not split the client_secret. We don't guarantee the format, it could change at any time

#

Usually as the web developer you have a cookie/session that tracks what your customer is doing, which PI they are paying for, etc.

boreal fable
#

I have a session id stored in the browser of the client. The server has stored information about the line items corresponding to that session. The client sends the session id, and the server knows the current status of that session - Note that my users aren't logged in since we're talking about an e-commerce website

rigid urchin
#

even without logged in you can track your customer and store all of this in session server-side

#

I usually never trust client-side data

boreal fable
#

store all of this in session server-side That's what I am doing today. The only thing the client stores in its cookie is the session_id

#

Is this what you mean or am I misunderstanding you

rigid urchin
#

So in that case why do you need the pi_123 anywhere?

boreal fable
#

Good question. I will need to give you a bit more context then.

When the user clicks on submitPayment, I want to make a few final checks on the server side before allowing the payment element to submit the payment to stripe:

  • The client sends the session id for the server to verify that the inventory of the items are available
  • The client sends the payment intent id to the server. The server verifies that the id the client sent is the one the server has associated to that session. This case should never happen, but I don't know what I don't know so I am checking for it as a double safety step
#

Lmk if this makes sense, but I might be completely missing something

rigid urchin
#

yeah I mean you basically don't trust the id, you use it as a way to check that nothing is out of sync, so that seems fine overall!

boreal fable
#

Cool cool - As a somewhat related question, why do we use client secrets in the first place? Why would the server not just send to the client the payment id instead of a secret

rigid urchin
#

Because we want a separate value that is specific to that PaymentIntent that would be used client-side to confirm a payment attempt or retrieve it. It's always a separate value in that case

boreal fable
#

Sorry one second ... will come back

boreal fable
#
Because we want a separate value that is specific to that PaymentIntent that would be used client-side to confirm a payment attempt or retrieve it. It's always a separate value in that case

hmm ... What do you mean by separate in this context? Separate compared to what?

gusty frost
#

๐Ÿ‘‹ stepping in here

#

My colleague meant separating between the PaymentIntent Id (pi_xxx) vs the PaymentIntent secret (pi_xxx_yyy)

boreal fable
#

Why do we need to separate those is specifically my question... Why is it better to send a pi_xxx_yyyy as opposed to just the pi_xxx. I am failing to see what is the security/ authentication risk client_secret is solving

gusty frost
#

It makes some attack vector harder. For example if you have leaked PaymentIntent Id from your Dashboard (Id is all place around in Dashboard), the attacker can't just use it in a mass testing against you public site

#

It also makes the Payment Intent Id alone safe to share around

#

for example you can share any Payment Intent Id here and I can help on investigating

boreal fable
#

Ah got it! This makes sense a lot of sense then.

#

Is the client_secret meant to be impossible to forge (i.e like a password)? Can it be used by the client to send it to the server so that the server for example makes modifications to that specific payment intent with a guarantee that no one else could have sent it other than that client?

gusty frost
#

It's almost impossible to forge, like a password yes, but it's not meant to be used in the scenario you described. Even if you do that, how would your server verify that payment intent secret?

boreal fable
#

Hmm I guess querying Stripe payment intents and getting the one that has the right secret but I agree that's far from ideal - How about I tell you what I am trying to achieve instead?

gusty frost
#

Sure

boreal fable
#

I am using the orders API for my checkout. I have a two steps checkout,
1- first step I collect the address on the client, then I need to update my Order with that address so that I can compute the taxes and shipping costs. This can only happen on the server side (due to the API limitations)
2- On the next page, there is the final amounts displayed with the payment element.

Hence, I need to make sure that in step 1, the server can update the correct Order and no one can compromise that

#

Alos note that my users are non authenticated (it's an e-commerce website)

gusty frost
#

So in step 1 you were passing back the order's client secret from server to client, and thinking about passing it again to server to prove that this client is legit?

boreal fable
#

correct - in step 1, the server creates the order and passes (not passes back) the secret to the client.

#

And yes, I was thinking about passing it back to the server to prove the client is legit

#

(In the high level, I am trying to implement a basic secure two steps checkout for non authenticated users)

gusty frost
#

I think there are 2 scenario:

  1. The attacker caught your previous payload from your server -> client, and try to leverage that info to compromise your server
  2. The attacker didn't snip your previous payload from your server -> client, still try to compromise your server

For 1, I think pretty much you can't do anything other than rate limiting, since the attacker behaves exactly like your client. They have the data, the logic in your client, they can just do the same logic (But really what's the point of such an attack, other than mass DDOS)
For 2, you can simply use the order id, or use the order id secret as you wanted. It doesn't really matter because the attacker can't fake an order id they didn't know.

boreal fable
#

Can 1. even happen if I am in Https?

For 2, can an attacker forge an order_id? If not, then that seems easier to retrieve the correct order on the server side

#

By forging I mean can they start generating random ones until they find a good one

gusty frost
#
  1. would be harder with Https yes. SSL is already an extra protection level with its own hand-shake algorithm. Although browser is one-way SSL and maybe you don't want to go further by implementing a 2-way SSL in a websocket ๐Ÿ˜„
#

2 is theoretically not possible. But ideally nothing can stop you to generate an extra unique id on your own and expects your client to send both in. It would work similar to a session_id in any logged-in website

boreal fable
#

Makes sense, this was super helpful. You helped me identify my next steps

#

Thanks a lot for the help

#

Hope you enjoyed some of these more fundamental questions haha