18

Is there any way to completely disable Java security manager?

I'm experimenting with source code of db4o. It uses reflection to persist objects and it seems that security manager doesn't allow reflection to read and write private or protected fields.

My code:

public static void main(String[] args) throws IOException {
    System.out.println("start");
    new File( DB_FILE_NAME ).delete();
    ObjectContainer container = Db4o.openFile( DB_FILE_NAME );
    String ob = new String( "test" );
    container.store( ob );
    ObjectSet result = container.queryByExample( String.class );
    System.out.println( "retrieved (" + result.size() + "):" );
    while( result.hasNext() ) {
        System.out.println( result.next() );
    }
    container.close();
    System.out.println("finish");
}

Output:

start
[db4o 7.4.68.12069   2009-04-18 00:21:30] 
 AccessibleObject#setAccessible() is not available. Private fields can not be stored.
retrieved (0):
finish


This thread suggests modifying java.policy file to allow reflection but it doesn't seem to work for me.

I'm starting JVM with arguments
-Djava.security.manager -Djava.security.policy==/home/pablo/.java.policy
so specified policy file will be the only policy file used

The file looks like this:

grant {
    permission java.security.AllPermission;
    permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
};

I spent last 3 hrs on this and don't have any ideas how to make this work. Any help appreciated.

Pawel Piatkowski
  • 2,359
  • 3
  • 15
  • 8

3 Answers3

7

You could try adding this to the main() of your program:

System.setSecurityManager(null);

Worked for me for a "trusted" WebStart application when I was having security manager issues. Not sure if it will work for your db4o case, but it might be worth a try.

EDIT: I'm not suggesting that this is a general solution to security manager problems. I was just proposing it as a way to help debug the original poster's problem. Clearly, if you want to benefit from a security manager then you should not disable it.

hallidave
  • 9,579
  • 6
  • 31
  • 27
  • 1
    That's generally not advised as it can be used by malicious code to take down security and gain local user privileges. – Tom Hawtin - tackline Apr 18 '09 at 05:11
  • 8
    The original poster *is* looking to 'completely disable' the security manager! :-) – Brian Agnew Apr 18 '09 at 09:26
  • Thanks, I was getting exception in "trusted" WebStart Application and calling System.setSecurityManager(null); worked for me – siddagrl Feb 27 '12 at 06:35
  • 2
    Well, the security manager can prevent setting the security manager, which is bad for attackers, but it allows one to create a "super" security manager that remains permanent throughout the rest of the program flow. – gparyani Aug 14 '13 at 21:20
  • 1
    @gparyani: Correct, thanks. Elaborating on your point, the program must have `java.lang.RuntimePermission` with `setSecurityManager` permission in order to be able to set the security manager. – Sadeq Dousti Mar 02 '19 at 12:50
5

Do you really have two '=' signs in your java.security.policy command line option? That won't work. Make sure you are setting the property as

-Djava.security.policy=/home/pablo/.java.policy

To actually disable the SecurityManager, simply leaving off the java.security.manager system property altogether should be enough.


Update: As I was reading the documentation for policy files to learn more about the "==" syntax, I noticed that unless the policy file is in the current working directory, it needs to be specified as a URL (including scheme). Have you tried prefixing the policy path with the "file:" scheme?

I was also puzzled because (assuming you are running as user "pablo"), it looks like that policy should be loaded by default from your home directory, so you shouldn't need to specify it at all. On the other hand, if you are not running as the user "pablo", maybe the file is not readable.

erickson
  • 265,237
  • 58
  • 395
  • 493
  • 5
    That doesn't work. Neither does not passing any arguments to JVM. BTW '==' means that specified file will be the only file used. Single '=' means that the file will be used along with standard policy files. At least that's what I've read. – Pawel Piatkowski Apr 17 '09 at 23:09
4

I found this example of how to make private fields and methods accessible to your code. Basically, it distills down to the use of Field.setAccessible(true) and Method.setAccessible(true)

Field example:

Field privateStringField = PrivateObject.class.
            getDeclaredField("privateString");

privateStringField.setAccessible(true);

Method example:

Method privateStringMethod = PrivateObject.class.
        getDeclaredMethod("getPrivateString", null);

privateStringMethod.setAccessible(true);

You could also look at using Groovy with your Java code as it (currently) circumvents much of the access level restrictions of Java code. Although, this message board posting seems to suggest this 'feature' may change in future versions of Groovy.

Kevin Williams
  • 2,588
  • 3
  • 24
  • 25
  • 7
    By disabling the security manager you get permission to call setAccessible(true). Without disabling the security manager you wouldn't have a prayer. – extraneon Apr 18 '09 at 12:37
  • @Kevin: I can call setAccesible for private fields in my own code. And by 'my own code' I mean a class I added to db4o sources. – Pawel Piatkowski Apr 18 '09 at 16:02
  • You should be able to call it on your code as long as you are not running it in an an applet or some other environment with a contravening security manager just as (+1) @extraneon suggests. This artima post has a good explanation of Java Security Manager: http://www.artima.com/underthehood/securitymanager.html – Kevin Williams Apr 20 '09 at 05:53