Java Security Manager provides additional protection for resources running in a JVM; It uses the Java security policy file to enforce a set of permissions granted to the code base. For example to use the NLS feature, application needs to give java.io.FilePermission "${oracle.jdbc.policy.ORAI18N}", "read"; permission. Please refer to the section below with the header "JDBC driver features and the required permissions" for more details.
You must enable the security manager to use the policy file. One way to enable the security manager using the -Djava.security.manager option. Application servers such as Web Logic Server, Tomcat, JBoss, etc. have different ways to specify the policy file.
Please refer to the following link for more details about the Java Security Manager: https://docs.oracle.com/javase/8/docs/technotes/guides/security/spec/security-specTOC.fm.html
Review all *.policy files. Check the policy files precedence order. Remove unused grants. Add extra permissions to applications or modules that require them, not all applications. Put comments in the file to track your changes. To debug any issue use –Djava.security.debug=all to troubleshoot security failures.
This is a sample Oracle JDBC Driver Security Policy File. If you enable a SecurityManager, you must grant Oracle JDBC certain permissions. You need to use the Oracle JDBC security policy file in your application such as -Djava.security.policy=ojdbc.policy. This file can be downloaded from the JDBC OTN website. e.g.
http://download.oracle.com/otn/utilities_drivers/jdbc/193/ojdbc.policy
If you don’t use the policy file, then the JDBC driver won’t work when the security manager is enabled. E.g. you can get an exception like
[java] java.security.AccessControlException: access denied (javax.management.MBeanTrustPermission register)
When you use the policy file, it protects critical internal resources. No privileged access to external resources. This way one cannot use the Thin driver for a DoS (denial-of-service) attack.
The ojdbc.policy file is parameterized. You must define certain system properties to use it.
e.g. -Doracle.jdbc.policy.JDBC_CODE_BASE=$ORACLE_HOME/lib/ojdbc8.jar
Here are the few samples of policy file:
Sample-1: Application uses a Thin driver connection and queries a table
I have a Select.java which connects to a database and then select from a table (e.g. DUAL) in that database. Here is the code snippet for it:
…
OracleDataSource ds = new OracleDataSource();
String url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=myhost)(PORT=myport))(CONNECT_DATA=(SERVICE_NAME=myservicename)))";
ds.setURL(url);
…
Connection conn = ds.getConnection();
Statement statement = conn.createStatement();
ResultSet rs = statement.executeQuery(“SELECT * FROM dual”);
…
You can run this sample to use the file using the following command:
java -Doracle.jdbc.policy.CLIENT_HOST=myclienthost -Doracle.jdbc.policy.DBMS_HOST=myserverhost -Doracle.jdbc.policy.DBMS_PORT=myport -Doracle.jdbc.policy.JDBC_CODE_BASE=$ORACLE_HOME/lib/ojdbc8.jar -Doracle.jdbc.policy.USER_CODE_BASE=/myhome/application/- -Doracle.jdbc.policy.CONFIG_FILE=$TNS_ADMIN/ojdbc.properties -Djava.security.manager -Djava.security.policy=myojdbc.policy Select
Please update above command with your actual host, port, application directory, etc.
myojdbc.policy file looks as shown below:
grant codeBase "file:${oracle.jdbc.policy.JDBC_CODE_BASE}" {
/* Always needed */
permission java.sql.SQLPermission "deregisterDriver", "";
permission java.util.PropertyPermission "user.name", "read";
permission java.util.PropertyPermission "oracle.jdbc.*", "read";
permission java.util.PropertyPermission "database", "read";
permission java.util.PropertyPermission "oracle.net.*", "read";
permission java.util.PropertyPermission "javax.net.ssl.*", "read";
permission java.lang.management.ManagementPermission "control";
permission javax.management.MBeanServerPermission "createMBeanServer";
permission javax.management.MBeanPermission "oracle.jdbc.driver.OracleDiagnosabilityMBean#[com.oracle.jdbc:type=diagnosability,*]", "registerMBean";
permission javax.management.MBeanTrustPermission "register";
permission java.lang.RuntimePermission "getenv.TNS_ADMIN";
permission java.util.PropertyPermission "TNS_ADMIN", "read";
permission java.io.FilePermission "${oracle.jdbc.policy.CONFIG_FILE}", "read";
permission java.lang.RuntimePermission "accessDeclaredMembers"; permission java.util.PropertyPermission "java.util.logging.config.file", "read";
/* Needed only if you use the Thin driver */ permission java.net.SocketPermission "${oracle.jdbc.policy.CLIENT_HOST}", "connect,resolve";
permission java.net.SocketPermission "${oracle.jdbc.policy.DBMS_HOST}:${oracle.jdbc.policy.DBMS_PORT}", "connect,resolve";
/* Allow the JDBC driver to auto-resolve and instantiate the Oracle PKI * Provider (For SSL with Oracle Wallets). Not needed if the Oracle PKI * provider is registered with Java security. */
permission java.util.PropertyPermission "oracle.pki.*", "read";
permission java.security.SecurityPermission "putProviderProperty.OraclePKI";
/* Allow the driver to obtain all key stores from Key Store Service */
permission oracle.security.jps.service.keystore.KeyStoreAccessPermission "stripeName=*,keystoreName=*,alias=*", "read"; };
grant codeBase "file:${oracle.jdbc.policy.USER_CODE_BASE}" {
permission java.io.FilePermission "${oracle.jdbc.policy.USER_CODE_BASE}","read,write";
permission java.io.FilePermission "${oracle.jdbc.policy.ORAI18N}", "read";
permission javax.management.MBeanServerPermission "createMBeanServer";
permission java.lang.RuntimePermission "accessDeclaredMembers";
permission java.util.PropertyPermission "oracle.jdbc.*", "read";
/* Needed only if you use the Thin driver */
permission java.net.SocketPermission "${oracle.jdbc.policy.DBMS_HOST}:${oracle.jdbc.policy.DBMS_PORT}", "connect,resolve";
permission java.net.SocketPermission "${oracle.jdbc.policy.CLIENT_HOST}", "connect,resolve";
/* Needed only if you use Key Store Service. Replace the * to limit access. */
permission oracle.security.jps.service.keystore.KeyStoreAccessPermission "stripeName=*,keystoreName=*,alias=*", "read"; };
If you use the Thick driver then, you need to add more permissions in the myojdbc.policy file as shown below:
grant codeBase "file:${oracle.jdbc.policy.JDBC_CODE_BASE}" { …
/* Needed only if you use the OCI driver */
permission java.lang.RuntimePermission "loadLibrary.ocijdbc19"; }
Sample-2: Application uses a Universal Connection Pool and query a table
I have a UCPSelect.java which connects to a database and then select from a table (e.g. DUAL) in that database. This time it uses the Universal Connection Pool. Here is the code snippet for it:
…
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource();
String url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=myhost)(PORT=myport))(CONNECT_DATA=(SERVICE_NAME=myservicename)))";
pds.setURL(url);
pds.setConnectionFactoryClassName(OracleDataSource.class.getName());
…
Connection conn = pds.getConnection();
Statement statement = conn.createStatement();
ResultSet rs = statement.executeQuery(“SELECT * FROM dual”);
…
You can run this sample to use the file using the following command:
java -Doracle.jdbc.policy.CLIENT_HOST=myclienthost -Doracle.jdbc.policy.DBMS_HOST=myserverhost -Doracle.jdbc.policy.DBMS_PORT=myport -Doracle.jdbc.policy.JDBC_CODE_BASE=$ORACLE_HOME/lib/ojdbc8.jar -Doracle.jdbc.policy.CONNECTION_POOL_CODE_BASE=$ORACLE_HOME/lib/ucp.jar -Doracle.jdbc.policy.USER_CODE_BASE=/myhome/application/- -Doracle.jdbc.policy.CONFIG_FILE=$TNS_ADMIN/ojdbc.properties -Djava.security.manager -Djava.security.policy=myojdbc.policy UCPSelect
You need to add more permissions in the myojdbc.policy file as shown below:
/* Needed only if you use connection pool. */
grant codeBase "file:${oracle.jdbc.policy.CONNECTION_POOL_CODE_BASE}" {
/* Always needed */
permission java.util.PropertyPermission "oracle.ucp.*", "read";
permission java.util.PropertyPermission "oracle.jdbc.*", "read";
permission java.util.PropertyPermission "oracle.jdbc.fanEnabled", "write";
permission java.util.PropertyPermission "oracle.jdbc.beginRequestAtConnectionCreation", "write";
permission java.util.PropertyPermission "java.util.logging.config.file", "read";
permission java.lang.RuntimePermission "accessDeclaredMembers";
permission java.lang.RuntimePermission "shutdownHooks";
permission java.lang.RuntimePermission "modifyThread";
permission javax.management.MBeanServerPermission "createMBeanServer";
permission javax.management.MBeanPermission "oracle.ucp.admin.UniversalConnectionPoolManagerMBean#-[oracle.ucp.admin:name=UniversalConnectionPoolManagerMBean(*),*]", "registerMBean";
permission javax.management.MBeanPermission "oracle.ucp.admin.JDBCUniversalConnectionPoolMBeanImpl#-[oracle.ucp.admin.UniversalConnectionPoolMBean:name=*]", "registerMBean";
/* Needed only if you use the Thin driver */ permission java.net.SocketPermission "${oracle.jdbc.policy.CLIENT_HOST}", "connect,resolve";
permission java.net.SocketPermission "${oracle.jdbc.policy.DBMS_HOST}:${oracle.jdbc.policy.DBMS_PORT}", "connect,resolve"; };
The JDBC driver features and the required permissions
Only define the system properties required by the JDBC features you use. Many permissions based on a feature in use such as DMS, XA, XDB, AQ, NLS, etc.
Here is the table showing features and related permissions to grant in the policy file for the ojdbc??.jar codebase:
Feature |
Permissions |
Remark |
NLS |
java.io.FilePermission "${oracle.jdbc.policy.ORAI18N}", "read"; |
Put orai18n.jar in your classpath |
AQ or DCN |
java.net.SocketPermission "${oracle.jdbc.policy.DBMS_HOST}", "accept"; |
|
DMS |
java.util.PropertyPermission "oracle.dms.console.DMSConsole", "read"; |
|
XA |
java.util.PropertyPermission "oracle.jserver.version", "read"; |
|
XML |
java.util.PropertyPermission "oracle.xdkjava.compatibility.version", "read"; |
|
Fast Connection Failover |
oracle.ons.CreatePermission "ONSUser"; |
Remote ONS host:port |
The sample ojdbc.policy file contains comments for permissions needed for each feature and codebase. Please read it and make the necessary changes for your application requirement.
There may be a small performance penalty when you use the policy file. It only applies when an application attempts some activity that requires permission checks. Most operations that require permission checks are expensive operations (IO, Network access, etc.) so the overhead of security checks will be a pretty low percentage of total runtime. Benchmark your application to determine performance overhead.
http://docs.oracle.com/javase/8/docs/technotes/guides/security/PolicyFiles.html#FileSyntax
http://docs.oracle.com/javase/8/docs/technotes/guides/security/permissions.html
http://www.oracle.com/technetwork/database/features/jdbc/jdbc-ucp-122-3110062.html
Previous Post
Next Post