Closed fluffy-critter closed 4 years ago
In your suggestion to only allow augmentations to the path, it's worth considering that the following user profile canonicalization may be worth supporting:
https://example.com/alice/
-> https://example.com/alice
is validI've considered this concern, but understood it to be okay as long as you treat the entire domain as a unit of trust. For https://example.com/alice/
to use IndieAuth safely, she must trust that example.com
will not be malicious and will not allow another URL on the same domain to impersonate her.
Such an assumption makes IndieAuth very suitable for single user per website, but it does not have good properties if it is to be used for multiple users per website. A change such as the one you're proposing can improve that aspect.
Hmm, yeah, I can see an argument being made for leaving off the terminal /
. I doubt it would come up in practice but it's good to be unambiguous.
I guess this goes down the rabbit hole of defining what's meant by a normalized path, or phrasing the concern in terms of path components or something.
And yeah the whole reason I proposed this change is because as it stands, IndieAuth is only suitable for one-user-per-domain situations, but there's definitely interest in getting IndieAuth support for multi-user systems like Mastodon, or old-school shared-domain sites like tilde.club/tilde.town et al.
And yeah the whole reason I proposed this change is because as it stands, IndieAuth is only suitable for one-user-per-domain situations, but there's definitely interest in getting IndieAuth support for multi-user systems
That makes sense.
To be thorough, I'll mention that since a subdomain is a part of the domain, IndieAuth is currently also suitable for one-user-per-subdomain situations. For example, https://alice.example.com/
can be safe knowing that https://bob.example.com/
could not impersonate her in the manner described in the original issue.
Oh, sure, but subdomains aren't the concern behind this proposal. :)
(Which is to say that in the context of IndieAuth -- or anything else, for that matter -- there's no difference between a domain and a subdomain. Strictly speaking, foo.com
and bar.com
are both subdomains of com
.)
The original issue talks only about differences in the URL path. Another case to consider is URLs that differ only in the query component. E.g.:
https://example.com/users?id=100
-> https://example.com/users?id=101
is valid or not valid?https://example.com/users?id=100
-> https://example.com/users?id=100&group=2
is valid or not valid?And that opens up a whole slew of things to wonder about, like given https://example.com/user/bob?foo=bar
what about https://example.com/user/bob/profile
That said, the path specificity already implies authoritative control over the path itself; it doesn't seem likely to have a situation where different users would have different control over the identity response given the same path but different query paremeters. Any situation where that is the case is not, IMO, worth caring too much about. To that end I think that the query component should be ignored in the comparison.
Now, to clarify the situation I'm worried about here, let's say you have a shared domain with old-fashioned https://example.com/~username
URLs that map to a public_html
directory, or generally anywhere that people have some control over the HTML <head>
and/or response headers. You want to prevent people from being able to authenticate themselves as other users on the same domain. For example, Alice has a webpage at https://example.com/~alice/
with:
<link rel="authorization_endpoint" href="https://example.com/cgi-bin/indieauth.cgi">
where indieauth.cgi
, say, uses PAM credentials to verify the profile URL. Meanwhile, Bob has a webpage at https://example.com/~bob/
with this HTML:
<link rel="authorization_endpoint" href="https://bogus-indieauth.example.com/">
where bogus-indieauth.example.com
is a rogue endpoint that allows people to specify any final me
URL they want (for example, https://github.com/fluffy-critter/AnyAuth/).
This isn't just theoretical. I have a proof of concept at https://tilde.club/~fluffy which points to an AnyAuth instance as the authorization endpoint. Sign into any IndieAuth site using that URL, and most clients will let you identify as any tilde.club user, under the current validation rules.
I've actually had this up and running for quite some time now (which is to say, since roughly last October). This is a serious flaw in the specification.
That URL (https://tilde.club/~fluffy/) broke with https://publish.koype.net. That's because I grab the token endpoint that's used in the returned profile to verify the token (which fails).
Yeah, that page doesn't declare a token endpoint. But anything which only does indieauth for identity verification, for example webmention.io, lets me log in appearing as any tilde.club user.
It does limit the scope of the issue somewhat but it's still a problem for anything that uses just IndieAuth without tokens, and this is why in Authl I opted to implement the profile URL validation per the suggestion in the original issue.
That said, I suppose that one possible alternative to codifying stricter URL validation would be to verify that the target profile has the same authorization_endpoint
. I can't readily think of any issues with that, but I also don't have a very good imagination when it comes to security stuff.
So okay maybe the solution is adding the following to the end of s7.1 (differing profile URLs):
If the resulting profile URL differs from the initially-entered profile URL, the client SHOULD verify that the resulting profile URL declares the same
authorization_endpoint
. This prevents users on a shared domain from forging their identity as being another user of that domain.
The spec as currently written says:
However this has a security concern in the case of a website with multiple users on a single domain; for example, given sites
https://example.com/alice/
andhttps://example.com/bob/
, thebob
user could provide an IndieAuth authorization_endpoint that maliciously verifies all codes with ame
ofhttps://example.com/alice
.The specification should instead only allow augmentations to the path; for example:
https://example.com/alice
->https://example.com/alice/
is validhttps://example.com/alice/
->https://example.com/alice/blog/
is validhowever,
https://example.com/bob
->https://example.com/alice
is not validhttps://example.com/bob
->https://example.com/bob_has_bad_security
is not validhttps://example.com/bob
->https://example.com/bob/../alice/
is not validPossible phrasing:
"The response URL's normalized path is strictly the same as or within a subdirectory of the provided identity URL's path"