Save This Page
Home » openjdk-7 » com.sun.script » javascript » [javadoc | source]
    1   /*
    2    * Copyright (c) 2005, 2006, 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 com.sun.script.javascript;
   27   
   28   import java.lang.reflect;
   29   import static sun.security.util.SecurityConstants.*;
   30   import sun.org.mozilla.javascript.internal;
   31   
   32   /**
   33    * This wrap factory is used for security reasons. JSR 223 script
   34    * engine interface and JavaScript engine classes are run as bootstrap
   35    * classes. For example, java.lang.Class.forName method (when called without
   36    * class loader) uses caller's class loader. This may be exploited by script
   37    * authors to access classes otherwise not accessible. For example,
   38    * classes in sun.* namespace are normally not accessible to untrusted
   39    * code and hence should not be accessible to JavaScript run from
   40    * untrusted code.
   41    *
   42    * @author A. Sundararajan
   43    * @since 1.6
   44    */
   45   final class RhinoWrapFactory extends WrapFactory {
   46       private RhinoWrapFactory() {}
   47       private static RhinoWrapFactory theInstance;
   48   
   49       static synchronized WrapFactory getInstance() {
   50           if (theInstance == null) {
   51               theInstance = new RhinoWrapFactory();
   52           }
   53           return theInstance;
   54       }
   55   
   56       // We use instance of this class to wrap security sensitive
   57       // Java object. Please refer below.
   58       private static class RhinoJavaObject extends NativeJavaObject {
   59           RhinoJavaObject(Scriptable scope, Object obj, Class type) {
   60               // we pass 'null' to object. NativeJavaObject uses
   61               // passed 'type' to reflect fields and methods when
   62               // object is null.
   63               super(scope, null, type);
   64   
   65               // Now, we set actual object. 'javaObject' is protected
   66               // field of NativeJavaObject.
   67               javaObject = obj;
   68           }
   69       }
   70   
   71       public Scriptable wrapAsJavaObject(Context cx, Scriptable scope,
   72               Object javaObject, Class staticType) {
   73           SecurityManager sm = System.getSecurityManager();
   74           ClassShutter classShutter = RhinoClassShutter.getInstance();
   75           if (javaObject instanceof ClassLoader) {
   76               // Check with Security Manager whether we can expose a
   77               // ClassLoader...
   78               if (sm != null) {
   79                   sm.checkPermission(GET_CLASSLOADER_PERMISSION);
   80               }
   81               // if we fall through here, check permission succeeded.
   82               return super.wrapAsJavaObject(cx, scope, javaObject, staticType);
   83           } else {
   84               String name = null;
   85               if (javaObject instanceof Class) {
   86                   name = ((Class)javaObject).getName();
   87               } else if (javaObject instanceof Member) {
   88                   Member member = (Member) javaObject;
   89                   // Check member access. Don't allow reflective access to
   90                   // non-public members. Note that we can't call checkMemberAccess
   91                   // because that expects exact stack depth!
   92                   if (sm != null && !Modifier.isPublic(member.getModifiers())) {
   93                       return null;
   94                   }
   95                   name = member.getDeclaringClass().getName();
   96               }
   97               // Now, make sure that no ClassShutter prevented Class or Member
   98               // of it is accessed reflectively. Note that ClassShutter may
   99               // prevent access to a class, even though SecurityManager permit.
  100               if (name != null) {
  101                   if (!classShutter.visibleToScripts(name)) {
  102                       return null;
  103                   } else {
  104                       return super.wrapAsJavaObject(cx, scope, javaObject, staticType);
  105                   }
  106               }
  107           }
  108   
  109           // we have got some non-reflective object.
  110           Class dynamicType = javaObject.getClass();
  111           String name = dynamicType.getName();
  112           if (!classShutter.visibleToScripts(name)) {
  113               // Object of some sensitive class (such as sun.net.www.*
  114               // objects returned from public method of java.net.URL class.
  115               // We expose this object as though it is an object of some
  116               // super class that is safe for access.
  117   
  118               Class type = null;
  119   
  120               // Whenever a Java Object is wrapped, we are passed with a
  121               // staticType which is the type found from environment. For
  122               // example, method return type known from signature. The dynamic
  123               // type would be the actual Class of the actual returned object.
  124               // If the staticType is an interface, we just use that type.
  125               if (staticType != null && staticType.isInterface()) {
  126                   type = staticType;
  127               } else {
  128                   // dynamicType is always a class type and never an interface.
  129                   // find an accessible super class of the dynamic type.
  130                   while (dynamicType != null) {
  131                       dynamicType = dynamicType.getSuperclass();
  132                       name = dynamicType.getName();
  133                       if (classShutter.visibleToScripts(name)) {
  134                            type = dynamicType; break;
  135                       }
  136                   }
  137                   // atleast java.lang.Object has to be accessible. So, when
  138                   // we reach here, type variable should not be null.
  139                   assert type != null:
  140                          "even java.lang.Object is not accessible?";
  141               }
  142               // create custom wrapper with the 'safe' type.
  143               return new RhinoJavaObject(scope, javaObject, type);
  144           } else {
  145               return super.wrapAsJavaObject(cx, scope, javaObject, staticType);
  146           }
  147       }
  148   }

Save This Page
Home » openjdk-7 » com.sun.script » javascript » [javadoc | source]