I did not :) What I did and what we are still doing now, is simply re-fetch the subscription details when a notification comes in. I have some logging to detect if they are really different, just out of curiosity (they are usually the same, once in a while there is a difference when the user did something like disable and re-enable autorenew triggering several notifications). This isn't ideal, but it's the default practice for so it's not too bad. We'll fix it eventually..
Post
Replies
Boosts
Views
Activity
We started with an implementation that just fetched the subscription details from appstore server API using originalTransactionId after every notification, like you have to do on (that other mobile platform) by design, but we had wanted to remove the second step since if you validate the signature, you shouldn't need to do this. Now I'm glad we did it this way, but still it would be nice to get rid of the redundant fetching of subscription details since it shouldn't be necessary
I also filed a ticket about this with (parsed) notification data at FB11938220
With regards to notifications in particular, "man-in-the-middle" is the wrong term to use for various reasons, but for this discussion, the relevant point is that there is no "middle". This is a web call that your application is receiving, that it did not request. It has simply arrived. The developer's job is now to make sure it was sent by Apple and isn't coming from someone who is just using Postman and happens to know the endpoint you're using, and knows how to make a JWT with a self-signed certificate.
How was this answer marked as accepted, when the topic clearly includes notifications? The documentation linked to is just the existing documentation everyone already has access to, and doesn't address how to properly validate the certificate chain to secure notifications.
There should be needs to be a section in the documentation for how to validate this certificate chain properly. Many developers do not know how to do it, or even think they do but actually don't.
`X509 parsing is a minefield, and the tooling built around it (much of it bindings to OpenSSL) has far too many knobs for the average developer to build safe applications. If you are expecting developers to implement certificate chain validation, providing explicit instructions is a minimum requirement, and providing tooling to do so is preferable. This is a rule of thumb that extends to any situation in which you are asking developers to perform some cryptographic step: we must ask "what knowledge is needed to do this correctly?", "what is the impact of misuse or improper implementation?", and "how can we reduce or eliminate the risk caused by lack of developer cryptographic knowledge?".
Ideally, there should be no requirement that developers manually implement these steps: a service provider should maintain client libraries that implement all the necessary cryptographic checks without exposing intricacies to the developer when it's not necessary.`
https://duo.com/labs/research/chain-of-fools
Just adding a comment to my above comment here since apple forums don't seem to allow editing or deleting posts (!) - anyway, do not do this ! it's not enough, it's not verifying the certificate chain. Any certs except the root one could be spoofed and this would work
This node.js project might be doing this correctly, I am not a crypto expert to be sure:
https://github.com/agisboye/app-store-server-api/blob/main/src/Decoding.ts
I can't use this because I can't do the parts where x509 certificates are loaded and extract the public key / fingerprint. But maybe this will help you
The solution provided in the Sign In With Apple feature, where Apple provides an endpoint to get the public key in a format compatible with most JWT parsing libraries, is miles better than simply pointing developers to the generic CA page and no other guidance as to how to proceed from there.
By the way, some JWT libraries don't yet support verifying JWS with the self-contained x5c headers, so saying "just use your favorite crypto library" isn't enough here either. I'm locked on a platform that doesn't support this, but the solution provided by Sign In With Apple works fine for me. I am not going to roll my own crypto functionality for this :D
In the end I am using the notifications and just trusting the type and subtype but re-fetching the subscription status every time a notification comes in with the REST api. I suppose this is wasteful, and occasionally they might not match, but it's easy and it's what you have to do for Google's subscription notifications.