Vulnerability: The CmdAuthenticate::_authenticateX509 function in db/commands/authentication_commands.cpp in mongod in MongoDB 2.6.x before 2.6.2 allows remote attackers to cause a denial of service (daemon crash) by attempting authentication with an invalid X.509 client certificate.
Vulnerability ID: CVE-2014-3971
CWE: CWE-20
Severity score: 2.9
Project: https://github.com/mongodb/mongo
Published: 2014-12-25
File: src/mongo/db/commands/authentication_commands.cpp
Commit message: SERVER-13573 Fix x.509 auth exception
Commit author: Andreas Nilsson

Vulnerable version (before fix):
 namespace mongo {         }         else {             std::string srvSubjectName = getSSLManager()->getServerSubjectName();             std::string srvClusterId = srvSubjectName.substr(srvSubjectName.find(",OU="));             std::string peerClusterId = subjectName.substr(subjectName.find(",OU="));              fassert(17002, !srvClusterId.empty() && srvClusterId != srvSubjectName);              // Handle internal cluster member auth, only applies to server-server connections             int clusterAuthMode = serverGlobalParams.clusterAuthMode.load();              if (srvClusterId == peerClusterId) {                 if (clusterAuthMode == ServerGlobalParams::ClusterAuthMode_undefined ||                     clusterAuthMode == ServerGlobalParams::ClusterAuthMode_keyFile) {                     return Status(ErrorCodes::AuthenticationFailed, "The provided certificate " 

Fixed version (after fix):
 namespace mongo {         }         else {             std::string srvSubjectName = getSSLManager()->getServerSubjectName();                          size_t srvClusterIdPos = srvSubjectName.find(",OU=");             size_t peerClusterIdPos = subjectName.find(",OU=");              std::string srvClusterId = srvClusterIdPos != std::string::npos ?                  srvSubjectName.substr(srvClusterIdPos) : "";             std::string peerClusterId = peerClusterIdPos != std::string::npos ?                  subjectName.substr(peerClusterIdPos) : "";              // Handle internal cluster member auth, only applies to server-server connections             int clusterAuthMode = serverGlobalParams.clusterAuthMode.load();              if (srvClusterId == peerClusterId && !srvClusterId.empty()) {                 if (clusterAuthMode == ServerGlobalParams::ClusterAuthMode_undefined ||                     clusterAuthMode == ServerGlobalParams::ClusterAuthMode_keyFile) {                     return Status(ErrorCodes::AuthenticationFailed, "The provided certificate " 

Patch:
patch: @@ -303,14 +303,18 @@ namespace mongo {
         }
         else {
             std::string srvSubjectName = getSSLManager()->getServerSubjectName();
-            std::string srvClusterId = srvSubjectName.substr(srvSubjectName.find(",OU="));
-            std::string peerClusterId = subjectName.substr(subjectName.find(",OU="));
+            
+            size_t srvClusterIdPos = srvSubjectName.find(",OU=");
+            size_t peerClusterIdPos = subjectName.find(",OU=");
 
-            fassert(17002, !srvClusterId.empty() && srvClusterId != srvSubjectName);
+            std::string srvClusterId = srvClusterIdPos != std::string::npos ? 
+                srvSubjectName.substr(srvClusterIdPos) : "";
+            std::string peerClusterId = peerClusterIdPos != std::string::npos ? 
+                subjectName.substr(peerClusterIdPos) : "";
 
             // Handle internal cluster member auth, only applies to server-server connections
             int clusterAuthMode = serverGlobalParams.clusterAuthMode.load(); 
-            if (srvClusterId == peerClusterId) {
+            if (srvClusterId == peerClusterId && !srvClusterId.empty()) {
                 if (clusterAuthMode == ServerGlobalParams::ClusterAuthMode_undefined ||
                     clusterAuthMode == ServerGlobalParams::ClusterAuthMode_keyFile) {
                     return Status(ErrorCodes::AuthenticationFailed, "The provided certificate "
path: src/mongo/db/commands/authentication_commands.cpp