Changeset 52080 in webkit
- Timestamp:
- Dec 13, 2009 9:01:01 PM (14 years ago)
- Location:
- trunk
- Files:
-
- 6 added
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r52079 r52080 1 2009-12-13 Charles Reis <creis@chromium.org> 2 3 Reviewed by Adam Barth. 4 5 Refactor some security code out of V8 bindings 6 https://bugs.webkit.org/show_bug.cgi?id=32326 7 8 No new tests. There should be no functionality changes in this patch, 9 since it is only refactoring code. 10 11 * WebCore.gyp/WebCore.gyp: 12 * WebCore.gypi: 13 * bindings/BindingSecurity.h: Added. 14 (WebCore::BindingSecurity::BindingSecurity): 15 (WebCore::::canAccessWindow): 16 (WebCore::::canAccessFrame): 17 (WebCore::::checkNodeSecurity): 18 * bindings/BindingSecurityBase.cpp: Added. 19 (WebCore::BindingSecurityBase::getDOMWindow): 20 (WebCore::BindingSecurityBase::getFrame): 21 (WebCore::BindingSecurityBase::canAccessWindow): 22 * bindings/BindingSecurityBase.h: Added. 23 * bindings/GenericBinding.h: Added. 24 (WebCore::): 25 * bindings/scripts/CodeGeneratorV8.pm: 26 * bindings/v8/ScriptController.cpp: 27 (WebCore::ScriptController::isSafeScript): 28 * bindings/v8/V8Binding.h: 29 * bindings/v8/V8BindingState.cpp: Added. 30 (WebCore::::Only): 31 (WebCore::::getActiveWindow): 32 (WebCore::::immediatelyReportUnsafeAccessTo): 33 * bindings/v8/V8BindingState.h: Added. 34 (WebCore::): 35 * bindings/v8/V8Proxy.cpp: 36 (WebCore::V8Proxy::reportUnsafeAccessTo): 37 (WebCore::reportUnsafeJavaScriptAccess): 38 * bindings/v8/V8Proxy.h: 39 (WebCore::V8Proxy::): 40 * bindings/v8/custom/V8CustomBinding.cpp: 41 (WebCore::allowSettingFrameSrcToJavascriptUrl): 42 (WebCore::INDEXED_ACCESS_CHECK): 43 (WebCore::NAMED_ACCESS_CHECK): 44 * bindings/v8/custom/V8DOMWindowCustom.cpp: 45 (WebCore::V8Custom::WindowSetTimeoutImpl): 46 (WebCore::ACCESSOR_GETTER): 47 (WebCore::ACCESSOR_SETTER): 48 (WebCore::CALLBACK_FUNC_DECL): 49 (WebCore::V8Custom::ClearTimeoutImpl): 50 (WebCore::NAMED_ACCESS_CHECK): 51 (WebCore::INDEXED_ACCESS_CHECK): 52 * bindings/v8/custom/V8LocationCustom.cpp: 53 (WebCore::ACCESSOR_GETTER): 54 (WebCore::CALLBACK_FUNC_DECL): 55 (WebCore::INDEXED_ACCESS_CHECK): 56 (WebCore::NAMED_ACCESS_CHECK): 57 1 58 2009-11-30 Holger Hans Peter Freyther <zecke@selfish.org> 2 59 -
trunk/WebCore/WebCore.gyp/WebCore.gyp
r51901 r52080 107 107 '../accessibility', 108 108 '../accessibility/chromium', 109 '../bindings', 109 110 '../bindings/v8', 110 111 '../bindings/v8/custom', -
trunk/WebCore/WebCore.gypi
r51993 r52080 435 435 'accessibility/win/AccessibilityObjectWrapperWin.h', 436 436 'accessibility/wx/AccessibilityObjectWx.cpp', 437 'bindings/BindingSecurity.h', 438 'bindings/BindingSecurityBase.cpp', 439 'bindings/BindingSecurityBase.h', 440 'bindings/GenericBinding.h', 437 441 'bindings/js/CachedScriptSourceProvider.h', 438 442 'bindings/js/DOMObjectWithSVGContext.h', … … 798 802 'bindings/v8/V8Binding.cpp', 799 803 'bindings/v8/V8Binding.h', 804 'bindings/v8/V8BindingState.cpp', 805 'bindings/v8/V8BindingState.h', 800 806 'bindings/v8/V8Collection.cpp', 801 807 'bindings/v8/V8Collection.h', -
trunk/WebCore/bindings/scripts/CodeGeneratorV8.pm
r51901 r52080 402 402 403 403 push(@implContentDecls, <<END); 404 if (!V8 Proxy::canAccessFrame(imp->frame(), false)) {404 if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), false)) { 405 405 static v8::Persistent<v8::FunctionTemplate> shared_template = 406 406 v8::Persistent<v8::FunctionTemplate>::New($newTemplateString); … … 549 549 # Generate security checks if necessary 550 550 if ($attribute->signature->extendedAttributes->{"CheckNodeSecurity"}) { 551 push(@implContentDecls, " if (!V8 Proxy::checkNodeSecurity(imp->$attrName())) return v8::Handle<v8::Value>();\n\n");551 push(@implContentDecls, " if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->$attrName())) return v8::Handle<v8::Value>();\n\n"); 552 552 } elsif ($attribute->signature->extendedAttributes->{"CheckFrameSecurity"}) { 553 push(@implContentDecls, " if (!V8 Proxy::checkNodeSecurity(imp->contentDocument())) return v8::Handle<v8::Value>();\n\n");553 push(@implContentDecls, " if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->contentDocument())) return v8::Handle<v8::Value>();\n\n"); 554 554 } 555 555 … … 899 899 # We have not find real use cases yet. 900 900 push(@implContentDecls, 901 " if (!V8 Proxy::canAccessFrame(imp->frame(), true)) {\n".901 " if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true)) {\n". 902 902 " return v8::Handle<v8::Value>();\n" . 903 903 " }\n"); … … 931 931 if ($function->signature->extendedAttributes->{"SVGCheckSecurityDocument"}) { 932 932 push(@implContentDecls, 933 " if (!V8 Proxy::checkNodeSecurity(imp->getSVGDocument(ec)))\n" .933 " if (!V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), imp->getSVGDocument(ec)))\n" . 934 934 " return v8::Handle<v8::Value>();\n"); 935 935 } … … 1146 1146 "#include \"config.h\"\n" . 1147 1147 "#include \"V8Proxy.h\"\n" . 1148 "#include \"V8Binding.h\"\n\n" . 1148 "#include \"V8Binding.h\"\n" . 1149 "#include \"V8BindingState.h\"\n\n" . 1149 1150 "#undef LOG\n\n"); 1150 1151 -
trunk/WebCore/bindings/v8/ScriptController.cpp
r52043 r52080 51 51 #include "Settings.h" 52 52 #include "V8Binding.h" 53 #include "V8BindingState.h" 53 54 #include "V8NPObject.h" 54 55 #include "V8Proxy.h" … … 85 86 bool ScriptController::isSafeScript(Frame* target) 86 87 { 87 return V8 Proxy::canAccessFrame(target, true);88 return V8BindingSecurity::canAccessFrame(V8BindingState::Only(), target, true); 88 89 } 89 90 -
trunk/WebCore/bindings/v8/V8Binding.h
r51125 r52080 33 33 34 34 #include "AtomicString.h" 35 #include "BindingSecurity.h" 35 36 #include "MathExtras.h" 36 37 #include "PlatformString.h" … … 44 45 class EventListener; 45 46 class EventTarget; 47 48 // Instantiate binding template classes for V8. 49 class V8Binding {}; 50 typedef BindingSecurity<V8Binding> V8BindingSecurity; 46 51 47 52 // A helper function extract native object pointer from a DOM wrapper -
trunk/WebCore/bindings/v8/V8Proxy.cpp
r51960 r52080 44 44 #include "StorageNamespace.h" 45 45 #include "V8Binding.h" 46 #include "V8BindingState.h" 46 47 #include "V8Collection.h" 47 48 #include "V8ConsoleMessage.h" … … 164 165 }; 165 166 166 static voidreportUnsafeAccessTo(Frame* target, DelayReporting delay)167 void V8Proxy::reportUnsafeAccessTo(Frame* target, DelayReporting delay) 167 168 { 168 169 ASSERT(target); … … 208 209 Frame* target = V8Custom::GetTargetFrame(host, data); 209 210 if (target) 210 reportUnsafeAccessTo(target,ReportLater);211 V8Proxy::reportUnsafeAccessTo(target, V8Proxy::ReportLater); 211 212 } 212 213 … … 856 857 v8::HandleScope scope; 857 858 setSecurityToken(); 858 }859 860 // Same origin policy implementation:861 //862 // Same origin policy prevents JS code from domain A access JS & DOM objects863 // in a different domain B. There are exceptions and several objects are864 // accessible by cross-domain code. For example, the window.frames object is865 // accessible by code from a different domain, but window.document is not.866 //867 // The binding code sets security check callbacks on a function template,868 // and accessing instances of the template calls the callback function.869 // The callback function checks same origin policy.870 //871 // Callback functions are expensive. V8 uses a security token string to do872 // fast access checks for the common case where source and target are in the873 // same domain. A security token is a string object that represents874 // the protocol/url/port of a domain.875 //876 // There are special cases where a security token matching is not enough.877 // For example, JavaScript can set its domain to a super domain by calling878 // document.setDomain(...). In these cases, the binding code can reset879 // a context's security token to its global object so that the fast access880 // check will always fail.881 882 // Check if the current execution context can access a target frame.883 // First it checks same domain policy using the lexical context884 //885 // This is equivalent to KJS::Window::allowsAccessFrom(ExecState*, String&).886 bool V8Proxy::canAccessPrivate(DOMWindow* targetWindow)887 {888 ASSERT(targetWindow);889 890 String message;891 892 v8::Local<v8::Context> activeContext = v8::Context::GetCalling();893 if (activeContext.IsEmpty()) {894 // There is a single activation record on the stack, so that must895 // be the activeContext.896 activeContext = v8::Context::GetCurrent();897 }898 DOMWindow* activeWindow = retrieveWindow(activeContext);899 if (activeWindow == targetWindow)900 return true;901 902 if (!activeWindow)903 return false;904 905 const SecurityOrigin* activeSecurityOrigin = activeWindow->securityOrigin();906 const SecurityOrigin* targetSecurityOrigin = targetWindow->securityOrigin();907 908 // We have seen crashes were the security origin of the target has not been909 // initialized. Defend against that.910 if (!targetSecurityOrigin)911 return false;912 913 if (activeSecurityOrigin->canAccess(targetSecurityOrigin))914 return true;915 916 // Allow access to a "about:blank" page if the dynamic context is a917 // detached context of the same frame as the blank page.918 if (targetSecurityOrigin->isEmpty() && activeWindow->frame() == targetWindow->frame())919 return true;920 921 return false;922 }923 924 bool V8Proxy::canAccessFrame(Frame* target, bool reportError)925 {926 // The subject is detached from a frame, deny accesses.927 if (!target)928 return false;929 930 if (!canAccessPrivate(target->domWindow())) {931 if (reportError)932 reportUnsafeAccessTo(target, ReportNow);933 return false;934 }935 return true;936 }937 938 bool V8Proxy::checkNodeSecurity(Node* node)939 {940 if (!node)941 return false;942 943 Frame* target = node->document()->frame();944 945 if (!target)946 return false;947 948 return canAccessFrame(target, true);949 859 } 950 860 -
trunk/WebCore/bindings/v8/V8Proxy.h
r51960 r52080 140 140 }; 141 141 142 // When to report errors. 143 enum DelayReporting { 144 ReportLater, 145 ReportNow 146 }; 147 142 148 explicit V8Proxy(Frame*); 143 149 … … 302 308 static bool handleOutOfMemory(); 303 309 304 // Check if the active execution context can access the target frame.305 static bool canAccessFrame(Frame*, bool reportError);306 307 // Check if it is safe to access the given node from the308 // current security context.309 static bool checkNodeSecurity(Node*);310 311 310 static v8::Handle<v8::Value> checkNewLegal(const v8::Arguments&); 312 311 … … 366 365 void initContextIfNeeded(); 367 366 void updateDocumentWrapper(v8::Handle<v8::Value> wrapper); 367 368 // Report an unsafe attempt to access the given frame on the console. 369 static void reportUnsafeAccessTo(Frame* target, DelayReporting delay); 368 370 369 371 private: … … 389 391 // Returns false when we're out of memory in V8. 390 392 bool setInjectedScriptContextDebugId(v8::Handle<v8::Context> targetContext); 391 392 static bool canAccessPrivate(DOMWindow*);393 393 394 394 static const char* rangeExceptionName(int exceptionCode); -
trunk/WebCore/bindings/v8/custom/V8CustomBinding.cpp
r45947 r52080 40 40 #include "HTMLFrameElementBase.h" 41 41 #include "Location.h" 42 #include "V8Binding.h" 43 #include "V8BindingState.h" 42 44 #include "V8Proxy.h" 43 45 … … 52 54 if (protocolIs(deprecatedParseURL(value), "javascript")) { 53 55 Node* contentDoc = frame->contentDocument(); 54 if (contentDoc && !V8 Proxy::checkNodeSecurity(contentDoc))56 if (contentDoc && !V8BindingSecurity::checkNodeSecurity(V8BindingState::Only(), contentDoc)) 55 57 return false; 56 58 } … … 98 100 // Only allow same origin access. 99 101 History* history = V8DOMWrapper::convertToNativeObject<History>(V8ClassIndex::HISTORY, host); 100 return V8 Proxy::canAccessFrame(history->frame(), false);102 return V8BindingSecurity::canAccessFrame(V8BindingState::Only(), history->frame(), false); 101 103 } 102 104 … … 106 108 // Only allow same origin access. 107 109 History* history = V8DOMWrapper::convertToNativeObject<History>(V8ClassIndex::HISTORY, host); 108 return V8 Proxy::canAccessFrame(history->frame(), false);110 return V8BindingSecurity::canAccessFrame(V8BindingState::Only(), history->frame(), false); 109 111 } 110 112 -
trunk/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
r51580 r52080 33 33 34 34 #include "V8Binding.h" 35 #include "V8BindingState.h" 35 36 #include "V8CustomBinding.h" 36 37 #include "V8CustomEventListener.h" … … 102 103 DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder()); 103 104 104 if (!V8 Proxy::canAccessFrame(imp->frame(), true))105 if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true)) 105 106 return v8::Undefined(); 106 107 … … 172 173 173 174 Frame* frame = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder)->frame(); 174 if (!V8 Proxy::canAccessFrame(frame, true))175 if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), frame, true)) 175 176 return v8::Undefined(); 176 177 … … 193 194 194 195 Frame* frame = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder)->frame(); 195 if (!V8 Proxy::canAccessFrame(frame, true))196 if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), frame, true)) 196 197 return; 197 198 … … 221 222 DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, info.Holder()); 222 223 223 if (!V8 Proxy::canAccessFrame(imp->frame(), true))224 if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true)) 224 225 return; 225 226 … … 344 345 DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder()); 345 346 346 if (!V8 Proxy::canAccessFrame(imp->frame(), true))347 if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true)) 347 348 return v8::Undefined(); 348 349 … … 377 378 DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder()); 378 379 379 if (!V8 Proxy::canAccessFrame(imp->frame(), true))380 if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true)) 380 381 return v8::Undefined(); 381 382 … … 442 443 DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder()); 443 444 444 if (!V8 Proxy::canAccessFrame(imp->frame(), true))445 if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true)) 445 446 return v8::Undefined(); 446 447 … … 461 462 DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder()); 462 463 463 if (!V8 Proxy::canAccessFrame(imp->frame(), true))464 if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true)) 464 465 return v8::Undefined(); 465 466 … … 622 623 Frame* frame = window->frame(); 623 624 624 if (!V8 Proxy::canAccessFrame(frame, true))625 if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), frame, true)) 625 626 return v8::Undefined(); 626 627 … … 710 711 Frame* frame = parent->frame(); 711 712 712 if (!V8 Proxy::canAccessFrame(frame, true))713 if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), frame, true)) 713 714 return v8::Undefined(); 714 715 … … 926 927 v8::Handle<v8::Object> holder = args.Holder(); 927 928 DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder); 928 if (!V8 Proxy::canAccessFrame(imp->frame(), true))929 if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true)) 929 930 return; 930 931 ScriptExecutionContext* context = static_cast<ScriptExecutionContext*>(imp->document()); … … 972 973 } 973 974 974 return V8 Proxy::canAccessFrame(target, false);975 return V8BindingSecurity::canAccessFrame(V8BindingState::Only(), target, false); 975 976 } 976 977 … … 994 995 return true; 995 996 996 return V8 Proxy::canAccessFrame(target, false);997 return V8BindingSecurity::canAccessFrame(V8BindingState::Only(), target, false); 997 998 } 998 999 -
trunk/WebCore/bindings/v8/custom/V8LocationCustom.cpp
r48994 r52080 33 33 34 34 #include "V8Binding.h" 35 #include "V8BindingState.h" 35 36 #include "V8CustomBinding.h" 36 37 #include "V8CustomEventListener.h" … … 218 219 } 219 220 Location* imp = V8DOMWrapper::convertToNativeObject<Location>(V8ClassIndex::LOCATION, holder); 220 if (!V8 Proxy::canAccessFrame(imp->frame(), false)) {221 if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), false)) { 221 222 static v8::Persistent<v8::FunctionTemplate> sharedTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(v8LocationReloadCallback, v8::Handle<v8::Value>(), v8::Signature::New(V8Location::GetRawTemplate()))); 222 223 return sharedTemplate->GetFunction(); 223 } else224 224 } 225 return privateTemplate->GetFunction(); 225 226 } 226 227 … … 236 237 } 237 238 Location* imp = V8DOMWrapper::convertToNativeObject<Location>(V8ClassIndex::LOCATION, holder); 238 if (!V8 Proxy::canAccessFrame(imp->frame(), false)) {239 if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), false)) { 239 240 static v8::Persistent<v8::FunctionTemplate> sharedTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(v8LocationReplaceCallback, v8::Handle<v8::Value>(), v8::Signature::New(V8Location::GetRawTemplate()))); 240 241 return sharedTemplate->GetFunction(); 241 } else242 242 } 243 return privateTemplate->GetFunction(); 243 244 } 244 245 … … 255 256 } 256 257 Location* imp = V8DOMWrapper::convertToNativeObject<Location>(V8ClassIndex::LOCATION, holder); 257 if (!V8 Proxy::canAccessFrame(imp->frame(), false)) {258 if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), false)) { 258 259 static v8::Persistent<v8::FunctionTemplate> sharedTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(v8LocationAssignCallback, v8::Handle<v8::Value>(), v8::Signature::New(V8Location::GetRawTemplate()))); 259 260 return sharedTemplate->GetFunction(); 260 } else261 261 } 262 return privateTemplate->GetFunction(); 262 263 } 263 264 … … 336 337 v8::Handle<v8::Object> holder = args.Holder(); 337 338 Location* imp = V8DOMWrapper::convertToNativeObject<Location>(V8ClassIndex::LOCATION, holder); 338 if (!V8 Proxy::canAccessFrame(imp->frame(), true))339 if (!V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), true)) 339 340 return v8::Undefined(); 340 341 String result = imp->href(); … … 347 348 // Only allow same origin access 348 349 Location* imp = V8DOMWrapper::convertToNativeObject<Location>(V8ClassIndex::LOCATION, host); 349 return V8 Proxy::canAccessFrame(imp->frame(), false);350 return V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), false); 350 351 } 351 352 … … 355 356 // Only allow same origin access 356 357 Location* imp = V8DOMWrapper::convertToNativeObject<Location>(V8ClassIndex::LOCATION, host); 357 return V8 Proxy::canAccessFrame(imp->frame(), false);358 return V8BindingSecurity::canAccessFrame(V8BindingState::Only(), imp->frame(), false); 358 359 } 359 360 -
trunk/WebKit/chromium/ChangeLog
r52027 r52080 1 2009-12-13 Charles Reis <creis@chromium.org> 2 3 Reviewed by Adam Barth. 4 5 Refactor some security code out of V8 bindings 6 https://bugs.webkit.org/show_bug.cgi?id=32326 7 8 * src/WebBindings.cpp: 9 (WebKit::getDragDataImpl): 10 1 11 2009-12-11 Nate Chapin <japhet@chromium.org> 2 12 -
trunk/WebKit/chromium/src/WebBindings.cpp
r50849 r52080 45 45 #include "NPV8Object.h" // for PrivateIdentifier 46 46 #include "Range.h" 47 #include "V8BindingState.h" 47 48 #include "V8DOMWrapper.h" 48 49 #include "V8Helpers.h" … … 237 238 V8Proxy* current = V8Proxy::retrieve(V8Proxy::retrieveFrameForCurrentContext()); 238 239 Frame* frame = V8Proxy::retrieveFrame(context); 239 if (!current || ! current->canAccessFrame(frame, false))240 if (!current || !V8BindingSecurity::canAccessFrame(V8BindingState::Only(), frame, false)) 240 241 return false; 241 242
Note: See TracChangeset
for help on using the changeset viewer.