The phrase "security vulnerability" gives most of us the creeps. We are afraid of them. Looking at them rationally, they share a trait with other bugs: All are a pain, but some are a bigger pain than others. And instead of trying to avoid the evil by not talking about it, let's take a look at MySQL's security vulnerability track record over the years, and explain the rationale behind our actions using actual cases from past years.
Let me start by pointing out that the MySQL database -- like all large software products -- has had, and in all likelihood still has, security vulnerabilities. As an often used default database for web apps, MySQL is pounded upon from a number of different directions. Since one of the most important user criteria is that the database must be secure, let me also be clear that MySQL treats security vulnerabilities as the highest-priority of all bugs and promptly allocates resources towards fixing such bugs when they are reported, as described below.
Yet, every single alleged security vulnerability does not merit MySQL's release of new binaries, nor do all of them require you as a user to upgrade your version of the database.
So in order to better be able to assess any future threat situation, let us take a deep breath and explore what "security vulnerabilities" are, how they are classified, how they are discovered, how MySQL gets to know about them, what the MySQL Security Team is and what the roles of the team members are, how the vulnerabilities are fixed, how the fixes are distributed and communicated, and whether you should care.
Security Vulnerability: The definition
Looking up "security vulnerability" in Wikipedia provides the following definition (http://en.wikipedia.org/wiki/Security_vulnerability):
"In computer security, the word vulnerability refers to a weakness in a system allowing an attacker to violate the confidentiality, integrity, availability, access control, consistency or audit mechanisms of the system or the data and applications it hosts. Vulnerabilities may result from bugs or design flaws in the system. A vulnerability can exist either only in theory, or could have a known exploit. Vulnerabilities are of significant interest when the program containing the vulnerability operates with special privileges, performs authentication or provides easy access to user data or facilities (such as a network server or RDBMS)."
The Wikipedia article points out the possible causes of vulnerabilities:
"Vulnerabilities often result from the carelessness of a programmer, though they may have other causes. A vulnerability may allow an attacker to misuse an application through (for example) bypassing access control checks or executing commands on the system hosting the application. Some vulnerabilities arise from un-sanitized user input, often allowing the direct execution of commands or SQL statements (known as SQL injection). Others arise from the programmer's failure to check the size of data buffers, which can then be overflowed, causing corruption of the stack or heap areas of memory (including causing the computer to execute code provided by the attacker)."
The MySQL Security Team
The MySQL Security Team is not a dedicated, separate team but a cross-functional group of employees who in case of a verified security vulnerability are prepared to promptly focus on the issue until the problem is fixed and applied to the source code. Depending on the nature of the security issue, a build is made, and the issue isn't closed until affected customers have been alerted and the vulnerability, and the subsequent 'fix' has been communicated to the user base. For more on how MySQL prioritizes security vulnerabilities and our response guidelines, see the section entitled “Rationale: Not all security vulnerabilities are created equal” below.
- several server developers, whose task it is to verify the bug report and fix the bug
- several representatives from the Build (Engineering) team, whose task it is to build a new release with the fix
- several support engineers, whose task it is to alert individual customers and who also verify bug reports
- several representatives from the Marketing and Community teams, whose task it is to communicate information to our user base
- several management representatives, whose task it is to ensure that relevant resources are allocated
The security team convenes not only when a severe security vulnerability is reported, but also regularly resolves less urgent security vulnerabilities.
What happens when a security vulnerability occurs?
Those are the steps external to MySQL. What happens once MySQL receives a vulnerability report?
First, if the security vulnerability is sent in through bugs.mysql.com, we may mark the bug private, in effect making it invisible outside the members of the Security Team plus a few other developers at MySQL AB.
Second, we allocate resources based on the anticipated effects of the security vulnerability. (For our rationale when assessing the bug, read on.)
Third, we verify the bug, using our normal bug verification processes (which may involve the Security Team members) but with a priority that surpasses all non-security issues.
Fourth, if an alleged security vulnerability is verified, our bug fixing resources are immediately reprioritised to fix the security bug before all other ongoing work. In severe cases, this may mean calling people out of their beds.
Fifth, the fix is reviewed by other developers and documented by a Documentation Team member, adding a note to the Release Notes. Again, these reviews are prioritised over outstanding tasks of the needed resources, and for severe cases, the additional reviewers have already been notified in step two and are standing-by to assist.
Sixth, for vulnerabilities where non-MySQLers haven't applied for a CVE number from MITRE (for a definition, see below), we will do so. However, we haven't done so in all cases during the last nine years of MySQL, and we're improving our practices in this area.
Seventh and last, the MySQL Build Team creates the official release, publishes and announces it in cooperation with our Community team. For our commercial customers on MySQL Enterprise, a separate update alert is written and broadcast.
Rationale: Not all security vulnerabilities are created equal
Criterion 1: Scope extends outside MySQL?
The most important factor that determines the seriousness of a security vulnerability is whether its effects are limited to the realm of MySQL, or if it affects the whole operating system, outside the realm of MySQL. This may occur for certain types of bugs, such as buffer overflows, where in some situations the exploiter can execute random machine code pushed by the exploiter.
Realm of vulnerability: MySQL or arbitrary code execution
- Bad: MySQL Server is vulnerable
- Worse: The entire Operating System is made vulnerable, through MySQL enabling arbitrary code execution
Criterion 2: Remote or local user?
The second most important factor that determines the seriousness of a security vulnerability is whether it occurs through a remote application user, without operating system privileges, or whether the MySQL Server is vulnerable only by local attack by users carrying credentials on the Operating System level.
Required OS privileges for triggering the vulnerability
- Bad: A named account with shell access to the OS can cause MySQL to crash (or gain access to data)
- Worse: Any unnamed remote user of the OS, even without privileges/credentials for the operating system, can cause MySQL to crash (or gain access to data)
Criterion 3: MySQL-level authentication
A third factor that determines the seriousness of a security vulnerability is whether it requires MySQL privileges or not.
Required MySQL privileges for triggering the vulnerability
- Bad: A named MySQL user account can cause MySQL to crash (or gain access to data) beyond the rights of that user
- Worse: Any unnamed remote user of a MySQL server, even without MySQL privileges, can cause MySQL to crash (or gain access to data)
Criterion 4: Likelihood of an exploit
The fourth factor, the likelihood of an exploit, is hard to quantify. At one extreme end, we have exploits which are theoretical; there are no known exploits. At the other end, we have exploits with a how-to-reconstruct published on the web. Between these far ends, there is a continuum where only experience can be used to judge the real likelihood.
Likelihood of an exploit
- Bad: The risk of a vulnerability being potentially exploitable
- Worse: Exploits that are not just known, but published
Criterion 5: Gaining access or crashing the server
While "crashing the server" may look serious, because of the connotation of the word "crash", arguably it's much worse if access to real data is gained.
Nature of vulnerability: Server crash or access to data
- Bad: MySQL Server crashes -- the execution of the mysqld process stops
- Worse: Unprivileged users get access to data -- reading or writing to the database without proper rights. This is worse for two reasons: (1) because sensitive data can be leaked or altered, and (2) because it won't be detected as promptly as a crash.
There are further criteria, some of which may explain some of our reasoning towards the likelihood of an exploit.
Type of MySQL software which is vulnerable
- Bad: Any vulnerable software, including scripts and clients
- Worse: The Server itself, where the vulnerability is usually not trivially fixed by an improved configuration
Denial of Service -- or potentially corrupting data
- Bad: Ill-willed users of a MySQL-based web site can slow down the Server so much that it becomes practically unusable
- Worse: They not only cause the Server to slow down -- they crash the Server, which requires the DBA to restart the Server and can leave some tables in a corrupted state
Effect of security precautions
- Bad: Any security bug, even if it just occurs when MySQL is running as Unix root on the server, or the "test" database and empty userid are left in a production environment
- Worse: A bug that makes MySQL vulnerable despite the DBA having followed best practices for securing a MySQL installation
Maturity of version on which the bug occurs
- Bad: Any security bug, even if it's on an alpha version
- Worse: A bug on a GA version, during that version's prime lifetime
What is an "Exploitable" Security Vulnerability?
Today, MySQL has no formal definition of an "exploitable" security vulnerability. We try to err on the side of being cautious, but on the other hand, we do want to react more swiftly to real threats than potential ones. Hence, for the purpose of this article, I've used the expression "exploitable" to mean "a known exploit exists, or is likely to exist within a short timeframe", as opposed to "theoretically possible to exploit within a finite timeframe". Both definitions are defensible, and we've picked ours with the interests of the users in mind. If you have improvement suggestions, tell us!
Summary: Policy on MySQL Security Vulnerabilities
While MySQL does not have a formal Security Policy, in practice, we intend to give vulnerabilities roughly three levels of treatment:
Attempted time to fix: Within hours of discovery. New MySQL Enterprise Server binaries issued: Within a week (ASAP, often quicker). New MySQL Community Server binaries issued: Within two weeks (ASAP, often quicker). Triggering effects:
- exploitable, arbitrary code execution
- exploitable, unauthenticated user gains access or crashes the server
Attempted time to fix: Within hours of discovery. New MySQL Enterprise Server binaries issued: Within two weeks (ASAP, often quicker). New MySQL Community Server binaries issued: No. Triggering effects:
- not exploitable arbitrary code execution
Attempted time to fix: Within days or weeks of discovery. New MySQL Enterprise Server binaries issued: No. New MySQL Community Server binaries issued: No. Triggering effects:
- any other security vulnerability
MITRE tracks vulnerabilities independently
Quite like most societies have set up independent policing authorities and don't rely on private security companies, the concept of an independent security organisation exists in the IT industry. The most authoritative of these is probably the MITRE Corporation (http://www.mitre.org), a US-based not-for-profit organization chartered to work in the public interest.
MITRE keeps a list of CVEs or Common Vulnerabilities and Exposures. Some of these are related to MySQL. When I searched the MITRE web site with the keyword "mysql" (http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=mysql) in late June 2007, I got 137 CVE entries, with the first one from 1999. Most of these entries ended up on the list because they are related to applications that use MySQL, so the more relevant number is the number of entries related to MySQL software provided by MySQL AB itself (notably MySQL Server, but in some cases also the Client software). Applying this criterion gives us 58 entries, of which two were disputed by MySQL AB at the time they occurred.
I asked MySQL's co-founder and MySQL Fellow, Michael "Monty" Widenius to take a look at these 56 security vulnerabilities, reported over a total of 9 years, and classify them. Based on this work, Lenz Grimmer (now in our Community Relations Team, but with a past track record in the Build Team) and Giuseppe Maxia (now in our Community Relations Team, but with a past track record as an external MySQL community member and a member of the MySQL Quality Assurance Team) documented a list of all individual cases. This list is now available on MySQL Forge at http://forge.mysql.com/wiki/Security_Vulnerabilities_In_MySQL_Server, with CVE numbers, dates and times when they were fixed in MySQL. I got plenty of help from several members of the Security Team at MySQL.
Historic MySQL CVE entries 1999-mid 2007
To learn more from MySQL's past track record, and to ensure a good security policy in the future, we went through all 56 Security Vulnerabilities from 1999 to mid-2007 and placed them into seven categories (worst case first):
- MySQL users can execute arbitrary (non-MySQL related) code of their own choice on the server
- Remote users can gain access to the MySQL Server
- Remote users can crash the MySQL Server
- Local users can gain access to the MySQL Server
- Local users can crash the MySQL Server
- Minor Security Vulnerability (e.g. configuration issue)
- Not a real Security Vulnerability (MySQL works as defined)
Definitions: A "remote user" is a user of MySQL, regardless of point of access, who does not have shell access to the underlying operating system that MySQL runs on. A "local user", on top of MySQL access, also has shell access.
Of these, the first six are true, undisputable vulnerabilities. The seventh one depends on the viewpoint. We may see it as "not a real problem", whereas one may also claim that this last category consists of design flaws. There are three such CVE entries from 1999 to mid-2007.
|Year||Hijack||Remote user||Local user||Minor||None||Total|
Source: Security Vulnerabilities in the MySQL Server by Lenz Grimmer, classified by Michael "Monty" Widenius
Let me provide you with all known examples of security vulnerabilities giving remote users access to MySQL Server:
MySQL 3.22 allows remote attackers to bypass password authentication and access a database via a short check string. Reported 8 Feb 2000, fixed in 3.22.32 on 14 February 2000.
The COM_CHANGE_USER command in MySQL 3.x before 3.23.54, and 4.x before 4.0.6, allows remote attackers to gain privileges via a brute force attack using a one-character password, which causes MySQL to only compare the provided password against the first character of the real password. Reported 3 Dec 2002, fixed in 3.23.54 on 5 Dec 2002 and in 4.0.6 on 14 Dec 2002.
SQL injection vulnerability in MySQL 4.1.x before 4.1.20 and 5.0.x before 5.0.22 allows context-dependent attackers to execute arbitrary SQL commands via crafted multibyte encodings in character sets such as SJIS, BIG5, and GBK, which are not properly handled when the mysql_real_escape function is used to escape the input. Originally reported as bug 8378 on 7 Feb 2005, then again as a security bug in May 2006, fixed in 4.1.20 on 24 May 2006 and in 5.0.22 on 24 May 2006.
Some sample security vulnerabilities through which remote users can crash MySQL Server:
mysqld in MySQL 3.21 creates log files with world-readable permissions, which allows local users to obtain passwords for users who are added to the user database. Reported on 26-Dec-1999. Fixed in 3.22.x
MySQL allows local users to modify passwords for arbitrary MySQL users via the GRANT privilege. Reported on 11-Jan-2000. Fixed the same day, in 3.22.30.
MySQL Database Engine uses a weak authentication method which leaks information that could be used by a remote attacker to recover the password. Reported on 8-Feb-2000. Fixed in 4.1.0 (4-Apr-2003)
Buffer overflow in MySQL before 3.23.33 allows remote attackers to execute arbitrary code via a long drop database request. Reported on 26-Jan-2001. Fixed in 3.23.33 (9-Feb-2001)
The COM_CHANGE_USER command in MySQL 3.x before 3.23.54, and 4.x to 4.0.6, allows remote attackers to execute arbitrary code via a long response. Reported on 3-Dec-2002. Fixed in 3.23.54 (5-Dec-2002) and 4.0.6 (14-Dec-2002).
Examples of security vulnerabilities not belonging to the most serious category:
MySQL before 5.1.18 allows remote authenticated users without SELECT privileges to obtain sensitive information from partitioned tables via an ALTER TABLE statement. Reported on 26-Oct-2006. Fixed in 5.1.18 (8-May-2007)
MySQL before 4.1.23, 5.0.x before 5.0.42, and 5.1.x before 5.1.18 does not require the DROP privilege for RENAME TABLE statements, which allows remote authenticated users to rename arbitrary tables.
This was not critical, as it required ALTER on the original table. Reported on 29-Mar-2007. Fixed in 4.1.23 (12-Jun-2007) / 5.0.42 Enterprise (23-May-2007) / 5.0.45 Community (4-Jul-2007) / 5.1.18 (08-May-2007)
sql_parse.cc in MySQL 4.0.x up to 4.0.26, 4.1.x up to 4.1.18, and 5.0.x up to 5.0.20 allows remote attackers to obtain sensitive information via a COM_TABLE_DUMP request with an incorrect packet length, which includes portions of memory in an error message. Reported on 25-Apr-2006. Fixed in 4.0.27 (6-May-2006), 4.1.19 (6-May-2006), and 5.0.22 (2-May-2006).
The check_connection function in sql_parse.cc in MySQL 4.0.x up to 4.0.26, 4.1.x up to 4.1.18, and 5.0.x up to 5.0.20 allows remote attackers to read portions of memory via a username without a trailing null byte, which causes a buffer over-read.
No exploit known. Reported on 25-Apr-2006. Fixed in 4.0.27 (6-May-2006), 4.1.19 (6-May-2006), and 5.0.22 (2-May-2006).
MySQL 5.0.18 and earlier allows local users to bypass logging mechanisms via SQL queries that contain the NULL character, which are not properly handled by the mysql_real_query function. NOTE: this issue was originally reported for the mysql_query function, but the vendor states that since mysql_query expects a null character, this is not an issue for mysql_query.
Minor issue, not a problem with binary logging. Reported on 25-Feb-2006. Fixed in 5.0.24 (27-Jul-2006).
Lastly, an example of a vulnerability raised because it represents surprising (to the reporter) behaviour potentially related to security. But not all of these are issues where the unexpected behaviour is unintended. Here is an example from 2006:
MySQL 4.1 before 4.1.21 and 5.0 before 5.0.24 allows a local user to access a table through a previously created MERGE table, even after the user's privileges are revoked for the original table, which might violate intended security policy.
This is how a MERGE table is defined to work
To conclude, let's see an example of a false alarm, presented to the MySQL Users Conference 2007. The fear started with an intimidating blog entry (Are you prepared for the attack of the MySQL worm?, followed by bug report #28089). The reporter describes an attack through a chain of compromised MySQL servers via Federated tables as highly probable. Fortunately, at the Users Conference there were all the experts on Federated tables and the report was quickly analyzed. Within hours, the alleged vulnerability was reduced to a largely improbable case, where most DBAs must drop all the default defenses and use lousy passwords in order for the attack to start. This case did not even become a CVE entry. It was defused with the full understanding of everyone involved, including the author of the initial report.
Let us know how we should improve
- http://www.microsoft.com/technet/archive/community/columns/security/essays/vulnrbl.mspx?mfr=true Microsoft's Definition of a Security Vulnerability
- http://en.wikipedia.org/wiki/Vulnerability_%28computer_science%29 Vulnerability Definition in Wikipedia
- http://en.wikipedia.org/wiki/Exploit_%28computer_science%29 Definition of an Exploit on Wikipedia
- http://cve.mitre.org/about/definition.html Vulnerability Definition from the CVE Editorial Board
- http://cve.mitre.org/about/terminology.html CVE Terminology: Vulnerability
- http://cve.mitre.org/docs/vuln-trends/index.html Report: Vulnerability Type Distributions in CVE
- http://en.wikipedia.org/wiki/Buffer_overflow Buffer overflow in Wikipedia
- http://en.wikipedia.org/wiki/Denial-of-service_attack Denial of Service in Wikipedia
- http://en.wikipedia.org/wiki/Zero_day Zero-day vulnerability in Wikipedia