-
Notifications
You must be signed in to change notification settings - Fork 0
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
Skip the .well-known check for Registered IdPs #4
Comments
I filed #9 as a suggestion for an alternative way to tie the provider to the eTLD+1 I'm curious about whether the IdP registration would be enough to avoid the tracking concerns that this requirement prevents though! |
We are aware it is a pretty unsatisfying constraint. We have a few options that aren't perfect, but could relax this some. First, there is w3c-fedid/FedCM#552 allows multiple configURLs if you can have all of the IdPs share the same accounts endpoint. Would that help? Second, @bvandersloot-mozilla lightweight credentials would also allow us to skip the .well-known file at least for the accounts endpoint. Can you expand a bit more on your use case and give us a concrete sense of what your requirements are? |
I don't have huge issues about the eTLD+1. I just found it a bit confusing to build, because the Edit: Sorry I mixed up the @anderspitman wouldn't this be solved in your case if users just host their own |
I don't think this solves it. The core problem is that anything other than eTLD+1 isn't allowed at all. I need eTLD+2+ to work.
For sure. I've now deployed this feature to the LastLogin staging server: https://lastlogin.net/login. If you go there and make sure you have at least one identity, then click the "Domains" button to try this out. If you add an eTLD+1 on that page, you should get full OIDC, IndieAuth, and FedCM+IndieAuth functionality on your domain. If you add an eTLD+2+, you only get OIDC and IndieAuth, and FedCM doesn't work, I'm assuming because of the well-known eTLD+1 rule. |
I believe this work technically work, but it's exactly the UX situation I'm trying to avoid. My target users may have no idea how to host a web page, let alone FedCM metadata. They may not even know how to set DNS records. By integrating LastLogin with my other service TakingNames.io, I can implement a system that lets users easily register a domain, and set up their own decentralized IdP, all without ever needing to understand DNS, TLS, HTTP, HTML, CSS, JavaScript, IPs, hosts, FedCM, etc, etc. But this will only be feasible if they can delegate a single subdomain to LastLogin. If they're required to use an eTLD+1, now every user has to buy at least 2 domains, assuming they want to delegate to any other services (and I hope they will). |
To explain why this is not possible, I can recap the attack which is explained elsewhere. If we allowed well-known to be hosted in an arbitrary subdomain, then an IDP can track the user:
I think lightweight credentials could be useful here (though I am not familiar with the latest status), or in general some account caching such that you do not need a credentialed fetch to show the FedCM UI. |
@npm1 I agree this is important and needs to be mitigated. My question is whether #2 already mitigates this. Currently in order for a user to enable IdP registration for a domain, they have to click a button or similar and trigger a consent popup that says "login.anderspitman.com wants to use your accounts to login to websites". But it won't work because it's not an eTLD+1. I'm wondering if clicking Allow on that popup could be considered sufficient interaction to bypass the eTLD+1 rule specifically for domains the user has consented to use for login. All other domains would still be subject to the current rules. |
There could even be an additional disclaimer in this case that says "This will allow login.anderspitman.com to know which apps you're logging in to". |
My opinion is that IdP registration is not sufficient to mitigate this. A user agreeing to use an IdP should not imply that that IdP can know all sites the user visits, even those they do not log in to with that IdP. |
As was noted earlier, and:
If they can delegate a domain, your users must know how to set up CNAME DNS records. If they can set up DNS records, would #9 suffice to you? |
I'm going to give this a try!
This doesn't seem right: I have a FedCM+IndieAuth server running on https://sso.sgo.to, which is not a etld+1 (another example here: https://sso.mfoster.social). The FedCM endpoints have to be same-site with the .well-known file, but they (as opposed to the .well-known file) don't have to be in the eltd+1. Could you allow users of lastlogin to specify a subdomain (e.g. lastlogin.sgo.to)? What's necessary is for the .well-known file to be in the eltd+1 (and for it to point to the endpoints), but the lastlogin endpoints don't have to be. See examples here: https://sso.sgo.to/test/fedcm.json |
Wait, how would non-logged-in sites be exposed? |
Not necessarily! I don't think users should have to understand how any of this works. They should be able to do a quick OAuth flow to delegate control of a [sub]domain to a third party. See DomainConnect for an example of a protocol that can be used for this. Unfortunately that one ended up pretty big-tech focused. I developed my own protocol called NameDrop, which is implemented by TakingNames.io. It's much more friendly for indie hosters. See here for a demo video. That said, maybe LastLogin can use the NameDrop access token to set up the proper DNS records as proposed in #9. It's still unclear to me whether that would be sufficient. I'll describe an example below and maybe you can help me decide.
This is still too constrained for what I'm trying to do. Here's an example:
Sometime later, the user hears about how they can run their own IdP on LastLogin.
The problem here is that example.com is completely managed by ghost.org. LastLogin has no control over what is hosted there. Potentially #9 could fix this if the user grants control to login.example.com and example.com for LastLogin, but now you have 2 third parties that could potentially interfere with each others' DNS configurations. This might be mitigated by only granting LastLogin control over a single TXT record for example.com, but now the UX becomes more cluttered and the implementation more complicated. |
Yeah, that's what I was imagining: ghost.com could grant to LastLogin the ability to change TXT (and even, specifically, a We can't allow .well-known files under subdomains because, as you already figured out in w3c-fedid/FedCM#230, it can cause a tracking vector. @bvandersloot-mozilla 's https://github.com/fedidcg/CrossSiteCookieAccessCredential is also another option that I think is worth exploring to solving this problem.
As @npm1 pointed out, this is likely not going to hold up, because it becomes a 1-prompt global permission (as opposed to for every RP/IdP pair) cross-site tracking vector: by accepting a single permission, the user is granting the ability for a website to track you across every site on the web (remember, we have to deal with abusive worse case scenarios, not well meaning IdPs). Game theoretically, every ad network is going to ask for the user's permission here, which pushes browsers to make the permission sufficiently scary in a race to the bottom, so we never explored this option much further. |
🫤
Thanks, I'll take a look.
Want to make sure I understand the attack here:
Am I missing anything? |
It is in my comment https://github.com/fedidcg/FedCM/issues/613#issuecomment-2158633033, the third step. To be more precise, it will learn about any site the user visits which invokes FedCM with that particular IdP
That's not the attack. I'm not sure how you go from (4) to (5), as the IdP would know the user ID abcd but would not know the RP badapp.com. The accounts fetch intentionally does not expose the RP. As a side note, the RP is not necessarily bad. |
You're right, my proposed attack makes no sense. The attack you describe requires a separate subdomain for each RP, right? Wouldn't the user have to visit every subdomain for every RP and register FedCM in order to be tracked at each of those RPs? |
If I'm wrong about that, would you mind giving a somewhat more detailed run through of the steps for this attack, in the context of the new Sorry I'm not getting this. For some reason I'm finding it very difficult to reason about. |
Oh, wow, I think you are actually right! I was trying to write down the steps for this attack, but I think you may actually be right: there isn't any! The IdP has to register the So, the browser, while expanding the This is quite exciting to me, because maybe it could turn obsolete #9 and w3c-fedid/FedCM#589, for registered IdPs. Do you mind if I rename this issue "Skip .well-known for registered IdPs"? Else, I could kick another issue off to track this more generally for all registered IdPs (rather than, specifically, for multi-tenant situations).
The
There is a chance you are having a hard time convincing yourself because we are actually wrong :) Thanks for asking this thought provoking question and keep asking for clarification questions: my intuition at the moment is that you are right. |
Yea apologies, I wrote the general attack but it does not apply to IdP registration since you only register one configURL at a time, so there is no way to encode the RP there ahead of time. I think I agree that skipping the well-known check seems feasible for registered IdPs. Let us know if this would be useful/solve your issue here |
Yes that would be excellent! I have the same plans to offer this as a service, and it would vastly simplify the setup to avoid the well-known! It would also simplify the enterprise use case I am working on since we are often in a similar position where the company's marketing team or external agency runs the |
We were starting to party but @johannhof pointed out that the fact that the IdP can encode the user ID as per https://github.com/fedidcg/FedCM/issues/613#issuecomment-2159152621 could indeed be an issue. Then the client metadata fetch becomes essentially 'credentialed' (since the URL can encode the user ID) so it leaks both RP and user ID to the IdP in the same fetch (game over). Even if we got rid of this fetch (since the RP may want to provide their own PP/TOS when using registered IdPs), having the configURL be effectively credentialed makes our privacy much weaker. For instance, right now we do not need to show UI if the config fetch fails, but we would in this scenario (it would introduce a timing attack from the config fetch itself!). Therefore, we might need to go back to the drawing board... |
Ok, @johannhof found a possible complication, which I think is avoidable, but a complication nonetheless: it turns every FedCM request into, effectively, a credentialed request, because the IdP can annotate the user id in it: // Registers as a "foobar" type of provider
IdentityProvider.register("https://idp.example?user_id=1234") So that, then, a colluding RP, could call: navigator.credentials.get({
identity: {
providers: [{
type: "foobar"
}]
}
}); Which would, at some point, lead to a request to the If you look at the list of requests FedCM makes, the So, here is one attack:
This specific attack could be addressed if we required something like #8. But, more generally, it would make every single FedCM that is currently uncredentialed into a credentialed one, from a privacy thread model perspective. Because of timing attacks, I think this complicates things a bit. I think it is still plausible, but not as trivial as I hoped for. |
Ok, just thinking out loud here online ...
There are two options that occur to me: (a) make the IdP register the entire payload of the The former would look like something like this: IdentityProvider.register({
accounts_endpoint: "...",
id_assertion_endpoint: "...",
types: ["foobar"],
branding: { "..." }
}); This could work but would be unsatisfying in the sense that, e.g., it would require another call to add more The latter is also plausible, but requires more thought. |
This turned into quite a roller coaster! But it sounds like there's still hope which is awesome. I'm glad you guys understand all the nuances a lot better than me. As far as client metadata specifically goes, that never interested me and I'm glad it's optional, since otherwise I would have to fake it for LastLogin, since unregistered clients are a core feature. For the general case, there's no way we can prevent IdPs from encoding a user ID while allowing subdomains, because even if browsers were to reject path/query in the URI, it could still be encoded in a subdomain part, right? |
I believe (a) would be sufficient for me. Seems like a small price to pay for subdomain support for my case at least. Also one less round trip, and you know how I feel about round trips. |
Sorry forgot to answer this. Feel free to change the title to whatever you prefer. |
So, if skipping the client metadata (and the privacy policy and terms of service links) is cool with you, then I think we have a good solution here, because we can handle the silent timing attack. To sum up, the proposal here is to:
And with that, I think we would get:
The downsides are:
|
Sounds mostly correct to me.
Hmm why is that? The IdP could still itself have well-known / client_metadata files if it wanted to, they just would not be used at all if the IdP is used as a registered IdP. |
This is fantastic. I believe it would cover everything I need. Thank you! |
My only concern with bypassing the client metadata was that we had been thinking about using it to allow the IdP to decline showing UI on certain RPs. But maybe this feature is not needed for registered IdPs? |
Interesting use case. What's an example where an IdP would want to do that? Kind of feels like the IdP interfering with the RP UX. |
If the IdP does not want it associated with... certain sites, they could choose to tell the browser that so that no UI is shown and the request will be rejected. I was trying to find the issue where this was requested but failed. But I promise I didn't just make it up :) |
Ah that makes sense. The IdP could still reject the login at a later stage, but the user might be left with the impression that the IdP is affiliated with the RP. |
Sorry if this is already covered somewhere, I did a search and read through several of the existing issues and I'm still uncertain.
I'm working on a feature for LastLogin that would allow users to bring their own domain and use it as an IdP on our servers. This works fine for OIDC/IndieAuth, but according to the FedCM docs, the
/.well-known/web-identity
file has to be served at eTLD+1 of a domain.I read through w3c-fedid/FedCM#230 and I'm pretty sure I understand the gist of the reasoning for this requirement. However, this would prohibit my users from using a subdomain, ie
idp.example.com
. It's very likely they wouldn't want to commit an entire domain to their IdP, so this creates a rather large problem for me. Is there any way around this currently?If not, since this feature would only be applicable for IdP registration (#240) cases anyway, could the act of registering an IdP be considered sufficient consent from the user to create an exception to the .well-known rule and allow hosting on a subdomain?
I suspect at least @zicklag, @erlend-sh, and @sebadob would also be interested in this functionality.
The text was updated successfully, but these errors were encountered: