Changeset 51757 in webkit
- Timestamp:
- Dec 7, 2009 5:06:18 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r51744 r51757 1 2009-12-06 Oliver Hunt <oliver@apple.com> 2 3 Reviewed by Maciej Stachowiak. 4 5 Object.getOwnPropertyDescriptor() allows cross-frame access 6 https://bugs.webkit.org/show_bug.cgi?id=32119 7 8 Add cross domain tests for getOwnPropertyDescriptor 9 10 * http/tests/security/cross-frame-access-getOwnPropertyDescriptor.html: Added. 11 * http/tests/security/resources/cross-frame-access.js: 12 (canGetDescriptor.set get catch): 13 (canGetDescriptor): 14 * http/tests/security/resources/cross-frame-iframe-for-get-test.html: 15 * http/tests/security/xss-DENIED-defineProperty.html: 16 1 17 2009-12-06 Kent Tamura <tkent@chromium.org> 2 18 -
trunk/LayoutTests/http/tests/security/resources/cross-frame-access.js
r41826 r51757 54 54 try { 55 55 return eval("window." + keyPath) !== undefined; 56 } catch(e) { 57 return false; 58 } 59 } 60 61 function canGetDescriptor(target, property) 62 { 63 try { 64 var desc = Object.getOwnPropertyDescriptor(target, property); 65 // To deal with an idiosyncrasy in how binding objects work in conjunction with 66 // slot and descriptor delegates we also allow descriptor with undefined value/getter/setter 67 return desc !== undefined && (desc.value !== undefined || desc.get !== undefined || desc.set !== undefined); 56 68 } catch(e) { 57 69 return false; -
trunk/LayoutTests/http/tests/security/resources/cross-frame-iframe-for-get-test.html
r30157 r51757 5 5 window.__proto__.windowPrototypeCustomProperty = 1; 6 6 window.Object.prototype.objectPrototypeCustomProperty = 1; 7 window.location.customProperty = 1; 8 window.history.customProperty = 1; 7 9 8 10 window.onload = function() -
trunk/LayoutTests/http/tests/security/xss-DENIED-defineProperty.html
r48542 r51757 17 17 document.getElementById("console").innerHTML += "FAIL: cross-site assignment of new property was allowed!<br/>"; 18 18 19 if ( Object.getOwnPropertyDescriptor(location, "hash").value.length == 0)19 if (location.hash.length == 0) 20 20 document.getElementById("console").innerHTML += "PASS: cross-site assignment of location.hash not allowed<br/>"; 21 21 else 22 22 document.getElementById("console").innerHTML += "FAIL: cross-site assignment of location.hash was allowed!<br/>"; 23 23 24 if ( Object.getOwnPropertyDescriptor(location, "hash").value.length == 0)24 if (location.search.length == 0) 25 25 document.getElementById("console").innerHTML += "PASS: cross-site assignment of location.search not allowed<br/>"; 26 26 else -
trunk/WebCore/ChangeLog
r51756 r51757 1 2009-12-06 Oliver Hunt <oliver@apple.com> 2 3 Reviewed by Maciej Stachowiak. 4 5 Object.getOwnPropertyDescriptor() allows cross-frame access 6 https://bugs.webkit.org/show_bug.cgi?id=32119 7 8 Make all implementations of getOwnPropertyDescriptor that have 9 cross domain restrictions simply fail immediately on cross domain 10 access, rather than trying to mimic the behaviour of normal 11 property access. 12 13 Test: http/tests/security/cross-frame-access-getOwnPropertyDescriptor.html 14 15 * bindings/js/JSDOMWindowCustom.cpp: 16 (WebCore::JSDOMWindow::getOwnPropertyDescriptor): 17 * bindings/js/JSHistoryCustom.cpp: 18 (WebCore::JSHistory::getOwnPropertyDescriptorDelegate): 19 * bindings/js/JSLocationCustom.cpp: 20 (WebCore::JSLocation::getOwnPropertyDescriptorDelegate): 21 * bindings/scripts/CodeGeneratorJS.pm: 22 1 23 2009-12-07 Steve Block <steveblock@google.com> 2 24 -
trunk/WebCore/bindings/js/JSDOMWindowCustom.cpp
r51577 r51757 298 298 bool JSDOMWindow::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 299 299 { 300 // When accessing a Window cross-domain, functions are always the native built-in ones, and they301 // are not affected by properties changed on the Window or anything in its prototype chain.302 // This is consistent with the behavior of Firefox.303 300 // Never allow cross-domain getOwnPropertyDescriptor 301 if (!allowsAccessFrom(exec)) 302 return false; 303 304 304 const HashEntry* entry; 305 305 … … 324 324 } 325 325 326 String errorMessage;327 bool allowsAccess = allowsAccessFrom(exec, errorMessage);328 if (allowsAccess && JSGlobalObject::getOwnPropertyDescriptor(exec, propertyName, descriptor))329 return true;330 331 326 // We need this code here because otherwise JSDOMWindowBase will stop the search before we even get to the 332 327 // prototype due to the blanket same origin (allowsAccessFrom) check at the end of getOwnPropertySlot. … … 336 331 if (entry) { 337 332 if (entry->attributes() & Function) { 338 if (entry->function() == jsDOMWindowPrototypeFunctionBlur) { 339 if (!allowsAccess) { 340 PropertySlot slot; 341 slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionBlur, 0>); 342 descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); 343 return true; 344 } 345 } else if (entry->function() == jsDOMWindowPrototypeFunctionClose) { 346 if (!allowsAccess) { 347 PropertySlot slot; 348 slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>); 349 descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); 350 return true; 351 } 352 } else if (entry->function() == jsDOMWindowPrototypeFunctionFocus) { 353 if (!allowsAccess) { 354 PropertySlot slot; 355 slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionFocus, 0>); 356 descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); 357 return true; 358 } 359 } else if (entry->function() == jsDOMWindowPrototypeFunctionPostMessage) { 360 if (!allowsAccess) { 361 PropertySlot slot; 362 slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionPostMessage, 2>); 363 descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); 364 return true; 365 } 366 } else if (entry->function() == jsDOMWindowPrototypeFunctionShowModalDialog) { 333 if (entry->function() == jsDOMWindowPrototypeFunctionShowModalDialog) { 367 334 if (!DOMWindow::canShowModalDialog(impl()->frame())) { 368 335 descriptor.setUndefined(); 369 336 return true; 370 337 } 371 }372 }373 } else {374 // Allow access to toString() cross-domain, but always Object.prototype.toString.375 if (propertyName == exec->propertyNames().toString) {376 if (!allowsAccess) {377 PropertySlot slot;378 slot.setCustom(this, objectToStringFunctionGetter);379 descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum);380 return true;381 338 } 382 339 } … … 407 364 JSValue proto = prototype(); 408 365 if (proto.isObject()) { 409 if (asObject(proto)->getPropertyDescriptor(exec, propertyName, descriptor)) { 410 if (!allowsAccess) { 411 printErrorMessage(errorMessage); 412 descriptor.setUndefined(); 413 } 366 if (asObject(proto)->getPropertyDescriptor(exec, propertyName, descriptor)) 414 367 return true; 415 }416 368 } 417 369 -
trunk/WebCore/bindings/js/JSHistoryCustom.cpp
r51644 r51757 96 96 bool JSHistory::getOwnPropertyDescriptorDelegate(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 97 97 { 98 // When accessing History cross-domain, functions are always the native built-in ones.99 // See JSDOMWindow::getOwnPropertySlotDelegate for additional details.100 101 // Our custom code is only needed to implement the Window cross-domain scheme, so if access is102 // allowed, return false so the normal lookup will take place. 103 String message;104 if ( allowsAccessFromFrame(exec, impl()->frame(), message))105 return false;106 98 if (!impl()->frame()) { 99 descriptor.setUndefined(); 100 return true; 101 } 102 103 // Throw out all cross domain access 104 if (!allowsAccessFromFrame(exec, impl()->frame())) 105 return true; 106 107 107 // Check for the few functions that we allow, even when called cross-domain. 108 108 const HashEntry* entry = JSHistoryPrototype::s_info.propHashTable(exec)->entry(exec, propertyName); … … 134 134 } 135 135 } 136 137 printErrorMessageForFrame(impl()->frame(), message); 136 138 137 descriptor.setUndefined(); 139 138 return true; -
trunk/WebCore/bindings/js/JSLocationCustom.cpp
r50784 r51757 103 103 } 104 104 105 // When accessing Location cross-domain, functions are always the native built-in ones. 106 // See JSDOMWindow::getOwnPropertySlotDelegate for additional details. 107 108 // Our custom code is only needed to implement the Window cross-domain scheme, so if access is 109 // allowed, return false so the normal lookup will take place. 110 String message; 111 if (allowsAccessFromFrame(exec, frame, message)) 112 return false; 105 // throw out all cross domain access 106 if (!allowsAccessFromFrame(exec, frame)) 107 return true; 113 108 114 109 // Check for the few functions that we allow, even when called cross-domain. … … 134 129 // but for now we have decided not to, partly because it seems silly to return "[Object Location]" in 135 130 // such cases when normally the string form of Location would be the URL. 136 137 printErrorMessageForFrame(frame, message); 131 138 132 descriptor.setUndefined(); 139 133 return true; -
trunk/WebCore/bindings/scripts/CodeGeneratorJS.pm
r51326 r51757 376 376 377 377 my @getOwnPropertyDescriptorImpl = (); 378 if ($dataNode->extendedAttributes->{"CheckDomainSecurity"}) { 379 if ($interfaceName eq "DOMWindow") { 380 push(@implContent, " if (!static_cast<$className*>(thisObject)->allowsAccessFrom(exec))\n"); 381 } else { 382 push(@implContent, " if (!allowsAccessFromFrame(exec, static_cast<$className*>(thisObject)->impl()->frame()))\n"); 383 } 384 push(@implContent, " return false;\n"); 385 } 378 386 379 387 if ($interfaceName eq "NamedNodeMap" or $interfaceName eq "HTMLCollection" or $interfaceName eq "HTMLAllCollection") {
Note: See TracChangeset
for help on using the changeset viewer.