Cross Column

Showing posts with label Java Security Manager. Show all posts
Showing posts with label Java Security Manager. Show all posts

Monday, December 22, 2014

Java Security Manager: Troubshooting Security

In [1], we have discussed how to fix security violations when Java Security Manager is enabled at WebLogic Server start-up.  In this article, we will look at how to troubleshoot security policy-related issues by using the java.security.debug option.

java.security.debug


To troubleshoot security policy-related issues, you can configure Java Security Manager with the level of security-related information to be reported using:
java.security.debug  
To find out what the debug option offers, do:
java -Djava.security.debug=help
If using JDK 7, you can find more information from [2].  As for JDK 8, we have included the list of debugging options in the Addendum for your convenience.  Note that you need to separate multiple options with a comma.  For example, we will look at the output from the following combination of debug options:
-Djava.security.debug=policy,access


policy Option


Setting "policy" option will allow Security Manager to report the details of
Loading and granting permissions with policy file
For example, from the WebLogic Server log file, you can find the following entries:

policy: Adding policy entry: 
policy:   signedBy null
policy:   codeBase file:/home/myusername/wls1221141208/wlserver/server/lib/-
policy:   ("java.security.AllPermission" "" "")
policy:
policy: Adding policy entry: 
policy:   signedBy null
policy:   codeBase file:/home/myusername/wls1221141208/wlserver/modules/-
policy:   ("java.security.AllPermission" "" "")
policy:


which correspond to grant entries from the weblogic.policy:[5]

grant codeBase "file:/home/myusername/wls1221141208/wlserver/server/lib/-" {
  permission java.security.AllPermission;
};

grant codeBase "file:/home/myusername/wls1221141208/wlserver/modules/-" {
  permission java.security.AllPermission;
};

Beside of policy loading entries, you could also find other entries (e.g. permission granting entries) such as:

policy:   granting ("java.util.PropertyPermission" "java.version" "read")
policy:   granting ("java.util.PropertyPermission" "java.vendor" "read")


access Option


Enabling access option, allows Security Manager to print all results from the AccessController.checkPermission method.

You can use the following options with the access option:
  • stack: Include stack trace
  • domain: Dump all domains (i.e., protection domain) in context
  • failure:[3] Before throwing exception, dump stack and domain that do not have permission
You can also use the following options with the stack and domain options:
  • permission=<classname>[4]
    • Only dump output if specified permission is being checked 
  • codebase=<URL>
    • This option would be useful when customer desires to trace the permissions impact of only the code in a given code souce, such as jar file.
    • URL is the location of the specified code base. 
      • Note that because the comma (',") is used as multi options separator, if the URL contains comma, the security debugger would not work properly as expected, it is recommended that the URL should not include character comma (','), semicolon (';'), and  space.

Addendum


$ jdk-hs/bin/java -Djava.security.debug=help

all           turn on all debugging
access        print all checkPermission results
certpath      PKIX CertPathBuilder and
              CertPathValidator debugging
combiner      SubjectDomainCombiner debugging
gssloginconfig
              GSS LoginConfigImpl debugging
configfile    JAAS ConfigFile loading
configparser  JAAS ConfigFile parsing
jar           jar verification
logincontext  login context results
jca           JCA engine class debugging
policy        loading and granting
provider      security provider debugging
pkcs11        PKCS11 session manager debugging
pkcs11keystore
              PKCS11 KeyStore debugging
sunpkcs11     SunPKCS11 provider debugging
scl           permissions SecureClassLoader assigns
ts            timestamping

The following can be used with access:

stack         include stack trace
domain        dump all domains in context
failure       before throwing exception, dump stack
              and domain that didn't have permission

The following can be used with stack and domain:

permission=
              only dump output if specified permission
              is being checked
codebase=
              only dump output if specified codebase
              is being checked

The following can be used with provider:

engine=
              only dump output for the specified list
              of JCA engines. Supported values:
              Cipher, KeyAgreement, KeyGenerator,
              KeyPairGenerator, KeyStore, Mac,
              MessageDigest, SecureRandom, Signature.

References

  1. Java Security Manager: java.security.AccessControlException: access denied (Xml and More)
  2. Troubshooting Security
  3. Debugging Security Policy Issues
    • JAVA_OPTS="$JAVA_OPTS -Djava.security.debug=access:failure"
  4. Fine granularity diagnosis on security
    • -Djava.security.debug=access,stack,permission=java.io.FilePermission
  5. Java SecurityManager: "java.security" and "java.policy" Files (Xml and More)

Saturday, December 13, 2014

Java Security Manager: java.security.AccessControlException: access denied

The JVM has security mechanisms built into it that allow you to define restrictions to code through Java security policy files (i.e., java.policy file). The Java Security Manager[1] uses these policies to enforce a set of permissions granted to classes. The permissions allow specified classes running in that instance of the JVM to allow or not allow certain runtime operations.



In this article, we will cover how to resolve security violations such as
java.security.AccessControlException: access denied
when you start WebLogic Server with Java Security checking enabled (see [1] for how to enable Java Security Manager).

java.security.AccessControlException


AccessController is the main security enforcer in Java Security Manager.  It helps decide whether an access to a critical system resource is to be allowed or denied, based on the security policy currently in effect,  For example, an java.security.AccessControlException will be thrown when a permission was not granted to read weblogic.security.DumpContextHandler property as below:

Caused by: java.security.AccessControlException: access denied ("java.util.PropertyPermission" "weblogic.security.DumpContextHandler" "read")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:457)
at java.security.AccessController.checkPermission(AccessController.java:884)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1294)
at java.lang.System.getProperty(System.java:714)
at java.lang.Boolean.getBoolean(Boolean.java:254)
at weblogic.security.utils.SecurityUtils.(SecurityUtils.java:23)

If the security violations in your application are only a few, you may consider to add an entry like below in the default section of your policy file:

// default permissions granted to all protection domains
grant {
    ...
    permission java.util.PropertyPermission "weblogic.security.DumpContextHandler", "read";
    ...
};

"weblogic.policy" and "ojdbc.policy"


When you run applications in WebLogic server, Oracle has provided an OOTB policy file at:
${WL_HOME}/server/lib/weblogic.policy
If you specify it in the JVM option:
-Djava.security.policy=${WL_HOME}/server/lib/weblogic.policy
then the specified policy file will be loaded in addition to all the java policy files (see [1] for details). However,  OOTB weblogic.policy is not intended to cover all deployed applications.  For example, if you use Oracle JDBC Driver in your applications, you may need to add the grant entries specified in ojdbc.policy[2] onto the ones specified in weblogic.policy file.

Grant Entries


If you look at either weblogic.policy or ojdbc.policy file, there are many grant entries. The basic format of a grant entry is the following:[4]

  grant signedBy "signer_names", codeBase "URL",
        principal principal_class_name "principal_name",
        principal principal_class_name "principal_name",
        ... {
      permission permission_class_name "target_name", "action", 
          signedBy "signer_names";
      permission permission_class_name "target_name", "action", 
          signedBy "signer_names";
      ...
  };

Each grant entry includes one or more "permission entries" preceded by optional codeBase, signedBy, and principal name/value pairs that specify which code you want to grant the permissions.

Sometimes it will be too much to enumerate all permissions individually.  This is the time for granting permissions by any combination of the following entries:
  • SignedBy
  • Principal
  • CodeBase

Grant Permission by SignedBy


An example of granting permission(s) based on signer is shown below:[3]
keystore "kim.keystore";

// Here is the permission ExampleGame needs.
// It grants code signed by "terry" the
// HighScorePermission, if the
// HighScorePermission was signed by "chris"
grant SignedBy "terry" {
  permission
    com.scoredev.scores.HighScorePermission
      "ExampleGame", signedBy "chris";
};
A signedBy value indicates the alias for a certificate stored in the keystore. The public key within that certificate is used to verify the digital signature on the code; you grant the permission(s) to code signed by the private key corresponding to the public key in the keystore entry specified by the alias.

The signedBy value can be a comma-separated list of multiple aliases. An example is "Adam,Eve,Charles", which means "signed by Adam and Eve and Charles"; the relationship is AND, not OR. To be more exact, a statement like "Code signed by Adam" means "Code in a class file contained in a JAR which is signed using the private key corresponding to the public key certificate in the keystore whose entry is aliased by Adam".

Grant Permission by Principal


An example of granting permission(s) based on principal is shown below:
// Grant notification listener actions to standard roles

grant principal weblogic.security.principal.WLSGroupImpl "Administrators" {
    permission javax.management.MBeanPermission "*", "addNotificationListener";
    permission javax.management.MBeanPermission "*", "removeNotificationListener";

};
A principal value specifies a class_name/principal_name pair which must be present within the executing thread's principal set. The principal set is associated with the executing code by way of a Subject.

The principal_class_name may be set to the wildcard value, *, which allows it to match any Principal class. In addition, the principal_name may also be set to the wildcard value, *, allowing it to match any Principal name. When setting the principal_class_name or principal_name to *, do not surround the * with quotes. Also, if you specify a wildcard principal class, you must also specify a wildcard principal name.

Grant Permission by CodeBase


A codeBase value indicates the code source location; you grant the permission(s) to code from that location. An example of granting permission by CodeBase is shown below:
// Grant for internal applications when using WebLogic startup scripts
grant codeBase "file:${user.dir}/servers/${weblogic.Name}/tmp/_WL_internal/-" {
  permission java.security.AllPermission;
};

BNF Grammar


An informal BNF grammer for the Policy file format is given below, where non-capitalized terms are terminals:[12]

PolicyFile -> PolicyEntry | PolicyEntry; PolicyFile
PolicyEntry -> grant {PermissionEntry}; |
           grant SignerEntry {PermissionEntry} |
           grant CodebaseEntry {PermissionEntry} |
           grant PrincipalEntry {PermissionEntry} |
           grant SignerEntry, CodebaseEntry {PermissionEntry} |
           grant CodebaseEntry, SignerEntry {PermissionEntry} |
           grant SignerEntry, PrincipalEntry {PermissionEntry} |
           grant PrincipalEntry, SignerEntry {PermissionEntry} |
           grant CodebaseEntry, PrincipalEntry {PermissionEntry} |
           grant PrincipalEntry, CodebaseEntry {PermissionEntry} |
           grant SignerEntry, CodebaseEntry, PrincipalEntry {PermissionEntry} |
           grant CodebaseEntry, SignerEntry, PrincipalEntry {PermissionEntry} |
           grant SignerEntry, PrincipalEntry, CodebaseEntry {PermissionEntry} |
           grant CodebaseEntry, PrincipalEntry, SignerEntry {PermissionEntry} |
           grant PrincipalEntry, CodebaseEntry, SignerEntry {PermissionEntry} |
           grant PrincipalEntry, SignerEntry, CodebaseEntry {PermissionEntry} |
           keystore "url"
SignerEntry -> signedby (a comma-separated list of strings)
CodebaseEntry -> codebase (a string representation of a URL)
PrincipalEntry -> OnePrincipal | OnePrincipal, PrincipalEntry
OnePrincipal -> principal [ principal_class_name ] "principal_name" (a principal)
PermissionEntry -> OnePermission | OnePermission PermissionEntry
OnePermission -> permission permission_class_name
                 [ "target_name" ] [, "action_list"]
                 [, SignerEntry];

Some entries in the grammar are optional, If they are omitted, it signifies:

When Omitted
It Means
CodebaseEntry "any code base" (it doesn't matter where the code originates from)
SignerEntry "any signer" (it doesn't matter whether the code is signed or not or by whom)
PrincipalEntry "any principals"


The "target_name"is the name of the permission is aimed.  For java.io.FilePermission, the targets of this class can be specified as:

file
directory (same as directory/)
directory/file
directory/* (all files in this directory)
* (all files in the current directory)
directory/- (all files in the file system under this directory)
- (all files in the file system under the current directory)
"<<ALL FILES>>" (all files in the file system)

As an example, you may grant read permission to all files in the file system as below:
permission java.io.FilePermission "<<ALL FILES>>", "read"; 

Finally, a set of actions can be specified together as a comma-separated composite string as below:
permission java.io.FilePermission "WEBLOGIC-APPLICATION-ROOT${/}-", "read, write, delete, execute";

References

© Travel for Life Guide. All Rights Reserved.

Analytical Insights on Health, Culture, and Security.