Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Proposal for mozApps app.replaceReceipt() method

58 views
Skip to first unread message

Ian Bicking

unread,
Apr 25, 2012, 1:49:13 PM4/25/12
to dev-w...@lists.mozilla.org
One of the features of the Marketplace and receipt signing process is that
certificates can potentially expire, and in that case receipts signed with
those certificates should be updated (the receipt replaced with a new one
signed with a new cert).

Up until now the only way we've proposed to update the receipts associated
with an application is by reinstalling the application with a new list of
receipts. There are a couple problems I see with this:

(a) Right now reinstallation requires user confirmation. There's no
indication in the native doorhanger why the reinstallation is being asked
for, or what its effect would be. Even explaining the reason is rather
hard, how could you reasonably tell a user "the receipt's certificate is
being updated" so they could make an intelligent choice?

(b) If we want to suppress the confirmation dialog, we have to infer the
intent of the reinstallation. Do we check that the manifest URL hasn't
changed, and then if only the receipts changed we allow reinstallation
without confirmation? Does this mean a store could overwrite another
store's receipts without confirmation? Without an API that clearly
indicates intent it is hard to answer these questions.

(c) The update process isn't atomic, updating receipts means fetching
receipts and updating the list and then saving an entire new list. A race
condition here is kind of obscure, but if pressed I'm sure I could come up
with a scenario ;)


I would propose we add a new method to application objects,
app.replaceReceipt(oldReceipt, newReceipt). Either argument could be null;
app.replaceReceipt(null, newReceipt) adds a receipt,
app.replaceReceipt(oldReceipt, null) deletes a receipt. Receipts are
strings.

This ability to change receipts also adds a question of ownership. Right
now three entities can get an application object and receipts: the app
itself, the store that sold the app, and any dashboards. I do not see any
use case for the dashboard to update a receipt. We could allow a store to
modify any receipt, but if we treat the receipt as a parsable entity we
could also restrict the store to modifying only its own receipts (receipts
are JWT strings, and can be decoded to give the originator of the receipt,
though we are not currently validating receipts in any way).

For the case of updating a receipt with a new/fresh receipt, I imagine the
flow going like this:

1. User arrives at site, mozApps.getSelf is called, app sends receipt(s)
back via XHR
2. On the backend, the app makes a call to marketplace (via a verification
URL embedded in the receipt) to validate the receipt
3. The marketplace sees the receipt has expired or for some reason can be
refreshed without any user intervention, and gives a response to the
application with the new receipt that should replace the old one
4. The app's server responds to the XHR with the new receipt that should
replace the old one
5. This invokes client-side Javascript that calls
app.replaceReceipt(oldReceipt, newReceipt)

Another use case for this API would be purging old receipts that purchased
time-limited access (e.g., a subscription).

Slightly related (at least, writing this up made me think about it), I
think we should start parsing and validating receipts to some degree for
some fraud reasons: https://bugzilla.mozilla.org/show_bug.cgi?id=748826

Andy McKay

unread,
Apr 27, 2012, 12:58:51 PM4/27/12
to Ian Bicking, dev-w...@lists.mozilla.org

On 25/04/2012, at 10:49 AM, Ian Bicking wrote:
> For the case of updating a receipt with a new/fresh receipt, I imagine the
> flow going like this:
>
> 1. User arrives at site, mozApps.getSelf is called, app sends receipt(s)
> back via XHR
> 2. On the backend, the app makes a call to marketplace (via a verification
> URL embedded in the receipt) to validate the receipt
> 3. The marketplace sees the receipt has expired or for some reason can be
> refreshed without any user intervention, and gives a response to the
> application with the new receipt that should replace the old one
> 4. The app's server responds to the XHR with the new receipt that should
> replace the old one
> 5. This invokes client-side Javascript that calls
> app.replaceReceipt(oldReceipt, newReceipt)

Sounds good Ian. I think this API is essential for the idea of expiring receipts.

The only use case that I think is worth discussing is revocation. This is when all the receipts are invalid and need to be replaced for security reasons. This is a very rare case and will hopefully never happen. If this was to happen, should there any user interaction?

Ian Bicking

unread,
Apr 27, 2012, 1:34:44 PM4/27/12
to Andy McKay, dev-w...@lists.mozilla.org
I think in this case at step 3 the marketplace will need a way to tell the
app that the user needs to go to the marketplace to resolve problems with
the receipt. The app would send that back to the browser, and app client
code would redirect to the marketplace. E.g., the marketplace might
respond with:

{"status": "manual-reissue", "href": "
https://marketplace.mozilla.org/receipt-reissue/"}

That wouldn't directly effect a mozApps API, in that case the page at
/receipt-reissue/ would use this same replaceReceipt API to fix the
receipts (after requiring login and whatever else might be necessary).

Jim Straus

unread,
Apr 27, 2012, 1:45:24 PM4/27/12
to Ian Bicking, dev-w...@lists.mozilla.org
Hello Ian -
Just clarifying some points and a point.

On Apr 25, 2012, at 1:49 PM, Ian Bicking wrote:

> For the case of updating a receipt with a new/fresh receipt, I imagine the
> flow going like this:
>
> 1. User arrives at site, mozApps.getSelf is called, app sends receipt(s)
> back via XHR

Do we want to provide a Gecko service to handle the receipts? See below.

> 2. On the backend, the app makes a call to marketplace (via a verification
> URL embedded in the receipt) to validate the receipt

I assume this is the server backend or is the device app validating the receipt as well?

> 3. The marketplace sees the receipt has expired or for some reason can be
> refreshed without any user intervention, and gives a response to the
> application with the new receipt that should replace the old one

How does the marketplace give a response to the application on the device?

> 4. The app's server responds to the XHR with the new receipt that should
> replace the old on
> 5. This invokes client-side Javascript that calls
> app.replaceReceipt(oldReceipt, newReceipt)

This should probably not happen in the app, but in the Gecko App service.
-----
I presume that receipt verification is normally only done at the app provider's site? In thinking about it, should the receipt verification (from the app's perspective) be something that Gecko should provide as a service? mozApps.sendReceipt(url). The Gecko code could validate that the URL is associated with the app developer's domain. Or are there use cases where an app may want to send the receipt to arbitrary servers?

For security reasons we may not want the update transaction going through the app provider's site nor through the app itself. If we provide a reject with a specific type of "Update Receipt" to the server and that gets sent to the Gecko code, then the Gecko code kicks off a transaction with the market place. Once the transaction is complete, the sending of the receipts to the original server can be re-started. There may be a delay in this case, but hopefully receipt refreshes don't occur very often.

Anant Narayanan

unread,
Apr 27, 2012, 2:14:39 PM4/27/12
to dev-w...@lists.mozilla.org
Hey Jim,

On 4/27/12 10:45 AM, Jim Straus wrote:
> On Apr 25, 2012, at 1:49 PM, Ian Bicking wrote:
>> 2. On the backend, the app makes a call to marketplace (via a verification
>> URL embedded in the receipt) to validate the receipt
>
> I assume this is the server backend or is the device app validating the receipt as well?

Yes, this would be the app's server.

>> 3. The marketplace sees the receipt has expired or for some reason can be
>> refreshed without any user intervention, and gives a response to the
>> application with the new receipt that should replace the old one
>
> How does the marketplace give a response to the application on the device?

The app's server will receive a new receipt instead of a message
validating the receipt it made the request with (the normal flow). The
exact semantics of this return message are still TBD.

>> 4. The app's server responds to the XHR with the new receipt that should
>> replace the old on
>> 5. This invokes client-side Javascript that calls
>> app.replaceReceipt(oldReceipt, newReceipt)
>
> This should probably not happen in the app, but in the Gecko App service.
> -----
> I presume that receipt verification is normally only done at the app provider's site? In thinking about it, should the receipt verification (from the app's perspective) be something that Gecko should provide as a service? mozApps.sendReceipt(url). The Gecko code could validate that the URL is associated with the app developer's domain. Or are there use cases where an app may want to send the receipt to arbitrary servers?

Gecko may provide a convenience method like that and one of our early
prototypes did, but I think it is not useful in many cases. Free apps
will not want to do verification at all, and serious paid apps will want
to verify the receipt themselves. The local runtime (in this case,
Gecko) cannot be trusted by them - I can always run a modified WebRT
that always returns true for mozApps.sendReceipt.

> For security reasons we may not want the update transaction going through the app provider's site nor through the app itself. If we provide a reject with a specific type of "Update Receipt" to the server and that gets sent to the Gecko code, then the Gecko code kicks off a transaction with the market place. Once the transaction is complete, the sending of the receipts to the original server can be re-started. There may be a delay in this case, but hopefully receipt refreshes don't occur very often.

What are the security concerns around going through the app provider's
site? They are the ones who are most interested in the integrity of the
receipt, after all.

Regards,
-Anant

Ian Bicking

unread,
Apr 27, 2012, 2:22:59 PM4/27/12
to Jim Straus, dev-w...@lists.mozilla.org
On Fri, Apr 27, 2012 at 12:45 PM, Jim Straus <jst...@mozilla.com> wrote:

> Hello Ian -
> Just clarifying some points and a point.
>
> On Apr 25, 2012, at 1:49 PM, Ian Bicking wrote:
>
> For the case of updating a receipt with a new/fresh receipt, I imagine the
> flow going like this:
>
> 1. User arrives at site, mozApps.getSelf is called, app sends receipt(s)
> back via XHR
>
>
> Do we want to provide a Gecko service to handle the receipts? See below.
>

We attach receipts to the application object at install time. These
receipts are also stored at the Marketplace, and in the Apps-in-the-Cloud
server. To actually get the receipts you do:

navigator.mozApps.getSelf().onsuccess = function () {
if (! this.result) {
// the app isn't installed
return;
}
var receipts = this.result.receipts;
// then send the receipts via XHR or something
};


> 2. On the backend, the app makes a call to marketplace (via a verification
> URL embedded in the receipt) to validate the receipt
>
>
> I assume this is the server backend or is the device app validating the
> receipt as well?
>

To actually ensure the receipt is valid the application's backend server
does need to validate the receipt. If an application developer isn't as
concerned with fraud they could also rely only on client-side checking
(you'd need something like an addon or greasemonkey script to reliably
defeat client-side checking – not terribly hard, but not something
mainstream customers would be likely to do).


> 3. The marketplace sees the receipt has expired or for some reason can be
> refreshed without any user intervention, and gives a response to the
> application with the new receipt that should replace the old one
>
>
> How does the marketplace give a response to the application on the device?
>

Each receipt contains a URL that can be used to verify the receipt. You
can potentially verify the receipt cryptographically without asking the
marketplace, and you could tell that the receipt was expired though you
need the marketplace to actually reissue the receipt. Some cases like a
chargeback can only be detected by asking the marketplace.



>
> 4. The app's server responds to the XHR with the new receipt that should
> replace the old on
>
> 5. This invokes client-side Javascript that calls
> app.replaceReceipt(oldReceipt, newReceipt)
>
>
> This should probably not happen in the app, but in the Gecko App service.
>

I'm not exactly sure what you mean by Gecko App service. There's the
mozApps API, but I think you might mean something more?


> -----
> I presume that receipt verification is normally only done at the app
> provider's site?
>

Yes


> In thinking about it, should the receipt verification (from the app's
> perspective) be something that Gecko should provide as a service?
> mozApps.sendReceipt(url). The Gecko code could validate that the URL is
> associated with the app developer's domain. Or are there use cases where
> an app may want to send the receipt to arbitrary servers?
>

I'm sure there could be operational reasons to send it to arbitrary
servers, and potentially receipt verification could be a centralized server
service. For instance, I can imagine a static-HTML game hosting service
that might handle this verification centrally. Something that just
occurred to me, would be if the user agent could connect to the
Marketplace, have its receipts verified, and the Marketplace would respond
with some signed value with an expiration that was sooner than the receipt
as a whole. Then the user agent could send that with its requests as a
kind of authentication token, and the app server could stick to purely
cryptographic checks.

Also, we can definitely provide a library that handles some of this receipt
flow. I don't think it needs to be part of the DOM/Gecko API. But one of
the problems with packaging up server calls in an API is that developers
can be quite opinionated about what their servers receive, and how some of
that flow works. We had an experimental verifyReceipt flow that tried to
handle this, with a bunch of different sorts of hooks. We could revive it.


> For security reasons we may not want the update transaction going through
> the app provider's site nor through the app itself. If we provide a reject
> with a specific type of "Update Receipt" to the server and that gets sent
> to the Gecko code, then the Gecko code kicks off a transaction with the
> market place. Once the transaction is complete, the sending of the
> receipts to the original server can be re-started. There may be a delay in
> this case, but hopefully receipt refreshes don't occur very often.
>

For this case I guess my intuition is that Gecko is less secure than the
other components, so I'm not sure I see the advantage of going through the
user agent with everything. There might be situations I'm not thinking
about, but I am not sure how to respond without something more concrete.
Well, I can see some danger to XSS holes in the application allowing an
attacker to get other people's receipts, or simply to do vandalism by
deleting receipts.

Jim Straus

unread,
Apr 27, 2012, 3:48:00 PM4/27/12
to Anant Narayanan, dev-w...@lists.mozilla.org
Inline below:

On Apr 27, 2012, at 2:14 PM, Anant Narayanan wrote:

> Hey Jim,
>
> On 4/27/12 10:45 AM, Jim Straus wrote:
>> On Apr 25, 2012, at 1:49 PM, Ian Bicking wrote:
>>>
>
> Gecko may provide a convenience method like that and one of our early prototypes did, but I think it is not useful in many cases. Free apps will not want to do verification at all, and serious paid apps will want to verify the receipt themselves. The local runtime (in this case, Gecko) cannot be trusted by them - I can always run a modified WebRT that always returns true for mozApps.sendReceipt.
>
My original thought was that the receipt verification was for the site to make the decision to provide "paid" content to the app, not that the app was using the verification to ensure it was paid for on the device. I'm haven't looked at what is being returned after receipt verification from the market place, but if the reply isn't signed, it can be spoofed as well.

Frankly, if we're worried about malicious Geckos then I believe we have bigger problems. A modified WebRT could spoof almost anything. One way would be to ignore the manifest and modify the app code to not do the receipt checking, or change the signature it is looking for. Or even inject code to do the same.

>> For security reasons we may not want the update transaction going through the app provider's site nor through the app itself. If we provide a reject with a specific type of "Update Receipt" to the server and that gets sent to the Gecko code, then the Gecko code kicks off a transaction with the market place. Once the transaction is complete, the sending of the receipts to the original server can be re-started. There may be a delay in this case, but hopefully receipt refreshes don't occur very often.
>
> What are the security concerns around going through the app provider's site? They are the ones who are most interested in the integrity of the receipt, after all.

For example, the app developer's site could be compromised and receipts could be siphoned off. Depending on what is in the user field, this could lead to privacy concerns. I haven't gone through all the concerns, and it may not be an issue, but it just raised a flag for me.

> Regards,
> -Anant
> _______________________________________________
> dev-webapps mailing list
> dev-w...@lists.mozilla.org
> https://lists.mozilla.org/listinfo/dev-webapps

Benjamin Smedberg

unread,
Apr 27, 2012, 4:10:51 PM4/27/12
to Jim Straus, dev-w...@lists.mozilla.org, Anant Narayanan
On 4/27/2012 3:48 PM, Jim Straus wrote:
> Frankly, if we're worried about malicious Geckos then I believe we
> have bigger problems. A modified WebRT could spoof almost anything.
> One way would be to ignore the manifest and modify the app code to not
> do the receipt checking, or change the signature it is looking for. Or
> even inject code to do the same.
Isn't the whole point of a receipt that the relying party of the receipt
(in this case the app) can verify it? It seems that it would be
trivially obvious for anyone to make Firefox (and almost certainly any
other browser) to forge a "look, it's a good receipt"! answer. browserid
doesn't rely on the browser providing a "correct" identity answer: the
serving site verifies the identity. Presumably any app would need to do
the same.

--BDS

Andy McKay

unread,
Apr 27, 2012, 4:14:40 PM4/27/12
to Ian Bicking, dev-w...@lists.mozilla.org

On 27/04/2012, at 10:34 AM, Ian Bicking wrote:

> I think in this case at step 3 the marketplace will need a way to tell the app that the user needs to go to the marketplace to resolve problems with the receipt. The app would send that back to the browser, and app client code would redirect to the marketplace. E.g., the marketplace might respond with:
>
> {"status": "manual-reissue", "href": "https://marketplace.mozilla.org/receipt-reissue/"}
>
> That wouldn't directly effect a mozApps API, in that case the page at /receipt-reissue/ would use this same replaceReceipt API to fix the receipts (after requiring login and whatever else might be necessary).

That sounds fine. The messaging at that point should probably be up to the marketplace being used at that time.

Andy McKay

unread,
Apr 27, 2012, 4:16:00 PM4/27/12
to Jim Straus, dev-w...@lists.mozilla.org, Anant Narayanan

On 27/04/2012, at 12:48 PM, Jim Straus wrote:
>> What are the security concerns around going through the app provider's site? They are the ones who are most interested in the integrity of the receipt, after all.
>
> For example, the app developer's site could be compromised and receipts could be siphoned off. Depending on what is in the user field, this could lead to privacy concerns. I haven't gone through all the concerns, and it may not be an issue, but it just raised a flag for me.

The user detail is just a unique ID that makes sense to the marketplace, there's nothing in there of value to anyone else.

https://wiki.mozilla.org/Apps/WebApplicationReceipt

Anant Narayanan

unread,
Apr 27, 2012, 4:22:10 PM4/27/12
to dev-w...@lists.mozilla.org
On 4/27/12 12:48 PM, Jim Straus wrote:
> My original thought was that the receipt verification was for the site to make the decision to provide "paid" content to the app, not that the app was using the verification to ensure it was paid for on the device. I'm haven't looked at what is being returned after receipt verification from the market place, but if the reply isn't signed, it can be spoofed as well.

We do not provide receipts for in-app payments, and we don't provide
in-app "purchases". Hence, the primary purpose of a receipt is to let
the app developer verify that a user has paid for an app before letting
them access it.

The return values from the verification URLs at the Marketplace are signed.

> Frankly, if we're worried about malicious Geckos then I believe we have bigger problems. A modified WebRT could spoof almost anything. One way would be to ignore the manifest and modify the app code to not do the receipt checking, or change the signature it is looking for. Or even inject code to do the same.

Apps that really care about enforcing the availability of their content
to paid users only will perform this check at the server level.
Client-side receipt checks are meaningless, as you note.

However, as an app developer if I do not serve the HTML/CSS/JS from the
paid area of my app until after I've verified the receipt on my server,
compromised WebRTs can do little to bypass this. The core of the system
is based around the fact that nobody but the marketplace can generate a
valid receipt.

>>> For security reasons we may not want the update transaction going through the app provider's site nor through the app itself. If we provide a reject with a specific type of "Update Receipt" to the server and that gets sent to the Gecko code, then the Gecko code kicks off a transaction with the market place. Once the transaction is complete, the sending of the receipts to the original server can be re-started. There may be a delay in this case, but hopefully receipt refreshes don't occur very often.
>>
>> What are the security concerns around going through the app provider's site? They are the ones who are most interested in the integrity of the receipt, after all.
>
> For example, the app developer's site could be compromised and receipts could be siphoned off. Depending on what is in the user field, this could lead to privacy concerns. I haven't gone through all the concerns, and it may not be an issue, but it just raised a flag for me.

This was a valid concern when the receipt contained the user email
address. The identity team has since then recommended that the email no
longer be stored in the receipt, so I think there is very little risk in
giving access to these to the app server. Additionally, app servers
shouldn't be persisting the receipts on their servers in the first
place, of course we can't stop them from doing so, but it's added cost
for them that's unnecessary.

-Anant

Jim Straus

unread,
Apr 27, 2012, 11:44:25 PM4/27/12
to Anant Narayanan, dev-w...@lists.mozilla.org

On Apr 27, 2012, at 4:22 PM, Anant Narayanan wrote:

> On 4/27/12 12:48 PM, Jim Straus wrote:
>
> Apps that really care about enforcing the availability of their content to paid users only will perform this check at the server level. Client-side receipt checks are meaningless, as you note.
>
> However, as an app developer if I do not serve the HTML/CSS/JS from the paid area of my app until after I've verified the receipt on my server, compromised WebRTs can do little to bypass this. The core of the system is based around the fact that nobody but the marketplace can generate a valid receipt.

Ok, I know this is going way off topic, but I was thinking this through and came up with this scenario... I'm a developer with a high value app. I don't want people using it who haven't paid for it. The app has more value than just content from my site (I'm not including HTML. JS, etc as content). I can't trust the runtime environment. I think I'm screwed.

If I deliver the app through the store, a pirate can purchase it and then repost it with a different (unsigned) manifest. Given that all the functionality of the app is in the cache, it is easy to extract and re-purpose.

If I require a receipt to be delivered to my site and the site serves up the HTML, JS, etc. then a compromised runtime can save off the pieces and we're in the same place as the previous scenario. And such an app would be considered unsecure (since the server can deliver up whatever code at any time, so no store could validate that the app is using sensitive APIs in a valid manner).

This issue happens for Android as well (and here). Web apps are even easier than Android apps to pirate. Apple has less of an issue in this area by stint of having a single source for obtaining apps where it can validate that apps aren't a simple pirated version. And the apps being machine code are much harder to modify to be only similar.

Google is providing a license (receipt) verification service that the app can validate at a number of points in the application. This works ok (not great) for unmodified pirated apps. Unfortunately,in a WebApp it is even easier for a pirate to find and disable any such checks. And generally the runtime is considered secure on Android devices.

I don't have a good answer. But we probably need to think about this.

Anant Narayanan

unread,
Apr 28, 2012, 3:58:52 AM4/28/12
to dev-w...@lists.mozilla.org
On 4/27/12 8:44 PM, Jim Straus wrote:
> If I deliver the app through the store, a pirate can purchase it and
> then repost it with a different (unsigned) manifest. Given that all the
> functionality of the app is in the cache, it is easy to extract and
> re-purpose.
>
> If I require a receipt to be delivered to my site and the site serves up
> the HTML, JS, etc. then a compromised runtime can save off the pieces
> and we're in the same place as the previous scenario. And such an app
> would be considered unsecure (since the server can deliver up whatever
> code at any time, so no store could validate that the app is using
> sensitive APIs in a valid manner).

If all your app provides is a set of HTML/CSS/JS files that's fairly
self-contained and can be run with no interaction with your app server,
then you're right, it is very easy to pirate.

However, I think the general consensus so far has been that the real
value is in server-side services. If Angry Birds had a paid version of
their web app, it would be easy to make a pirated offline version, but
you wouldn't be able to post high scores on their website or challenge
your friends via a GameCenter-like service.

Similarly, apps like Netflix, New York Times, Crossword of the Day,
Multiplayer Games, and so on; all need to communicate with the app
server to be useful. If the app developer is paranoid enough, they will
ask for a receipt from the client every 15 minutes (the timeout for
Netflix is 20 minutes for their Silverlight client).

Now, the real problem with server-centric apps like these is receipt
sharing. Since we removed the user's Persona from the receipt and
replaced it with a unique identifier, one just needs to copy the receipt
over to another user's machine to let them use it.

This was possible before, only in a marginally more difficult manner,
i.e. by sharing Persona accounts with multiple people (not really that
different from sharing an account at any paid web service). The way
websites mitigate this today is by employing heuristics on the
server-side, for instance: tracking the IPs from which a single account
was accessed and blocking the ones which show unusual patterns. We
should recommend app authors to employ similar strategies with the
unique receipt IDs.

In my opinion, it is a futile effort to try and protect self-contained
apps (or "packaged" apps as some like to call them). The very nature of
HTML/JS/CSS prevents us from being able to do anything significant in
this realm, without getting into a serious Apple-like DRM strategy
(system certs and signed apps). We could consider doing something like
this for the most trusted ring on B2G in the interest of user safety,
but it would be an overkill and even detrimental to the open web if we
generalize such a system to all packaged apps.

-Anant

m1...@earthlink.net

unread,
Apr 28, 2012, 4:32:27 PM4/28/12
to dev-w...@lists.mozilla.org, Kumar McMillan
Adding Kumar McMillan, who might be interested.

Here are a couple bugs related to revoking receipts:

Bug 740830 - [Security Review][Action Item]In App Payment - AppSecret revocation/replacement
https://bugzilla.mozilla.org/show_bug.cgi?id=740830

Bug 738368 - Allow developers to revoke compromised in-app payment secret
https://bugzilla.mozilla.org/show_bug.cgi?id=738368

Here is an MDN page that gives general info about how in-app payments will work:
https://developer.mozilla.org/en/Apps/In-app_payments

No other comments from me below.

Mark



On 4/27/2012 1:22 PM, Anant Narayanan wrote:
On 4/27/12 12:48 PM, Jim Straus wrote:
My original thought was that the receipt verification was for the site to make the decision to provide "paid" content to the app, not that the app was using the verification to ensure it was paid for on the device.  I'm haven't looked at what is being returned after receipt verification from the market place, but if the reply isn't signed, it can be spoofed as well.

We do not provide receipts for in-app payments, and we don't provide in-app "purchases". Hence, the primary purpose of a receipt is to let the app developer verify that a user has paid for an app before letting them access it.

The return values from the verification URLs at the Marketplace are signed.

Frankly, if we're worried about malicious Geckos then I believe we have bigger problems.  A modified WebRT could spoof almost anything.  One way would be to ignore the manifest and modify the app code to not do the receipt checking, or change the signature it is looking for.  Or even inject code to do the same.

Apps that really care about enforcing the availability of their content to paid users only will perform this check at the server level. Client-side receipt checks are meaningless, as you note.

However, as an app developer if I do not serve the HTML/CSS/JS from the paid area of my app until after I've verified the receipt on my server, compromised WebRTs can do little to bypass this. The core of the system is based around the fact that nobody but the marketplace can generate a valid receipt.

For security reasons we may not want the update transaction going through the app provider's site nor through the app itself.  If we provide a reject with a specific type of "Update Receipt" to the server and that gets sent to the Gecko code, then the Gecko code kicks off a transaction with the market place.  Once the transaction is complete, the sending of the receipts to the original server can be re-started.  There may be a delay in this case, but hopefully receipt refreshes don't occur very often.

What are the security concerns around going through the app provider's site? They are the ones who are most interested in the integrity of the receipt, after all.

For example, the app developer's site could be compromised and receipts could be siphoned off.  Depending on what is in the user field, this could lead to privacy concerns.  I haven't gone through all the concerns, and it may not be an issue, but it just raised a flag for me.

This was a valid concern when the receipt contained the user email address. The identity team has since then recommended that the email no longer be stored in the receipt, so I think there is very little risk in giving access to these to the app server. Additionally, app servers shouldn't be persisting the receipts on their servers in the first place, of course we can't stop them from doing so, but it's added cost for them that's unnecessary.

-Anant

m1...@earthlink.net

unread,
Apr 29, 2012, 4:52:35 PM4/29/12
to dev-w...@lists.mozilla.org
Oops the bugs I mention below are for revoking app secrets for in-app payments, not for revoking receipts. Please pardon.

Mark

---------------------------------------------------------------------------------
0 new messages