privacycg / storage-access

The Storage Access API
https://privacycg.github.io/storage-access/
199 stars 26 forks source link

Make implicit and explicit deny indistinguishable #120

Open bvandersloot-mozilla opened 1 year ago

bvandersloot-mozilla commented 1 year ago

This is accomplished by adding a 2-minute timeout to reject an unfulfilled promise immediately before checking for implicit denies and not rejecting the promise when the implicit or explicit deny occurs.

I am open to hearing better ways to specify a timeout or Promise fulfillment testing.

I am also open to discussion of removing the timeout entirely and allowing the Promise to leak.


Preview | Diff

annevk commented 1 year ago

If this is accepted we should note in the commit message that it fixes #60.

bvandersloot-mozilla commented 1 year ago

So the idea here is that we still reject early for state-related reasons, such as there not being user interaction, but the user not answering or dismissing the prompt would result in rejection after two minutes?

Yes, exactly.

This algorithm running while "in parallel" is problematic as you shouldn't (can't) mutate state on the global while "in parallel", but that's probably a follow-up. Most things can probably move to the main thread except for actually asking the user.

:+1:

annevk commented 1 year ago

With this you cannot distinguish between the end user saying "no" and the end user saying nothing.

bvandersloot-mozilla commented 1 year ago

So what responses does the delay make indistinguishable, then?

Anne hit it pretty well in his comment.

It would be great if this change could come with an accompanying description of the threat and how we're mitigating it, e.g. in the Privacy & Security considerations.

Sure, I can add something in a subsection there.

johannhof commented 1 year ago

I don't think that that's accurate, and we should be precise about it to ensure we hit the goals outlined in https://github.com/privacycg/storage-access/issues/60#issue-689407570:

Implicit deny == the browser decides this third party is not allowed to request storage access and immediately rejects. This could be the result of policy or a user facing feature à la "Don't ask me again." Explicit deny == the user gets prompted and chooses "Don't allow."

So we want to ensure that sites cannot tell whether users have seen the prompt or whether browser policies restricted it. I think this PR does that by ensuring that implementation defined steps are rejected after the timeout, but I would like to be explicit about which steps we'd like to have covered under the timeout and which are fine to reject immediately.

In fact, I think if we had a way to reach this goal while still letting the site know whether the user has responded or is still pondering that would be beneficial, as this is a major usability issue for well-intentioned sites. We've learned this lesson on Firefox for Notification permission prompts which the user could leave invisibly dangling, so that sites would remain in limbo state after asking for permission. It was not nice. We could consider shortening the timeout to, say, 1 min or 30s to reduce that effect.

annevk commented 1 year ago

I discussed this further with John and he noted that always delaying the answer by a certain amount of time might leave the user with an unresponsive user interface. You click somewhere, you get a prompt, you reply, and then nothing happens (because the browser delays resolving the promise).

So instead we should probably look into delaying the case where we're not prompting with some randomized amount of time that looks identical to the user replying, but cannot be used for tracking.

bvandersloot-mozilla commented 1 year ago

Waiting on #121