Bug #42574 | ValidateUser does not use the application id, allowing cross application login | ||
---|---|---|---|
Submitted: | 3 Feb 2009 21:50 | Modified: | 5 Mar 2009 11:26 |
Reporter: | Craig Nagy | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | Connector / NET | Severity: | S3 (Non-critical) |
Version: | 5.2.5 | OS: | Any |
Assigned to: | CPU Architecture: | Any | |
Tags: | applicationname, membershipprovider, validateuser |
[3 Feb 2009 21:50]
Craig Nagy
[3 Feb 2009 22:28]
Craig Nagy
Sorry, fix is incorrect. There is no applicationId in the my_aspnet_Membership table. Perhaps fix should be in GetUserId. Users should be retrieved with application id in mind.
[4 Feb 2009 8:27]
Tonci Grgin
Hi Craig and thanks for your report. AFAIS in latest sources, same error is present, both for unreleased versions and 5.2: // first get the user id. If that is -1, then the user doesn't exist // so we just return false since we can't bump any counters int userId = GetUserId(connection, username); if (-1 == userId) return false; string sql = @"SELECT Password, PasswordKey, PasswordFormat, IsApproved, Islockedout FROM my_aspnet_Membership WHERE userId=@userId"; MySqlCommand cmd = new MySqlCommand(sql, connection); cmd.Parameters.AddWithValue("@userId", userId); cmd.Parameters.AddWithValue("@appId", applicationId); <<< Verified as described by looking into sources although not using AppID is not an error per-se but the way things can be set up, according to MSDN: http://msdn.microsoft.com/en-us/library/0580x1f5.aspx ApplicationName property The application name that is stored with each profile. The profile provider uses the application name to store profile information separately for each application. This enables multiple ASP.NET applications to use the same data source without a conflict if the same user name is created in different applications. Alternatively, multiple ASP.NET applications can share a profile data source by specifying the same application name. So it is my opinion you should lover the severity of reported problem to at least S3 if not S4.
[4 Feb 2009 14:06]
Craig Nagy
Severity lowered to S3 per Tonci's comment since it's likely that the situation encountered is rare. However, it seems like a potentially serious security hole since two applications sharing the provider may expect users to be maintained separately. Applying the fix to GetUserById as follows resolves the issue. private int GetUserId(MySqlConnection connection, string username) { MySqlCommand cmd = new MySqlCommand( "SELECT id FROM my_aspnet_Users WHERE name LIKE @name AND applicationId=@appId", connection); cmd.Parameters.AddWithValue("@name", username); cmd.Parameters.AddWithValue("@appId", applicationId); object id = cmd.ExecuteScalar(); if (id == null) return -1; return (int)id; }
[4 Feb 2009 14:48]
Craig Nagy
applicationId is also missing from the query in IsUserInRole.
[4 Feb 2009 17:43]
Tonci Grgin
Craig, thank you. I do see this as rare complication but all necessary code seems to be in place so I notified c/NET team leader to take a look at this.
[4 Mar 2009 7:01]
Tonci Grgin
Same problem reported in Bug#43339.
[4 Mar 2009 16:20]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/68268
[4 Mar 2009 16:21]
Reggie Burnett
fixed in 5.2.6
[5 Mar 2009 11:26]
Tony Bedford
An entry was added to the 5.2.6 changelog: MySQLMembershipProvider.ValidateUser only used the userId to validate. However, it should also use the applicationId to perform the validation correctly. The generated query was, for example: SELECT Password, PasswordKey, PasswordFormat, IsApproved, Islockedout FROM my_aspnet_Membership WHERE userId=13 Note that applicationId is not used.