[SERVER-73576] enforceUserClusterSeparation authenticate validation incorrect Created: 03/Feb/23 Updated: 27/Oct/23 Resolved: 20/Mar/23 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Mark Baker-Munton | Assignee: | Spencer Jackson |
| Resolution: | Works as Designed | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
||||||||||||||||||||
| Assigned Teams: |
Server Security
|
||||||||||||||||||||
| Operating System: | ALL | ||||||||||||||||||||
| Sprint: | Security 2023-02-20, Security 2023-03-06 | ||||||||||||||||||||
| Participants: | |||||||||||||||||||||
| Description |
SummaryHistorically we haven't allowed x509 auth when the client certificate O/OU/DC matched the server certificate O/OU/DC. The intention of The enforceUserClusterSeparation parameter was introduced to override this behaviour. Code was added to the createUser and authentication commands accordingly. The logic for the authentication command has been implemented - I believe - incorrectly. Currently, the O/OU/DC client/server validation only takes place if the clusterAuthMode does not allow X509 (i.e keyFile mode). For X509 clusterAuthMode, no validation is performed, only a log warning. We actually want the validation to be performed on the X509 code path only - with no validation when using keyFile. The validation logic for the createUser command and configuration check on process startup seem correct. Faulty logic: MotivationHow does this affect the end user?Possible security implications due to faulty validation logic. Currently, when X509 clusterAuth is enabled, any client certificate that matches the server O/OU/DC will bypass validation and be granted __system privileges. How likely is it that this problem or use case will occur?Fairly rare. |
| Comments |
| Comment by Mark Baker-Munton [ 10/Mar/23 ] | ||||||||||||||||
|
spencer.jackson@mongodb.com - gotcha, ok, that's a much bigger change then. I had forgotten about the arbiter problem. Thanks for the explanation, that's really useful to know! | ||||||||||||||||
| Comment by Spencer Jackson [ 09/Mar/23 ] | ||||||||||||||||
|
Hmm. An interesting question. That change would be possible, but a little harder than it might seem on its face. I believe isInternalClient() will return true if the remote party set a flag on their connection. However, these flags not particularly trustworthy. Consider that we're inspecting them here, before authentication has concluded. So, an adversary could just enable this flag to gain access here. Of course, on the other other hand, we have some applications based on MongoDB Drivers which need to connect as, and impersonate, cluster members. Automation, for example, has to pretend to be a cluster member in order to issue commands on Arbiters. Arbiters don't have data stores, so can't store user information, so can't remember the Automation Agent's password. It's a silly edge case, but Automation would need to be able to gain internal authorization rights. That would mean... probably adding a weird quasi secret Driver API for setting the internal client flag? That would be a project's worth of work to coordinate the upgrade across server, the Go Driver, and the Automation Agent. Also, that uassert should go in the keyFile auth path as well. We know the client is authenticating using MONGODB-X509, and their cert would be considered a cluster cert if the configuration was changed. We want to pre-emptively break, rather than allow the administrator to use certificates which could grant more permission in the future if the configuration flag was toggled. | ||||||||||||||||
| Comment by Mark Baker-Munton [ 09/Mar/23 ] | ||||||||||||||||
|
Hi spencer.jackson@mongodb.com! Thanks for the detail, that makes a bit more sense now. I have one question though. You say there is no way to distinguish between cluster and user certificates but it looks like we have a way of determining whether the client connection itself is internal (the isInternalClient function). Would it be feasible to use the isInternalClient() function here at all? Something like this:
| ||||||||||||||||
| Comment by Spencer Jackson [ 08/Mar/23 ] | ||||||||||||||||
|
Hi mark.baker-munton@mongodb.com! I don't think I'm seeing the issue you're describing. In the codeblock you've referenced, if (sslConfiguration.isClusterMember(clientName)) at the very top of the block is checking whether or not the presented client certificate's O/OU/DC components match the server's certificate. All the remaining code in the block is run under the assumption that the presented certificate matches the rules for being a cluster certificate. Thus, in the codepath where we are accepting keyFiles, we're checking whether enforceUserClusterSeparation was enabled. If the flag has not been enabled, then the administrator has deliberately relaxed the validation rules, so that they could use X.509 authentication with certificates that look like cluster certificates. Otherwise, they're trying to authenticate as a user which, if X.509 intracluster authentication was enabled, could be interpreted as a cluster user and so should be rejected so the administrator doesn't get comfortable with minting certificates like this for applications. In the alternative path, where we are accepting intracluster X.509 certificates, no further validation can be performed can be performed on the certificate. Given that our configuration tells us to accept a set of X.509 certificates as cluster certificates, and we've been presented with a member of that set, we must accept the certificate as a cluster member. We don't have a mechanism, other than the subject name, for distinguishing between cluster and user certificates. |