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.test; 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 jdk.nashorn.api.scripting.ClassFilter; 36 import jdk.nashorn.api.scripting.NashornScriptEngineFactory; 37 import org.testng.annotations.Test; 38 39 /** 40 * jsr223 tests for security access checks. 41 */ 42 @SuppressWarnings("javadoc") 43 public class ScriptEngineSecurityTest { 44 45 private static void log(final String msg) { 46 org.testng.Reporter.log(msg, true); 47 } 48 49 @Test 50 public void securityPackagesTest() { 51 if (System.getSecurityManager() == null) { 52 // pass vacuously 53 return; 54 } 55 56 final ScriptEngineManager m = new ScriptEngineManager(); 57 final ScriptEngine e = m.getEngineByName("nashorn"); 58 try { 59 e.eval("var v = Packages.sun.misc.Unsafe;"); 60 fail("should have thrown SecurityException"); 61 } catch (final Exception exp) { 62 if (exp instanceof SecurityException) { 63 log("got " + exp + " as expected"); 64 } else { 65 fail(exp.getMessage()); 66 } 67 } 68 } 69 70 @Test 71 public void securityJavaTypeTest() { 72 if (System.getSecurityManager() == null) { 73 // pass vacuously 74 return; 75 } 76 77 final ScriptEngineManager m = new ScriptEngineManager(); 78 final ScriptEngine e = m.getEngineByName("nashorn"); 79 try { 80 e.eval("var v = Java.type('sun.misc.Unsafe');"); 81 fail("should have thrown SecurityException"); 82 } catch (final Exception exp) { 83 if (exp instanceof SecurityException) { 84 log("got " + exp + " as expected"); 85 } else { 86 fail(exp.getMessage()); 87 } 88 } 89 } 90 91 @Test 92 public void securityClassForNameTest() { 93 if (System.getSecurityManager() == null) { 94 // pass vacuously 95 return; 96 } 97 98 final ScriptEngineManager m = new ScriptEngineManager(); 99 final ScriptEngine e = m.getEngineByName("nashorn"); 100 try { 101 e.eval("var v = java.lang.Class.forName('sun.misc.Unsafe');"); 102 fail("should have thrown SecurityException"); 103 } catch (final Exception exp) { 104 if (exp instanceof SecurityException) { 105 log("got " + exp + " as expected"); 106 } else { 107 fail(exp.getMessage()); 108 } 109 } 110 } 111 112 @Test 113 public void securitySystemExit() { 114 if (System.getSecurityManager() == null) { 115 // pass vacuously 116 return; 117 } 118 119 final ScriptEngineManager m = new ScriptEngineManager(); 120 final ScriptEngine e = m.getEngineByName("nashorn"); 121 try { 122 e.eval("java.lang.System.exit(0);"); 123 fail("should have thrown SecurityException"); 124 } catch (final Exception exp) { 125 if (exp instanceof SecurityException) { 126 log("got " + exp + " as expected"); 127 } else { 128 fail(exp.getMessage()); 129 } 130 } 131 } 132 133 134 @Test 135 public void securitySystemExitFromFinalizerThread() throws ScriptException { 136 if (System.getSecurityManager() == null) { 137 // pass vacuously 138 return; 139 } 140 141 final ScriptEngineManager m = new ScriptEngineManager(); 142 final ScriptEngine e = m.getEngineByName("nashorn"); 143 e.eval("var o = Java.extend(Java.type('javax.imageio.spi.ServiceRegistry'), { deregisterAll: this.exit.bind(null, 1234)});\n" + 144 "new o(new java.util.ArrayList().iterator())"); 145 System.gc(); 146 System.runFinalization(); 147 // NOTE: this test just exits the VM if it fails. 148 } 149 150 @Test 151 public void securitySystemLoadLibrary() { 152 if (System.getSecurityManager() == null) { 153 // pass vacuously 154 return; 155 } 156 157 final ScriptEngineManager m = new ScriptEngineManager(); 158 final ScriptEngine e = m.getEngineByName("nashorn"); 159 try { 160 e.eval("java.lang.System.loadLibrary('foo');"); 161 fail("should have thrown SecurityException"); 162 } catch (final Exception exp) { 163 if (exp instanceof SecurityException) { 164 log("got " + exp + " as expected"); 165 } else { 166 fail(exp.getMessage()); 167 } 168 } 169 } 170 171 // @bug 8032948: Nashorn linkages awry 172 @SuppressWarnings("serial") 173 public static class FakeProxy extends Proxy { 174 public FakeProxy(final InvocationHandler ih) { 175 super(ih); 176 } 177 178 public static Class<?> makeProxyClass(final ClassLoader cl, final Class<?>... ifaces) { 179 return Proxy.getProxyClass(cl, ifaces); 180 } 181 } 182 183 @Test 184 public void fakeProxySubclassAccessCheckTest() { 185 if (System.getSecurityManager() == null) { 186 // pass vacuously 187 return; 188 } 189 190 final ScriptEngineManager m = new ScriptEngineManager(); 191 final ScriptEngine e = m.getEngineByName("nashorn"); 192 193 e.put("name", ScriptEngineSecurityTest.class.getName()); 194 e.put("cl", ScriptEngineSecurityTest.class.getClassLoader()); 195 e.put("intfs", new Class[] { Runnable.class }); 196 197 final String getClass = "Java.type(name + '$FakeProxy').getProxyClass(cl, intfs);"; 198 199 // Should not be able to call static methods of Proxy via fake subclass 200 try { 201 e.eval(getClass); 202 fail("should have thrown SecurityException"); 203 } catch (final Exception exp) { 204 if (! (exp instanceof SecurityException)) { 205 fail("SecurityException expected, got " + exp); 206 } 207 } 208 } 209 210 @Test 211 public void fakeProxySubclassAccessCheckTest2() { 212 if (System.getSecurityManager() == null) { 213 // pass vacuously 214 return; 215 } 216 217 final ScriptEngineManager m = new ScriptEngineManager(); 218 final ScriptEngine e = m.getEngineByName("nashorn"); 219 220 e.put("name", ScriptEngineSecurityTest.class.getName()); 221 e.put("cl", ScriptEngineSecurityTest.class.getClassLoader()); 222 e.put("intfs", new Class[] { Runnable.class }); 223 224 final String getClass = "Java.type(name + '$FakeProxy').makeProxyClass(cl, intfs);"; 225 226 // Should not be able to call static methods of Proxy via fake subclass 227 try { 228 e.eval(getClass); 229 fail("should have thrown SecurityException"); 230 } catch (final Exception exp) { 231 if (! (exp instanceof SecurityException)) { 232 fail("SecurityException expected, got " + exp); 233 } 234 } 235 } 236 237 @Test 238 public static void proxyStaticAccessCheckTest() { 239 if (System.getSecurityManager() == null) { 240 // pass vacuously 241 return; 242 } 243 244 final ScriptEngineManager m = new ScriptEngineManager(); 245 final ScriptEngine e = m.getEngineByName("nashorn"); 246 final Runnable r = (Runnable)Proxy.newProxyInstance( 247 ScriptEngineTest.class.getClassLoader(), 248 new Class[] { Runnable.class }, 249 new InvocationHandler() { 250 @Override 251 public Object invoke(final Object p, final Method mtd, final Object[] a) { 252 return null; 253 } 254 }); 255 256 e.put("rc", r.getClass()); 257 e.put("cl", ScriptEngineSecurityTest.class.getClassLoader()); 258 e.put("intfs", new Class[] { Runnable.class }); 259 260 // make sure static methods of Proxy is not accessible via subclass 261 try { 262 e.eval("rc.static.getProxyClass(cl, intfs)"); 263 fail("Should have thrown SecurityException"); 264 } catch (final Exception exp) { 265 if (! (exp instanceof SecurityException)) { 266 fail("SecurityException expected, got " + exp); 267 } 268 } 269 } 270 271 272 @Test 273 public void nashornConfigSecurityTest() { 274 if (System.getSecurityManager() == null) { 275 // pass vacuously 276 return; 277 } 278 279 final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); 280 try { 281 fac.getScriptEngine(new ClassFilter() { 282 @Override 283 public boolean exposeToScripts(final String name) { 284 return true; 285 } 286 }); 287 fail("SecurityException should have been thrown"); 288 } catch (final SecurityException e) { 289 //empty 290 } 291 } 292 293 @Test 294 public void nashornConfigSecurityTest2() { 295 if (System.getSecurityManager() == null) { 296 // pass vacuously 297 return; 298 } 299 300 final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); 301 try { 302 fac.getScriptEngine(new String[0], null, new ClassFilter() { 303 @Override 304 public boolean exposeToScripts(final String name) { 305 return true; 306 } 307 }); 308 fail("SecurityException should have been thrown"); 309 } catch (final SecurityException e) { 310 //empty 311 } 312 } 313 }