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

Side by Side Diff: chrome/renderer/extensions/automation_internal_custom_bindings.cc

Issue 2828773002: Replace v8::Object::Set with CreateDataProperty for security reasons. (Closed)
Patch Set: Added comment Created 3 years, 7 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "chrome/renderer/extensions/automation_internal_custom_bindings.h" 5 #include "chrome/renderer/extensions/automation_internal_custom_bindings.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <memory> 10 #include <memory>
(...skipping 29 matching lines...) Expand all
40 v8::String::NewFromUtf8( 40 v8::String::NewFromUtf8(
41 isolate, 41 isolate,
42 "Invalid arguments to AutomationInternalCustomBindings function", 42 "Invalid arguments to AutomationInternalCustomBindings function",
43 v8::NewStringType::kNormal) 43 v8::NewStringType::kNormal)
44 .ToLocalChecked()); 44 .ToLocalChecked());
45 45
46 LOG(FATAL) << "Invalid arguments to AutomationInternalCustomBindings function" 46 LOG(FATAL) << "Invalid arguments to AutomationInternalCustomBindings function"
47 << automation_bindings->context()->GetStackTraceAsString(); 47 << automation_bindings->context()->GetStackTraceAsString();
48 } 48 }
49 49
50 v8::Local<v8::Value> CreateV8String(v8::Isolate* isolate, const char* str) { 50 v8::Local<v8::String> CreateV8String(v8::Isolate* isolate,
51 return v8::String::NewFromUtf8(isolate, str, v8::String::kNormalString, 51 const std::string& str) {
52 strlen(str)); 52 return v8::String::NewFromUtf8(isolate, str.c_str(),
Devlin 2017/04/24 20:01:42 nit: Let's use gin::StringToSymbol()
dmazzoni 2017/04/26 00:09:35 Done.
53 v8::String::kNormalString, str.length());
53 } 54 }
54 55
55 v8::Local<v8::Value> CreateV8String(v8::Isolate* isolate, 56 // Note: when building up an object to return from one of the
56 const std::string& str) { 57 // automation API bindings like a rect ({left: 0, top: 0, ...}) or
57 return v8::String::NewFromUtf8(isolate, str.c_str(), 58 // something like that, we should use this function instead of
58 v8::String::kNormalString, str.length()); 59 // v8::Object::Set, because a malicious extension author could use
60 // Object.defineProperty to override a setter and trigger all sorts of
61 // things to happen in the middle of one of our functions below.
Devlin 2017/04/24 20:01:42 I'd expand this to say that this is only safe if t
dmazzoni 2017/04/26 00:09:35 Done.
62 void SafeSetV8Property(v8::Isolate* isolate,
63 v8::Local<v8::Object> object,
64 const std::string& key,
Devlin 2017/04/24 20:01:42 s/const std::string&/base::StringPiece. Since the
dmazzoni 2017/04/26 00:09:35 Done.
65 v8::Local<v8::Value> value) {
66 v8::Maybe<bool> maybe = object->CreateDataProperty(
67 isolate->GetCurrentContext(), CreateV8String(isolate, key), value);
68 if (!maybe.IsJust() || !maybe.FromJust())
69 LOG(ERROR) << "Failed to set property with key " << key;
Devlin 2017/04/24 20:01:42 We should at least NOTREACHED() here. Maybe even
dmazzoni 2017/04/26 00:09:35 Done. Note that maybe.ToChecked() is the same as m
59 } 70 }
60 71
61 v8::Local<v8::Object> RectToV8Object(v8::Isolate* isolate, 72 v8::Local<v8::Object> RectToV8Object(v8::Isolate* isolate,
62 const gfx::Rect& rect) { 73 const gfx::Rect& rect) {
63 v8::Local<v8::Object> result(v8::Object::New(isolate)); 74 v8::Local<v8::Object> result(v8::Object::New(isolate));
64 result->Set(CreateV8String(isolate, "left"), 75 SafeSetV8Property(isolate, result, "left",
65 v8::Integer::New(isolate, rect.x())); 76 v8::Integer::New(isolate, rect.x()));
66 result->Set(CreateV8String(isolate, "top"), 77 SafeSetV8Property(isolate, result, "top",
67 v8::Integer::New(isolate, rect.y())); 78 v8::Integer::New(isolate, rect.y()));
68 result->Set(CreateV8String(isolate, "width"), 79 SafeSetV8Property(isolate, result, "width",
69 v8::Integer::New(isolate, rect.width())); 80 v8::Integer::New(isolate, rect.width()));
70 result->Set(CreateV8String(isolate, "height"), 81 SafeSetV8Property(isolate, result, "height",
71 v8::Integer::New(isolate, rect.height())); 82 v8::Integer::New(isolate, rect.height()));
72 return result; 83 return result;
73 } 84 }
74 85
75 // Compute the bounding box of a node, fixing nodes with empty bounds by 86 // Compute the bounding box of a node, fixing nodes with empty bounds by
76 // unioning the bounds of their children. 87 // unioning the bounds of their children.
77 static gfx::RectF ComputeLocalNodeBounds(TreeCache* cache, ui::AXNode* node) { 88 static gfx::RectF ComputeLocalNodeBounds(TreeCache* cache, ui::AXNode* node) {
78 gfx::RectF bounds = node->data().location; 89 gfx::RectF bounds = node->data().location;
79 if (bounds.width() > 0 && bounds.height() > 0) 90 if (bounds.width() > 0 && bounds.height() > 0)
80 return bounds; 91 return bounds;
81 92
(...skipping 856 matching lines...) Expand 10 before | Expand all | Expand 10 after
938 if (!cache) 949 if (!cache)
939 return; 950 return;
940 951
941 TreeCache* focused_tree_cache = nullptr; 952 TreeCache* focused_tree_cache = nullptr;
942 ui::AXNode* focused_node = nullptr; 953 ui::AXNode* focused_node = nullptr;
943 if (!GetFocusInternal(cache, &focused_tree_cache, &focused_node)) 954 if (!GetFocusInternal(cache, &focused_tree_cache, &focused_node))
944 return; 955 return;
945 956
946 v8::Isolate* isolate = GetIsolate(); 957 v8::Isolate* isolate = GetIsolate();
947 v8::Local<v8::Object> result(v8::Object::New(isolate)); 958 v8::Local<v8::Object> result(v8::Object::New(isolate));
948 result->Set(CreateV8String(isolate, "treeId"), 959 SafeSetV8Property(isolate, result, "treeId",
949 v8::Integer::New(isolate, focused_tree_cache->tree_id)); 960 v8::Integer::New(isolate, focused_tree_cache->tree_id));
950 result->Set(CreateV8String(isolate, "nodeId"), 961 SafeSetV8Property(isolate, result, "nodeId",
951 v8::Integer::New(isolate, focused_node->id())); 962 v8::Integer::New(isolate, focused_node->id()));
952 args.GetReturnValue().Set(result); 963 args.GetReturnValue().Set(result);
953 } 964 }
954 965
955 void AutomationInternalCustomBindings::GetHtmlAttributes( 966 void AutomationInternalCustomBindings::GetHtmlAttributes(
956 const v8::FunctionCallbackInfo<v8::Value>& args) { 967 const v8::FunctionCallbackInfo<v8::Value>& args) {
957 v8::Isolate* isolate = GetIsolate(); 968 v8::Isolate* isolate = GetIsolate();
958 if (args.Length() < 2 || !args[0]->IsNumber() || !args[1]->IsNumber()) 969 if (args.Length() < 2 || !args[0]->IsNumber() || !args[1]->IsNumber())
959 ThrowInvalidArgumentsException(this); 970 ThrowInvalidArgumentsException(this);
960 971
961 int tree_id = args[0]->Int32Value(); 972 int tree_id = args[0]->Int32Value();
962 int node_id = args[1]->Int32Value(); 973 int node_id = args[1]->Int32Value();
963 974
964 TreeCache* cache = GetTreeCacheFromTreeID(tree_id); 975 TreeCache* cache = GetTreeCacheFromTreeID(tree_id);
965 if (!cache) 976 if (!cache)
966 return; 977 return;
967 978
968 ui::AXNode* node = cache->tree.GetFromId(node_id); 979 ui::AXNode* node = cache->tree.GetFromId(node_id);
969 if (!node) 980 if (!node)
970 return; 981 return;
971 982
972 v8::Local<v8::Object> dst(v8::Object::New(isolate)); 983 v8::Local<v8::Object> dst(v8::Object::New(isolate));
973 base::StringPairs src = node->data().html_attributes; 984 base::StringPairs src = node->data().html_attributes;
974 for (size_t i = 0; i < src.size(); i++) { 985 for (size_t i = 0; i < src.size(); i++) {
975 std::string& key = src[i].first; 986 std::string& key = src[i].first;
976 std::string& value = src[i].second; 987 std::string& value = src[i].second;
977 dst->Set(CreateV8String(isolate, key), CreateV8String(isolate, value)); 988 SafeSetV8Property(isolate, dst, key, CreateV8String(isolate, value));
978 } 989 }
979 args.GetReturnValue().Set(dst); 990 args.GetReturnValue().Set(dst);
980 } 991 }
981 992
982 void AutomationInternalCustomBindings::GetState( 993 void AutomationInternalCustomBindings::GetState(
983 const v8::FunctionCallbackInfo<v8::Value>& args) { 994 const v8::FunctionCallbackInfo<v8::Value>& args) {
984 v8::Isolate* isolate = GetIsolate(); 995 v8::Isolate* isolate = GetIsolate();
985 if (args.Length() < 2 || !args[0]->IsNumber() || !args[1]->IsNumber()) 996 if (args.Length() < 2 || !args[0]->IsNumber() || !args[1]->IsNumber())
986 ThrowInvalidArgumentsException(this); 997 ThrowInvalidArgumentsException(this);
987 998
988 int tree_id = args[0]->Int32Value(); 999 int tree_id = args[0]->Int32Value();
989 int node_id = args[1]->Int32Value(); 1000 int node_id = args[1]->Int32Value();
990 1001
991 TreeCache* cache = GetTreeCacheFromTreeID(tree_id); 1002 TreeCache* cache = GetTreeCacheFromTreeID(tree_id);
992 if (!cache) 1003 if (!cache)
993 return; 1004 return;
994 1005
995 ui::AXNode* node = cache->tree.GetFromId(node_id); 1006 ui::AXNode* node = cache->tree.GetFromId(node_id);
996 if (!node) 1007 if (!node)
997 return; 1008 return;
998 1009
999 v8::Local<v8::Object> state(v8::Object::New(isolate)); 1010 v8::Local<v8::Object> state(v8::Object::New(isolate));
1000 uint32_t state_pos = 0, state_shifter = node->data().state; 1011 uint32_t state_pos = 0, state_shifter = node->data().state;
1001 while (state_shifter) { 1012 while (state_shifter) {
1002 if (state_shifter & 1) { 1013 if (state_shifter & 1) {
1003 std::string key = ToString(static_cast<ui::AXState>(state_pos)); 1014 std::string key = ToString(static_cast<ui::AXState>(state_pos));
1004 state->Set(CreateV8String(isolate, key), v8::Boolean::New(isolate, true)); 1015 SafeSetV8Property(isolate, state, key, v8::Boolean::New(isolate, true));
1005 } 1016 }
1006 state_shifter = state_shifter >> 1; 1017 state_shifter = state_shifter >> 1;
1007 state_pos++; 1018 state_pos++;
1008 } 1019 }
1009 1020
1010 TreeCache* top_cache = GetTreeCacheFromTreeID(0); 1021 TreeCache* top_cache = GetTreeCacheFromTreeID(0);
1011 if (!top_cache) 1022 if (!top_cache)
1012 top_cache = cache; 1023 top_cache = cache;
1013 TreeCache* focused_cache = nullptr; 1024 TreeCache* focused_cache = nullptr;
1014 ui::AXNode* focused_node = nullptr; 1025 ui::AXNode* focused_node = nullptr;
1015 if (GetFocusInternal(top_cache, &focused_cache, &focused_node)) { 1026 if (GetFocusInternal(top_cache, &focused_cache, &focused_node)) {
1016 if (focused_cache == cache && focused_node == node) { 1027 if (focused_cache == cache && focused_node == node) {
1017 state->Set(CreateV8String(isolate, "focused"), 1028 SafeSetV8Property(isolate, state, "focused",
1018 v8::Boolean::New(isolate, true)); 1029 v8::Boolean::New(isolate, true));
1019 } 1030 }
1020 } 1031 }
1021 if (cache->tree.data().focus_id == node->id()) { 1032 if (cache->tree.data().focus_id == node->id()) {
1022 state->Set(CreateV8String(isolate, "focused"), 1033 SafeSetV8Property(isolate, state, "focused",
1023 v8::Boolean::New(isolate, true)); 1034 v8::Boolean::New(isolate, true));
1024 } 1035 }
1025 1036
1026 args.GetReturnValue().Set(state); 1037 args.GetReturnValue().Set(state);
1027 } 1038 }
1028 1039
1029 void AutomationInternalCustomBindings::UpdateOverallTreeChangeObserverFilter() { 1040 void AutomationInternalCustomBindings::UpdateOverallTreeChangeObserverFilter() {
1030 tree_change_observer_overall_filter_ = 0; 1041 tree_change_observer_overall_filter_ = 0;
1031 for (const auto& observer : tree_change_observers_) 1042 for (const auto& observer : tree_change_observers_)
1032 tree_change_observer_overall_filter_ |= 1 << observer.filter; 1043 tree_change_observer_overall_filter_ |= 1 << observer.filter;
1033 } 1044 }
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
1413 for (auto id : ids) 1424 for (auto id : ids)
1414 nodes->AppendInteger(id); 1425 nodes->AppendInteger(id);
1415 args.Append(std::move(nodes)); 1426 args.Append(std::move(nodes));
1416 } 1427 }
1417 1428
1418 bindings_system_->DispatchEventInContext("automationInternal.onNodesRemoved", 1429 bindings_system_->DispatchEventInContext("automationInternal.onNodesRemoved",
1419 &args, nullptr, context()); 1430 &args, nullptr, context());
1420 } 1431 }
1421 1432
1422 } // namespace extensions 1433 } // namespace extensions
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698