Demystifying MySQL Security for Web 2.0: Part 1

Web 2.0 applications are proliferating and it has become widely popular for delivering dynamic user-generated content, information collaboration, data mashups, social networking and Web services. Building security for Web 2.0 applications pose several daunting challenges to Web 2.0 developers as these applications are publicly accessible and it blindly opens door to several intentional/unintentional abuses and malicious practices including data interception and manipulation by cyber-criminals.  Unfortunately, Web 2.0 has no silver bullet or one-size fits all security solution ! Interestingly, the most common Web 2.0 security threats pertain to the inherent flaws with the application design, deployment architecture and its failure to proactively identify the potential application-level risks  and mitigate them with appropriate countermeasures.

 

Lately Web 2.0 application databases have become an easier target for cyber criminals – as it is transparent to user with rich-client applications and draws close proximity to the network perimeter ignoring the traditional logical-tiers of insulation considered with multi-tier architectures (such as Java EE). If we explore the existing Web 2.0 attack patterns and attempt to identify the potential security threats and exploits of Web 2.0 databases, we will find the most common vulnerabilities pertain to the following issues:

·         Eavesdropping database connections

·         Un-trusted application clients

·         Insufficient authentication controls

·         Insecure database access execution privileges

·         Unauthorized disclosure of user account credentials

·         Unauthorized access to application data tables

·         SQL injection or Arbitrary code execution

·         Lack of auditing controls

 

Thus it becomes extremely critical to proactively address the known database security issues by deploying appropriate countermeasures and ensuring confidentiality and integrity of the database including user accounts and stored data.

MySQL is the most popular open-source database and widely popular in Web 2.0 application environments.  MySQL is certainly not my forte! Recently, I had my first experiences with MySQL on couple of projects so I ended up digging deeper into MySQL security and churned up  the features for use in Web 2.0 applications.  Here is my first installment of my hitchhiker’s view on MySQL security and its relevance to Web 2.0 applications.

 

Securing MySQL database connections

 

Enforcing confidentiality and integrity of database communications is critical for thwarting eavesdropping and untrusted client connections.  Enabling MySQL connections with SSL/TLS protocol guarantees transport-layer security and assures that the database communciation is not accessible for unauthorized access and the data exchanged is not modified or altered during transit.

 

To secure communication between the client and the database server,  MySQL supports the use of SSL for ensuring transport-level security using encrypted communication.  Since MySQL 5.0.x, MySQL bundles yaSSL  (compatible with OpenSSL ) to support SSL and related cryptographic requirements.

 

Configuring MySQL with SSL/TLS communication

 

If you are using binary versions of MySQL to verify the existence of yaSSL support, login to the mysql client and try the following:

 

mysql> SHOW VARIABLES LIKE ‘have_ssl’;

+—————+——-+

| Variable_name | Value  |

+—————+——-+

| have_ssl      | YES   |

+—————+——-+

 

 

Incase of using MySQL source distribution and if you want to choose OpenSSL  (I strongly recommend OpenSSL as it is FIPS-140 certified) as your SSL provider, you may choose to recompile your MySQL server using  –with-openssl   as configure switches.

 

# ./configure –with-openssl

 

To verify the configuration with OpenSSL

 

mysql> SHOW VARIABLES LIKE ‘have_openssl’;

+—————+——-+

| Variable_name | Value |

+—————+——-+

| have_openssl  | YES   |

+—————+——-+

 

To establish an SSL communication, you must obtain the SSL certificates from a certificate authority (CA) (recommended) or alternatively you would able generate the certificates using  Solaris Key Management Framework (pktool utility) or OpenSSL (refer my earlier post on OpenSSL as CA/SSL Test Kit: Cheat Sheet) .  To enable SSL, MySQL requires the following three certificate files for both server and client (if required):

 

a)      CA certificate

b)      Server certificate

c)      Client certificate

 

You may append the location of these certificate files in the [mysqld] and [client] section of the MySQL server configuration file  my.cnf.  For example:

 

[client]

ssl-ca=/client-certs/cacert.pem

ssl-cert=/client-certs/my-new-client-cert.pem

ssl-key=/client-certs/my-new-client-key.pem

     [mysqld]

ssl-ca=/certs/cacert.pem

ssl-cert=/certs/my-new-server-cert.pem

ssl-key=/certs/my-new-server-key.pem

    

 

Alternatively, you can specify each certificate as a command-line argument to mysqld (server) and mysql (client) environments. 

 

To start the MySQL server daemon with the SSL configuration:

 

mysqld

        –ssl-ca=cacert.pem

              –ssl-cert=my-new-server-cert.pem

                    -ssl-key=my-new-server-key.pem

 

To start the MySQL client to use SSL, assuming the connecting user has no client certificate authentication requirements:

 

mysql –ssl-ca=cacert.pem

 

To start the MySQL client, assuming the connecting user is required to provide a client certificate for SSL authentication:

 

mysql

      –ssl-ca=cacert.pem

          –ssl-cert=my-new-client-cert.pem

                    -ssl-key=my-new-client-key.pem

 

 

To verify configuration and to ensure that the MySQL server uses SSL connection, the status can be checked from the MySQL client using ssl_cipher status variable.

 

mysql> SHOW STATUS LIKE ‘ssl_cipher’;

+—————+——————–+

| Variable_name | Value              |

+—————+——————–+

| Ssl_cipher    | DHE-RSA-AES256-SHA |

+—————+——————–+

 

Test-driving MySQL SSL connections using JDBC

 To test-drive SSL communication using JDBC, MySQL Connector/J  (MySQL JDBC driver) supports using SSL communication as long as the MySQL database server and Java client is configured with SSL certificates. To enable JDBC communication with SSL, it requires setting JDBC property requireSSL=true and useSSL=true.  In case, if you want to validate the Server certificate you may choose to use verifyServerCertificate=true.

 

Here is the example code, I tried out :

 

import java.sql.*;

public class TestJDBCoverSSL    {

public static void main(String args[])   {

      Connection mySQLconnection = null;

          try {

                //Register the JDBC driver for MySQL.
                 Class.forName(“com.mysql.jdbc.Driver”);

                 String url =  “jdbc:mysql://localhost:3306/mysql?&verifyServerCertificate=false&useSSL=true&requireSSL=true”;
                 mySQLconnection =  DriverManager.getConnection(url,  “jdbcuser”, “password”);

                 //Print URL and connection information
                  System.out.println(“URL: ” + url);
                  System.out.println(“Connection: ” + mySQLconnection); 


                 // Close the connection
                    mySQLconnection.close();

             }    catch(Exception ex)  {
                     ex.printStackTrace();
                  }
                }
     }

More importantly, You need to import the SSL certificates in the Java keystore and then provide the Java keystore location properties where the SSL certificates are stored. You may provide these values as -D Java runtime options on the command line as follows:

-Djavax.net.ssl.keyStore=path_to_Java_keystore_file
-Djavax.net.ssl.keyStorePassword=JavaKeyStore_password
-Djavax.net.ssl.trustStore=path_to_Java_truststore_file
-Djavax.net.ssl.trustStorePassword=JavaTruststore_password

Alternatively, you may incorporate the Java keystore and truststore properties in the JDBC application:

System.setProperty("javax.net.ssl.keyStore","path_to_Java_keystore_file");
System.setProperty("javax.net.ssl.keyStorePassword","JavaKeyStore_password");
System.setProperty("javax.net.ssl.trustStore","path_to_Java_truststore_file");
System.setProperty("javax.net.ssl.trustStorePassword","JavaTruststore_password");

To summarize, enabling SSL/TLS based MySQL connections ensure trusted communication between MySQL clients and the database server. It helps thwarting attacks related to eavesdropping MySQL communications, Man-in-the-Middle (MITM), Forged requests and so forth.  In my next post, I will discuss how to secure user accounts and enable stronger authentication controls in MySQL.

5 thoughts on “Demystifying MySQL Security for Web 2.0: Part 1

  1. Pingback: Ramesh Nagappan Blog : Demystifying MySQL Security for Web 2.0 … « MyPage Builder

  2. Pingback: At a Glance: Last week’s NetBeans, OpenOffice and MySQL reviews - Technology

  3. Sergio

    Could you please explain sense of putting client certificates in the my.cnf?
    Is it that server can accept only connections from client with that certificate?

    Reply
  4. Sergio

    May be now I found the reason – these certificates will be the same for all clients. But there is interesting question:
    possible specificate e.g. 2 ports e.g. 3306 3307 – and for one default certificate (because use in internal networki only for port 3306 and port 3306 closed by firewall) and for 3307 – without certificates default – because use from external? May be this solution can be usefull.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *