nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineSecurityTest.java
changeset 29784 b9220497eb43
parent 29783 db33e568f107
parent 29770 6415d011ad02
child 29785 da950f343762
equal deleted inserted replaced
29783:db33e568f107 29784:b9220497eb43
     1 /*
       
     2  * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package jdk.nashorn.api.scripting;
       
    27 
       
    28 import static org.testng.Assert.fail;
       
    29 import java.lang.reflect.InvocationHandler;
       
    30 import java.lang.reflect.Method;
       
    31 import java.lang.reflect.Proxy;
       
    32 import javax.script.ScriptEngine;
       
    33 import javax.script.ScriptEngineManager;
       
    34 import javax.script.ScriptException;
       
    35 import org.testng.annotations.Test;
       
    36 
       
    37 /**
       
    38  * jsr223 tests for security access checks.
       
    39  */
       
    40 @SuppressWarnings("javadoc")
       
    41 public class ScriptEngineSecurityTest {
       
    42 
       
    43     private static void log(final String msg) {
       
    44         org.testng.Reporter.log(msg, true);
       
    45     }
       
    46 
       
    47     @Test
       
    48     public void securityPackagesTest() {
       
    49         if (System.getSecurityManager() == null) {
       
    50             // pass vacuously
       
    51             return;
       
    52         }
       
    53 
       
    54         final ScriptEngineManager m = new ScriptEngineManager();
       
    55         final ScriptEngine e = m.getEngineByName("nashorn");
       
    56         try {
       
    57             e.eval("var v = Packages.sun.misc.Unsafe;");
       
    58             fail("should have thrown SecurityException");
       
    59         } catch (final Exception exp) {
       
    60             if (exp instanceof SecurityException) {
       
    61                 log("got " + exp + " as expected");
       
    62             } else {
       
    63                 fail(exp.getMessage());
       
    64             }
       
    65         }
       
    66     }
       
    67 
       
    68     @Test
       
    69     public void securityJavaTypeTest() {
       
    70         if (System.getSecurityManager() == null) {
       
    71             // pass vacuously
       
    72             return;
       
    73         }
       
    74 
       
    75         final ScriptEngineManager m = new ScriptEngineManager();
       
    76         final ScriptEngine e = m.getEngineByName("nashorn");
       
    77         try {
       
    78             e.eval("var v = Java.type('sun.misc.Unsafe');");
       
    79             fail("should have thrown SecurityException");
       
    80         } catch (final Exception exp) {
       
    81             if (exp instanceof SecurityException) {
       
    82                 log("got " + exp + " as expected");
       
    83             } else {
       
    84                 fail(exp.getMessage());
       
    85             }
       
    86         }
       
    87     }
       
    88 
       
    89     @Test
       
    90     public void securityClassForNameTest() {
       
    91         if (System.getSecurityManager() == null) {
       
    92             // pass vacuously
       
    93             return;
       
    94         }
       
    95 
       
    96         final ScriptEngineManager m = new ScriptEngineManager();
       
    97         final ScriptEngine e = m.getEngineByName("nashorn");
       
    98         try {
       
    99             e.eval("var v = java.lang.Class.forName('sun.misc.Unsafe');");
       
   100             fail("should have thrown SecurityException");
       
   101         } catch (final Exception exp) {
       
   102             if (exp instanceof SecurityException) {
       
   103                 log("got " + exp + " as expected");
       
   104             } else {
       
   105                 fail(exp.getMessage());
       
   106             }
       
   107         }
       
   108     }
       
   109 
       
   110     @Test
       
   111     public void securitySystemExit() {
       
   112         if (System.getSecurityManager() == null) {
       
   113             // pass vacuously
       
   114             return;
       
   115         }
       
   116 
       
   117         final ScriptEngineManager m = new ScriptEngineManager();
       
   118         final ScriptEngine e = m.getEngineByName("nashorn");
       
   119         try {
       
   120             e.eval("java.lang.System.exit(0);");
       
   121             fail("should have thrown SecurityException");
       
   122         } catch (final Exception exp) {
       
   123             if (exp instanceof SecurityException) {
       
   124                 log("got " + exp + " as expected");
       
   125             } else {
       
   126                 fail(exp.getMessage());
       
   127             }
       
   128         }
       
   129     }
       
   130 
       
   131 
       
   132     @Test
       
   133     public void securitySystemExitFromFinalizerThread() throws ScriptException {
       
   134         if (System.getSecurityManager() == null) {
       
   135             // pass vacuously
       
   136             return;
       
   137         }
       
   138 
       
   139         final ScriptEngineManager m = new ScriptEngineManager();
       
   140         final ScriptEngine e = m.getEngineByName("nashorn");
       
   141         e.eval("var o = Java.extend(Java.type('javax.imageio.spi.ServiceRegistry'), { deregisterAll: this.exit.bind(null, 1234)});\n" +
       
   142                 "new o(new java.util.ArrayList().iterator())");
       
   143         System.gc();
       
   144         System.runFinalization();
       
   145         // NOTE: this test just exits the VM if it fails.
       
   146     }
       
   147 
       
   148     @Test
       
   149     public void securitySystemLoadLibrary() {
       
   150         if (System.getSecurityManager() == null) {
       
   151             // pass vacuously
       
   152             return;
       
   153         }
       
   154 
       
   155         final ScriptEngineManager m = new ScriptEngineManager();
       
   156         final ScriptEngine e = m.getEngineByName("nashorn");
       
   157         try {
       
   158             e.eval("java.lang.System.loadLibrary('foo');");
       
   159             fail("should have thrown SecurityException");
       
   160         } catch (final Exception exp) {
       
   161             if (exp instanceof SecurityException) {
       
   162                 log("got " + exp + " as expected");
       
   163             } else {
       
   164                 fail(exp.getMessage());
       
   165             }
       
   166         }
       
   167     }
       
   168 
       
   169     // @bug 8032948: Nashorn linkages awry
       
   170     @SuppressWarnings("serial")
       
   171     public static class FakeProxy extends Proxy {
       
   172         public FakeProxy(final InvocationHandler ih) {
       
   173             super(ih);
       
   174         }
       
   175 
       
   176         public static Class<?> makeProxyClass(final ClassLoader cl, final Class<?>... ifaces) {
       
   177             return Proxy.getProxyClass(cl, ifaces);
       
   178         }
       
   179     }
       
   180 
       
   181     @Test
       
   182     public void fakeProxySubclassAccessCheckTest() {
       
   183         if (System.getSecurityManager() == null) {
       
   184             // pass vacuously
       
   185             return;
       
   186         }
       
   187 
       
   188         final ScriptEngineManager m = new ScriptEngineManager();
       
   189         final ScriptEngine e = m.getEngineByName("nashorn");
       
   190 
       
   191         e.put("name", ScriptEngineSecurityTest.class.getName());
       
   192         e.put("cl", ScriptEngineSecurityTest.class.getClassLoader());
       
   193         e.put("intfs", new Class[] { Runnable.class });
       
   194 
       
   195         final String getClass = "Java.type(name + '$FakeProxy').getProxyClass(cl, intfs);";
       
   196 
       
   197         // Should not be able to call static methods of Proxy via fake subclass
       
   198         try {
       
   199             e.eval(getClass);
       
   200             fail("should have thrown SecurityException");
       
   201         } catch (final Exception exp) {
       
   202             if (! (exp instanceof SecurityException)) {
       
   203                 fail("SecurityException expected, got " + exp);
       
   204             }
       
   205         }
       
   206     }
       
   207 
       
   208     @Test
       
   209     public void fakeProxySubclassAccessCheckTest2() {
       
   210         if (System.getSecurityManager() == null) {
       
   211             // pass vacuously
       
   212             return;
       
   213         }
       
   214 
       
   215         final ScriptEngineManager m = new ScriptEngineManager();
       
   216         final ScriptEngine e = m.getEngineByName("nashorn");
       
   217 
       
   218         e.put("name", ScriptEngineSecurityTest.class.getName());
       
   219         e.put("cl", ScriptEngineSecurityTest.class.getClassLoader());
       
   220         e.put("intfs", new Class[] { Runnable.class });
       
   221 
       
   222         final String getClass = "Java.type(name + '$FakeProxy').makeProxyClass(cl, intfs);";
       
   223 
       
   224         // Should not be able to call static methods of Proxy via fake subclass
       
   225         try {
       
   226             e.eval(getClass);
       
   227             fail("should have thrown SecurityException");
       
   228         } catch (final Exception exp) {
       
   229             if (! (exp instanceof SecurityException)) {
       
   230                 fail("SecurityException expected, got " + exp);
       
   231             }
       
   232         }
       
   233     }
       
   234 
       
   235     @Test
       
   236     public static void proxyStaticAccessCheckTest() {
       
   237         if (System.getSecurityManager() == null) {
       
   238             // pass vacuously
       
   239             return;
       
   240         }
       
   241 
       
   242         final ScriptEngineManager m = new ScriptEngineManager();
       
   243         final ScriptEngine e = m.getEngineByName("nashorn");
       
   244         final Runnable r = (Runnable)Proxy.newProxyInstance(
       
   245             ScriptEngineTest.class.getClassLoader(),
       
   246             new Class[] { Runnable.class },
       
   247             new InvocationHandler() {
       
   248                 @Override
       
   249                 public Object invoke(final Object p, final Method mtd, final Object[] a) {
       
   250                     return null;
       
   251                 }
       
   252             });
       
   253 
       
   254         e.put("rc", r.getClass());
       
   255         e.put("cl", ScriptEngineSecurityTest.class.getClassLoader());
       
   256         e.put("intfs", new Class[] { Runnable.class });
       
   257 
       
   258         // make sure static methods of Proxy is not accessible via subclass
       
   259         try {
       
   260             e.eval("rc.static.getProxyClass(cl, intfs)");
       
   261             fail("Should have thrown SecurityException");
       
   262         } catch (final Exception exp) {
       
   263             if (! (exp instanceof SecurityException)) {
       
   264                 fail("SecurityException expected, got " + exp);
       
   265             }
       
   266         }
       
   267     }
       
   268 
       
   269 
       
   270     @Test
       
   271     public void nashornConfigSecurityTest() {
       
   272         if (System.getSecurityManager() == null) {
       
   273             // pass vacuously
       
   274             return;
       
   275         }
       
   276 
       
   277         final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
       
   278         try {
       
   279             fac.getScriptEngine(new ClassFilter() {
       
   280                @Override
       
   281                public boolean exposeToScripts(final String name) {
       
   282                    return true;
       
   283                }
       
   284             });
       
   285             fail("SecurityException should have been thrown");
       
   286         } catch (final SecurityException e) {
       
   287             //empty
       
   288         }
       
   289     }
       
   290 
       
   291     @Test
       
   292     public void nashornConfigSecurityTest2() {
       
   293         if (System.getSecurityManager() == null) {
       
   294             // pass vacuously
       
   295             return;
       
   296         }
       
   297 
       
   298         final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
       
   299         try {
       
   300             fac.getScriptEngine(new String[0], null, new ClassFilter() {
       
   301                @Override
       
   302                public boolean exposeToScripts(final String name) {
       
   303                    return true;
       
   304                }
       
   305             });
       
   306             fail("SecurityException should have been thrown");
       
   307         } catch (final SecurityException e) {
       
   308             //empty
       
   309         }
       
   310     }
       
   311 }