-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Resolve user to stable unique ID in policy #2205
Conversation
@micolous would be great if you can take a look at this. |
If I'm reading this correctly, it looks like this is always doing full table scans in the app ( These matches could be checked on an SQL / ORM level. I'd make sure there's a way to explicitly declare which of these types you're matching (eg: With implicit-only matching, and a full-table scan, it looks like
Even though this would prioritise matching by User ID or OIDC ID, if the database returned another If the While it's good that having > 1 match fails safe for usernames and emails, that could be used as a denial of service vector by a malicious user when the policy is intended to match a different field. It could also allow for deceptive policy changes, where a policy intending to match by one field actually matches against a different one. Having an way to explicitly choose which field to match would fix that issue for User ID and OIDC ID matches - because we can guarantee these are unique and unchanging. That said, any username-based (or potentially, email-based) policy is always to vulnerable to this sort of issue. The only way to really mitigate that is for Headscale to resolve all unstable identifiers into stable identifiers at policy submission time – then the denial of service vector only comes when an administrator tries to update a policy. That may be something to think about later, though. |
45f5b15
to
17ecffd
Compare
This will be changed as the policy code will be reimplemented, currently I will not spend time on improving the performance of this as it will be tossed.
Ultimately, I do not think we will accept all of these in the policy identifiers, I do not think infinite configurability is the way to go here. Currently I am leaning towards
I've added more tests, I do not think this is the case and that it currently works as intended 🤔 You only pass it one "token" and that can only be resolved to one type.
I am not sure if I understand this, but I think it will be solved/reduced by reducing the amount of allowed fields.
I've removed User ID as it does not really provide value, it is too much flexibility.
This is planned to be resolved when redoing the policy package. The new version is planned to resolve everything at load-time instead of runtime, I've started this work, but it is dependent on other work here. |
700c2b3
to
50165ce
Compare
The reason for allowing explicit prefixes everywhere is to ensure a policy condition always evaluates against a specific type or attribute. When (a/certain) type(s)/attribute(s) can only be tested with an unprefixed value (eg: with usernames in This could cause some unexpected evaluations, particularly if someone decided to set their username to something like On the OIDC side, you should assume that the As a side note, there few restrictions on which characters may appear in the
This would allow
You'll need a test where there's a username that looks like a numeric user ID (eg:
Consider a policy that applies to If a malicious user changes their If the genuine user is deleted, but a policy still references the user by OIDC provider identifier, a malicious user could change their If there's explicit prefixes for matching on each of those attributes, an administrator can be assured that a rule can only evaluate against the type and attribute that they expect.
At the moment, it doesn't look like This means that you wouldn't need to worry about
No worries 😄 |
We will not do any prefixing of the types.
Fixed the case where the
We will solve this by using the same requirements for usernames as we do for the CLI, that way it cannot look like the provider identity.
The administrator is responsible for maintaining this. |
@micolous PTAL |
6332979
to
f8ec54d
Compare
currently, the policy approach node to user matching with a quite naive approach looking at the username provided in the policy and matched it with the username on the nodes. This worked ok as long as usernames were unique and did not change. As usernames are no longer guarenteed to be unique in an OIDC environment we cant rely on this. This changes the mechanism that matches the user string (now user token) with nodes: - first find all potential users by looking up: - database ID - provider ID (OIDC) - username/email If more than one user is matching, then the query is rejected, and zero matching nodes are returned. When a single user is found, the node is matched against the User database ID, which are also present on the actual node. This means that from this commit, users can use the following to identify users in the policy: - provider identity (iss + sub) - username - email - database id There are more changes coming to this, so it is not recommended to start using any of these new abilities, with the exception of email, which will not change since it includes an @. Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
f8ec54d
to
c59144a
Compare
currently, the policy approach node to user matching with a quite naive approach looking at the username provided in the policy and matched it with the username on the nodes. This worked ok as long as usernames were unique and did not change.
As usernames are no longer guarenteed to be unique in an OIDC environment we cant rely on this.
This changes the mechanism that matches the user string (now user token) with nodes:
If more than one user is matching, then the query is rejected, and zero matching nodes are returned.
When a single user is found, the node is matched against the User database ID, which are also present on the actual node.
This means that from this commit, users can use the following to identify users in the policy:
There are more changes coming to this, so it is not recommended to start using any of these new abilities, with the exception of email, which will not change since it includes an @.