Database security is required in any large scale software system that updates sensitive database records for the operator that administers it. Apache Derby database security has several holes, especially if someone gains superuser access.
In the following sections a description will be issued on how to take advantage of Apache Derby security features and a type of attack for each one of them will be given. Whether these kinds of attacks are applicable on a local Derby database or even on a remote one will also be discussed.
Finally, a new security mechanism, that allows a local superuser to read the database entries but not modify, add or delete them, is going to be proposed. This means that you could apply such a mechanism not only in Apache Derby databases but also in any other relational database system.
1. User Authentication
The main function of the user authentication security feature is to restrict access to Derby databases. The available ways of specifying the user name and password for connecting to the database include:
1.1 Credentials-Based Authentications
- Based on a user id and password JDBC attributes in connection URL or properties object
- user and password parameters in DriverManager.getConnection() methods
- user and password properties in DataSource
Attack: The username and password are provided in JDBC connection URL in clear text. Here is an example through the Apache Derby "ij" tool:
ij> connect 'jdbc:Derby://localhost:1527/DbTest;user=app; password=Derby';
The "ij" tool issues JDBC connections over TCP towards Apache Derby server in non-encrypted fashion. Therefore, a network traffic monitor tool could capture all the packets going to Apache Derby machine, TCP 1527 port, revealing the user name and password in less than a minute.
Solution1: Since username/password are passed over the network they could pass encrypted to the server but one needs to implement a TCP server with an embedded Derby client that would first decrypt the user/pass and then reconstruct the JDBC connection URL with the deciphered credentials, towards the local Apache Derby server. Of course, the superuser could snoop the local interface and see the clear text credentials again.
Solution2: Instead of a custom encryption as described in solution 1, SSL sockets could provide another level of security. The local superuser access problem still persists, since he may access both the private and public keys.
Solution3: The latest Apache Derby releases implement JCE and Diffie Helman with prime key of 32 bytes encryption between the client and the server.
1.2 Database Properties File
There is another way to define the user credentials for a specific database. The "service.properties" file of the database should contain the following:
The Java class should implement the Java interface:
Therefore, authentication credentials are hidden inside this Java class. Let's see some simple attacks on this type of security:
Attack1: If the superuser removes from the "service.properties" file these two lines described above, no more security is used for this database.
Attack2: A superuser with Java programming skills could easily decompile the Java class, retrieving in that way the clear text credentials.
1.3 Database-Level Calls (BUILTIN)
The BUILTIN authentication feature is defined in "service.properties" as follows:
There are two options to define the user credentials:
- Inside properties file:
- Database level will store password internally (SHA-1):
CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('Derby.user.name', 'password')
Attack: As described above, in previous attacks, the superuser could easily remove the configuration entries from the properties file.
Solution: If all the properties are stored internally, in binary database files on the local disk, using CALL_SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY() statements, the clear text property values could be protected from removals from the properties files:
This information is encrypted in local files under a directory called /$(Derby_installation)/$(DB_NAME)/seg0. If one deletes these files, the database will be corrupted and non-usable any more.
2. User Authoriztions
The main function of the user authorization security feature is to restrict access to specific users of Derby database. The available authorization options are:
- Three options
- fullAccess: Read & modify data (default)
- readOnlyAccess: Readonly
- noAccess: Cannot connect
- Per database (set as database properties)
- For the system (Derby.properties file)
- Grant/Revoke (#DERBY-464 Jira Issue)
2.1 Datanbase Level Calls
The properties to set the options of authorization rules are:
Derby.database.defaultConnectionMode=fullAccess, readOnlyAccess, noAccess
Attack: The #DERBY-528 Jira feature ensures that userid/password will travel encrypted through DRDA protocol. A snoop from the Derby client to the Derby server, by filtering the listening port, provides the encrypted userid/password. A Java programmer could write a Java utility that decrypts the userid/password as it is implemented in Apache Derby Java class:
protected String readEncryptedString (DecryptionManager decryptM, int securityMechanism, byte initVector, byte sourcePublicKey)
3. Database Encryption
The database encryption sub-features are:
- Protects physical files
- Complete encryption of on disk data
- Indexes and tables
- Transaction log file
- Temporary files (for ORDER BY, etc.)
- Includes application and system data
- Table data
- System catalog/metadata information
3.1 Boot Password
The service.properties file should contain the following properties:
In the first connection the client must provide the boot password (database key store) or encryption key (external key store). Once database is booted, any subsequent connection requests can be made without boot password/encryption key. Also, the database remains booted after first connection disconnects. Therefore, this kind of security is not safe at all.
4. Proposed Solution
The proposed solution is a way to get rid of such attacks although it's not actually related to the Apache Derby project, and works for every database engine. The idea is to enrich the database tables that need protection, with one more field that will contain a hash key. This hash key should be calculated on the fly, before inserting the record in the database. The records will not be encrypted at all, so the superuser could easily view the contents. This mechanism protects the database against additions, deletions or modifications.
So, the only possible attack is to decompile the Java class that implements the proposed mechanism. An alternative solution is to implement the ciphering algorithm in a C-library and call the functions through JNI. One could say that since the API is exposed through the C-library, a brute force attack could give the desired key. The answer is yes, but if you use a strong algorithm it would not be computationally feasible.
Let's see an example of a real database schema:
CREATE TABLE "LICENSE"."STATSDATA" ("STATSID" BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1), "PROCESSCOMPLETIONTIME" TIMESTAMP NOT NULL, "PACKAGEDRECORDS" INTEGER NOT NULL, "PROCESSEDRECORDS" INTEGER NOT NULL, "OUTPUTTYPEID" INTEGER NOT NULL, "HASHENTRY" VARCHAR(255) NOT NULL);
Let's see now an example with contents:
ij> SELECT * FROM "LICENSE"."STATSDATA";
The hash string is calculated by using a strong encryption algorithm, salted by a private key. The application that adds or updates these database entries, is responsible for invoking the cipher function to generate or update the hash key field. All the database fields that we would like to protect from unauthorized manipulation need to participate to the hash key field. Also, the application is responsible for confirming the integrity of the records when it reads from the database.
Summarizing all the above attacks and proposed solutions, one could claim that the best approach is a combination of all the above. To be more specific, a hash field is required to enrich the database integrity, while the username/password of the remote read/write user should be encrypted by using JCE algorithms. A C-library that implements several encryption algorithms, for the hash key generation would be more difficult to be reverted in contrast with a Java based one. Apache Derby database is a very good solution for many products, especially if the appropriate security policies are applied, making the later a robust database solution.
I would like to thank George Tsolis, Bytemobile Engineering Architect, for his valuable comments.
Jean T. Anderson, "Apache Derby Security"
The Apache DB Project Documentation
Marios Karagiannopoulos is a Senior Software Engineer at the Bytemobile European Development Center. Marios Karagiannopoulos holds a BSc. in Software Engineering and an MSc. in Computational Mathematics & Informatics. He has acquired more than 12 years of professional experience in Software Engineering of real time systems. Marios has worked in Greece, Sweden, Norway and the United States of America in some of the largest telecommunication software industries like Intracom, Ericsson Telecom AB, and Bytemobile, Inc.
His contribution in the scientific community includesnine publications in national conferences and two papers in international journals in the fields of distributed data mining and information security. While working for companies of the telecom sector, he has published internally more than 12 technical innovative design/specifications.
© Copyright 2010 Bytemobile, Inc.