Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App => Web support #51

Open
benjaminsavage opened this issue Oct 30, 2024 · 4 comments
Open

App => Web support #51

benjaminsavage opened this issue Oct 30, 2024 · 4 comments

Comments

@benjaminsavage
Copy link
Contributor

Many popular apps primarily display advertising in mobile applications, while conversions might be generated in either the system browser, or within an in-app-webview. If there was an OS-level impression store, and an OS-level privacy budget, it seems possible to support common user journeys like:

  1. Clicking on an ad in a mobile app, which opens in a Webview, where a conversion event is generated.
  2. Clicking on an ad in a mobile app, and later visiting the website in the system browser, where a conversion event is generated.

There are various technologies available on mobile platforms, including both Webviews (highly customisable) and "Remote Tabs" (not customisable). Meta's apps use the former. If this API does not support the App => Webview user journey, it will have very poor coverage of most user conversion journeys.

But there are various risks associated with enabling this API in webviews that must be mitigated:

  1. How to ensure a malicious app does not spend websites' privacy budgets without their consent (e.g. by injecting JavaScript into the webview that calls the measureConversion() API)
  2. How to ensure a malicious app does not utilise a webview to somehow multiply their own privacy budget (e.g. by automatically visiting large numbers of websites in an invisible webview and calling saveImpression() across all of them).

I would love to discuss mitigations to these risks, and to identify any other risks that might be present.

@martinthomson
Copy link
Collaborator

How to ensure a malicious app does not utilise a webview to somehow multiply their own privacy budget (e.g. by automatically visiting large numbers of websites in an invisible webview and calling saveImpression() across all of them).

I'm mostly concerned about measureConversion() here, not saveImpression(). The latter has no observable outcome.

Other than that, I can see how this could be important. My first impression (no pun intended) is that this is fundamentally quite challenging because access to the OS-level store for querying conversions depends critically on trusting the entity that asks to represent the identity of the true requester accurately.

To a first approximation, an app operating a webview need to be thought of as a browser when talking to the OS, so I'll talk about browsers and you can substitute "app" as needed.

If the browser stores impressions, then the browser can trust itself to know that the website is really the website it means (that's a core function of a browser). That's easy.

It's harder when the store is at the OS level. A browser needs to assert to the OS that this is really "example.com" that is spending privacy budget. The OS doesn't really have much hope of validating that claim unless it has some pretty extreme control over how the browser operates. This might be possible on iOS with their browser restriction, but on a platform without extreme restrictions, that's not going to hold.

We saw a similar example of this pattern of attack with passkeys. Any form of access to the device from an app gives that app the ability to assert that someone is accessing any website. Attackers were able to use WebUSB to spoof site identity and effectively bypass protections.

I can see a few options:

  1. Try to tie down webviews in some way so that claims about site identity can be validated. I don't know how to do that though.
  2. Develop a process for the platform to certify certain apps as "browsers". This might need to be paired with some set of rules and processes so that bad actors can get caught and punished.
  3. Require the use of "remote tabs" for conversions. This is likely to be regarded as infeasible, but it does avoid the problems associated with the app-OS distrust. It might even be the case that impressions can be saved by apps without use of remote tabs, so the customization problem only exists for conversions. I don't know whether you could bounce between the two; maybe our HTTP API proposal could make that possible.

@martinthomson martinthomson moved this to Essential in Level 1 API Nov 25, 2024
@martinthomson martinthomson closed this as completed by moving to Nice to have in Level 1 API Nov 25, 2024
@martinthomson martinthomson reopened this Nov 29, 2024
@benjaminsavage
Copy link
Contributor Author

Had one idea here. If we place zero trust in the web browser, then perhaps we can use a solution that involves the site generating a signature using its public key.

One approach for webviews (e.g. UIWebview on iOS) could be to disable the JavaScript API, and only enable the HTTP API (see #47 for some brainstorming here).

But we would need to add some kind of signature generated by the website's web-server. So the response might be something like:

302 Whatever
Location: https://example.com/save-conversion
Some-Custom-Header: delegation=<delegation-ID>,\
   aggregator=agg.example,histogramSize=20,\
   signature=f738a73bc6101cab037502bca53

where this is a signature generated using the website's private key, and which signs over all of the fields, including the delegation-ID.

Now a malicious app could at worst intercept and drop this call. It couldn't save signatures for use elsewhere since the delegation ID is expected to be unique.

@benjaminsavage
Copy link
Contributor Author

@martinthomson does this proposal seem like a way to achieve your option #1? The OS could be the one to validate the signature.

@martinthomson
Copy link
Collaborator

The basic shape of this might work. Though we'd need to work out more of the details.

Attacks that might need mitigation:

  • Replay or transplanting attacks, where the webview takes a valid signature and either plays the same value out multiple times or just moves it from one time to another. We'd need to ensure that the signature covers enough information to make this hard to do. (Covering the time is tricky though, because clocks are basically impossible to cover.)

  • Changes to the context in which a request is made that might convince a site to generate a request when it should not have. For instance, a malicious webapp might seek to site to register conversions at a time that is most advantageous to it. After all, the webview has complete control over what the site learns about the client. That's an attack on the conversion site that might need more thought.

  • How the keys are learned. Presumably we can do something with .well-known to signal which keys are valid for which purposes, which is probably enough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Nice to have
Development

No branches or pull requests

2 participants