Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(67)

Side by Side Diff: content/browser/renderer_host/java/java_bound_object.cc

Issue 213693005: [Android] Block access to java.lang.Object.getClass in injected Java objects (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/java/java_bound_object.h" 5 #include "content/browser/renderer_host/java/java_bound_object.h"
6 6
7 #include "base/android/jni_android.h" 7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h" 8 #include "base/android/jni_string.h"
9 #include "base/memory/singleton.h" 9 #include "base/memory/singleton.h"
10 #include "base/numerics/safe_conversions.h" 10 #include "base/numerics/safe_conversions.h"
(...skipping 21 matching lines...) Expand all
32 // Note that in some cases, we differ from from the spec in order to maintain 32 // Note that in some cases, we differ from from the spec in order to maintain
33 // existing behavior. These areas are marked LIVECONNECT_COMPLIANCE. We may 33 // existing behavior. These areas are marked LIVECONNECT_COMPLIANCE. We may
34 // revisit this decision in the future. 34 // revisit this decision in the future.
35 35
36 namespace content { 36 namespace content {
37 namespace { 37 namespace {
38 38
39 const char kJavaLangClass[] = "java/lang/Class"; 39 const char kJavaLangClass[] = "java/lang/Class";
40 const char kJavaLangObject[] = "java/lang/Object"; 40 const char kJavaLangObject[] = "java/lang/Object";
41 const char kJavaLangReflectMethod[] = "java/lang/reflect/Method"; 41 const char kJavaLangReflectMethod[] = "java/lang/reflect/Method";
42 const char kJavaLangSecurityExceptionClass[] = "java/lang/SecurityException";
42 const char kGetClass[] = "getClass"; 43 const char kGetClass[] = "getClass";
43 const char kGetMethods[] = "getMethods"; 44 const char kGetMethods[] = "getMethods";
44 const char kIsAnnotationPresent[] = "isAnnotationPresent"; 45 const char kIsAnnotationPresent[] = "isAnnotationPresent";
45 const char kReturningJavaLangClass[] = "()Ljava/lang/Class;"; 46 const char kReturningJavaLangClass[] = "()Ljava/lang/Class;";
46 const char kReturningJavaLangReflectMethodArray[] = 47 const char kReturningJavaLangReflectMethodArray[] =
47 "()[Ljava/lang/reflect/Method;"; 48 "()[Ljava/lang/reflect/Method;";
48 const char kTakesJavaLangClassReturningBoolean[] = "(Ljava/lang/Class;)Z"; 49 const char kTakesJavaLangClassReturningBoolean[] = "(Ljava/lang/Class;)Z";
50 // This is an exception message, so no need to localize.
51 const char kAccessToObjectGetClassIsBlocked[] =
52 "Access to java.lang.Object.getClass is blocked";
palmer 2014/04/03 21:53:58 Nit: As you think of more bad classes/methods to b
mnaganov (inactive) 2014/04/04 10:16:49 As I have explained in the bug, so far 'getClass'
49 53
50 // Our special NPObject type. We extend an NPObject with a pointer to a 54 // Our special NPObject type. We extend an NPObject with a pointer to a
51 // JavaBoundObject. We also add static methods for each of the NPObject 55 // JavaBoundObject. We also add static methods for each of the NPObject
52 // callbacks, which are registered by our NPClass. These methods simply 56 // callbacks, which are registered by our NPClass. These methods simply
53 // delegate to the private implementation methods of JavaBoundObject. 57 // delegate to the private implementation methods of JavaBoundObject.
54 struct JavaNPObject : public NPObject { 58 struct JavaNPObject : public NPObject {
55 JavaBoundObject* bound_object; 59 JavaBoundObject* bound_object;
56 60
57 static const NPClass kNPClass; 61 static const NPClass kNPClass;
58 62
(...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 } 817 }
814 818
815 JavaBoundObject::JavaBoundObject( 819 JavaBoundObject::JavaBoundObject(
816 const JavaRef<jobject>& object, 820 const JavaRef<jobject>& object,
817 const JavaRef<jclass>& safe_annotation_clazz, 821 const JavaRef<jclass>& safe_annotation_clazz,
818 const base::WeakPtr<JavaBridgeDispatcherHostManager>& manager, 822 const base::WeakPtr<JavaBridgeDispatcherHostManager>& manager,
819 bool can_enumerate_methods) 823 bool can_enumerate_methods)
820 : java_object_(AttachCurrentThread(), object.obj()), 824 : java_object_(AttachCurrentThread(), object.obj()),
821 manager_(manager), 825 manager_(manager),
822 are_methods_set_up_(false), 826 are_methods_set_up_(false),
827 object_get_class_method_id_(NULL),
823 can_enumerate_methods_(can_enumerate_methods), 828 can_enumerate_methods_(can_enumerate_methods),
824 safe_annotation_clazz_(safe_annotation_clazz) { 829 safe_annotation_clazz_(safe_annotation_clazz) {
825 BrowserThread::PostTask( 830 BrowserThread::PostTask(
826 BrowserThread::UI, FROM_HERE, 831 BrowserThread::UI, FROM_HERE,
827 base::Bind(&JavaBridgeDispatcherHostManager::JavaBoundObjectCreated, 832 base::Bind(&JavaBridgeDispatcherHostManager::JavaBoundObjectCreated,
828 manager_, 833 manager_,
829 base::android::ScopedJavaGlobalRef<jobject>(object))); 834 base::android::ScopedJavaGlobalRef<jobject>(object)));
830 // Other than informing the JavaBridgeDispatcherHostManager that a java bound 835 // Other than informing the JavaBridgeDispatcherHostManager that a java bound
831 // object has been created (above), we don't do anything else with our Java 836 // object has been created (above), we don't do anything else with our Java
832 // object when first created. We do it all lazily when a method is first 837 // object when first created. We do it all lazily when a method is first
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
889 } 894 }
890 895
891 // Coerce 896 // Coerce
892 std::vector<jvalue> parameters(arg_count); 897 std::vector<jvalue> parameters(arg_count);
893 for (size_t i = 0; i < arg_count; ++i) { 898 for (size_t i = 0; i < arg_count; ++i) {
894 parameters[i] = CoerceJavaScriptValueToJavaValue(args[i], 899 parameters[i] = CoerceJavaScriptValueToJavaValue(args[i],
895 method->parameter_type(i), 900 method->parameter_type(i),
896 true); 901 true);
897 } 902 }
898 903
899 ScopedJavaLocalRef<jobject> obj = java_object_.get(AttachCurrentThread()); 904 JNIEnv* env = AttachCurrentThread();
905 ScopedJavaLocalRef<jobject> obj = java_object_.get(env);
906
907 // Block access to java.lang.Object.getClass.
908 // As it is declared to be final, it is sufficient to compare methodIDs.
909 if (method->id() == object_get_class_method_id_) {
910 BrowserThread::PostTask(
911 BrowserThread::UI, FROM_HERE,
912 base::Bind(&JavaBoundObject::ThrowSecurityException,
913 kAccessToObjectGetClassIsBlocked));
914 return false;
915 }
900 916
901 bool ok = false; 917 bool ok = false;
902 if (!obj.is_null()) { 918 if (!obj.is_null()) {
903 // Call 919 // Call
904 ok = CallJNIMethod(obj.obj(), method->return_type(), 920 ok = CallJNIMethod(obj.obj(), method->return_type(),
905 method->id(), &parameters[0], result, 921 method->id(), &parameters[0], result,
906 safe_annotation_clazz_, 922 safe_annotation_clazz_,
907 manager_, 923 manager_,
908 can_enumerate_methods_); 924 can_enumerate_methods_);
909 } 925 }
910 926
911 // Now that we're done with the jvalue, release any local references created 927 // Now that we're done with the jvalue, release any local references created
912 // by CoerceJavaScriptValueToJavaValue(). 928 // by CoerceJavaScriptValueToJavaValue().
913 JNIEnv* env = AttachCurrentThread();
914 for (size_t i = 0; i < arg_count; ++i) { 929 for (size_t i = 0; i < arg_count; ++i) {
915 ReleaseJavaValueIfRequired(env, &parameters[i], method->parameter_type(i)); 930 ReleaseJavaValueIfRequired(env, &parameters[i], method->parameter_type(i));
916 } 931 }
917 932
918 return ok; 933 return ok;
919 } 934 }
920 935
921 void JavaBoundObject::EnsureMethodsAreSetUp() const { 936 void JavaBoundObject::EnsureMethodsAreSetUp() const {
922 if (are_methods_set_up_) 937 if (are_methods_set_up_)
923 return; 938 return;
924 are_methods_set_up_ = true; 939 are_methods_set_up_ = true;
925 940
926 JNIEnv* env = AttachCurrentThread(); 941 JNIEnv* env = AttachCurrentThread();
942
943 object_get_class_method_id_ = GetMethodIDFromClassName(
944 env,
945 kJavaLangObject,
946 kGetClass,
947 kReturningJavaLangClass);
948
927 ScopedJavaLocalRef<jobject> obj = java_object_.get(env); 949 ScopedJavaLocalRef<jobject> obj = java_object_.get(env);
928 950
929 if (obj.is_null()) { 951 if (obj.is_null()) {
930 return; 952 return;
931 } 953 }
932 954
933 ScopedJavaLocalRef<jclass> clazz(env, static_cast<jclass>( 955 ScopedJavaLocalRef<jclass> clazz(env, static_cast<jclass>(
934 env->CallObjectMethod(obj.obj(), GetMethodIDFromClassName( 956 env->CallObjectMethod(obj.obj(), object_get_class_method_id_)));
935 env,
936 kJavaLangObject,
937 kGetClass,
938 kReturningJavaLangClass))));
939 957
940 ScopedJavaLocalRef<jobjectArray> methods(env, static_cast<jobjectArray>( 958 ScopedJavaLocalRef<jobjectArray> methods(env, static_cast<jobjectArray>(
941 env->CallObjectMethod(clazz.obj(), GetMethodIDFromClassName( 959 env->CallObjectMethod(clazz.obj(), GetMethodIDFromClassName(
942 env, 960 env,
943 kJavaLangClass, 961 kJavaLangClass,
944 kGetMethods, 962 kGetMethods,
945 kReturningJavaLangReflectMethodArray)))); 963 kReturningJavaLangReflectMethodArray))));
946 964
947 size_t num_methods = env->GetArrayLength(methods.obj()); 965 size_t num_methods = env->GetArrayLength(methods.obj());
948 // Java objects always have public methods. 966 // Java objects always have public methods.
(...skipping 15 matching lines...) Expand all
964 982
965 if (!safe) 983 if (!safe)
966 continue; 984 continue;
967 } 985 }
968 986
969 JavaMethod* method = new JavaMethod(java_method); 987 JavaMethod* method = new JavaMethod(java_method);
970 methods_.insert(std::make_pair(method->name(), method)); 988 methods_.insert(std::make_pair(method->name(), method));
971 } 989 }
972 } 990 }
973 991
992 // static
993 void JavaBoundObject::ThrowSecurityException(const char* message) {
994 DCHECK_CURRENTLY_ON(BrowserThread::UI);
995 JNIEnv* env = AttachCurrentThread();
996 base::android::ScopedJavaLocalRef<jclass> clazz(
997 env, env->FindClass(kJavaLangSecurityExceptionClass));
998 env->ThrowNew(clazz.obj(), message);
999 }
1000
974 } // namespace content 1001 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698