Reviewed by Darin and Geoff.
<rdar://problem/
5619295>
REGRESSION: 303-304: Embedded YouTube video fails to render- JS errors (16150) (Flash 9)
Get rid of unnecessary and incorrect security checks for plug-ins accessing JavaScript objects.
The way this used to work was that each NPObject that wrapped a JSObject would have a root object
corresponding to the frame object (used for managing the lifecycle) and an origin root object (used for
doing security checks).
This would prevent a plug-in from accessing a frame's window object if it's security origin was different
(some parts of the window, such as the location object, can be accessed from frames with different security
origins, and those checks are being done in WebCore).
Also, if a plug-in were to access a window object of a frame that later went away, it could lead to that
Window JSObject being garbage collected and the NPObject pointing to freed memory.
How this works now is that there is no origin root object anymore, and all NPObject wrappers that are created
for a plug-in will have the root object of the containing frame of that plug-in.
* bindings/NP_jsobject.cpp:
(jsDeallocate):
Don't free the origin root object.
(_NPN_CreateScriptObject):
Remove the origin root object parameter.
(_NPN_InvokeDefault):
(_NPN_Invoke):
(_NPN_Evaluate):
(_NPN_GetProperty):
(_NPN_SetProperty):
(_NPN_RemoveProperty):
(_NPN_HasProperty):
(_NPN_HasMethod):
(_NPN_Enumerate):
Get rid of all security checks.
* bindings/NP_jsobject.h:
Remove originRootObject from the JavaScriptObject struct.
* bindings/c/c_utility.cpp:
(KJS::Bindings::convertValueToNPVariant):
Always use the root object from the ExecState.
WebCore:
Reviewed by Darin and Geoff.
<rdar://problem/
5619295>
REGRESSION: 303-304: Embedded YouTube video fails to render- JS errors (16150) (Flash 9)
_NPN_CreateScriptObject doesn't take an origin root object anymore.
* html/HTMLPlugInElement.cpp:
(WebCore::HTMLPlugInElement::createNPObject):
* page/Frame.cpp:
(WebCore::Frame::windowScriptNPObject):
WebKitTools:
Reviewed by Darin and Geoff.
<rdar://problem/
5619295>
REGRESSION: 303-304: Embedded YouTube video fails to render- JS errors (16150) (Flash 9)
Add property getting methods to the plug-in.
* DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.cpp:
(pluginInvoke):
LayoutTests:
Reviewed by Darin and Geoff.
<rdar://problem/
5619295>
REGRESSION: 303-304: Embedded YouTube video fails to render- JS errors (16150) (Flash 9)
Add cross frame plug/in test where a plug/in inside an iframe tries to access properties of the
top-level frame.
* http/tests/plugins/cross-frame-object-access-expected.txt: Added.
* http/tests/plugins/cross-frame-object-access.html: Added.
* http/tests/plugins/resources/cross-frame-object-access.html: Added.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@28715
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2007-12-14 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Darin and Geoff.
+
+ <rdar://problem/5619295>
+ REGRESSION: 303-304: Embedded YouTube video fails to render- JS errors (16150) (Flash 9)
+
+ Get rid of unnecessary and incorrect security checks for plug-ins accessing JavaScript objects.
+
+ The way this used to work was that each NPObject that wrapped a JSObject would have a root object
+ corresponding to the frame object (used for managing the lifecycle) and an origin root object (used for
+ doing security checks).
+
+ This would prevent a plug-in from accessing a frame's window object if it's security origin was different
+ (some parts of the window, such as the location object, can be accessed from frames with different security
+ origins, and those checks are being done in WebCore).
+
+ Also, if a plug-in were to access a window object of a frame that later went away, it could lead to that
+ Window JSObject being garbage collected and the NPObject pointing to freed memory.
+
+ How this works now is that there is no origin root object anymore, and all NPObject wrappers that are created
+ for a plug-in will have the root object of the containing frame of that plug-in.
+
+ * bindings/NP_jsobject.cpp:
+ (jsDeallocate):
+ Don't free the origin root object.
+
+ (_NPN_CreateScriptObject):
+ Remove the origin root object parameter.
+
+ (_NPN_InvokeDefault):
+ (_NPN_Invoke):
+ (_NPN_Evaluate):
+ (_NPN_GetProperty):
+ (_NPN_SetProperty):
+ (_NPN_RemoveProperty):
+ (_NPN_HasProperty):
+ (_NPN_HasMethod):
+ (_NPN_Enumerate):
+ Get rid of all security checks.
+
+ * bindings/NP_jsobject.h:
+ Remove originRootObject from the JavaScriptObject struct.
+
+ * bindings/c/c_utility.cpp:
+ (KJS::Bindings::convertValueToNPVariant):
+ Always use the root object from the ExecState.
+
2007-12-13 Steve Falkenburg <sfalken@apple.com>
Move source file generation into its own vcproj to fix build dependencies.
__Z12jsRegExpFreeP8JSRegExp
__Z15jsRegExpCompilePKti24JSRegExpIgnoreCaseOption23JSRegExpMultilineOptionPjPPKc
__Z15jsRegExpExecutePK8JSRegExpPKtiiPii
-__Z23_NPN_CreateScriptObjectP4_NPPPN3KJS8JSObjectEN3WTF10PassRefPtrINS1_8Bindings10RootObjectEEES8_
+__Z23_NPN_CreateScriptObjectP4_NPPPN3KJS8JSObjectEN3WTF10PassRefPtrINS1_8Bindings10RootObjectEEE
__Z25_NPN_CreateNoScriptObjectv
__ZN3KJS10Identifier11addSlowCaseEPNS_7UString3RepE
__ZN3KJS10Identifier3addEPKNS_5UCharEi
if (obj->rootObject)
obj->rootObject->deref();
- if (obj->originRootObject)
- obj->originRootObject->deref();
-
free(obj);
}
NPClass* NPScriptObjectClass = &javascriptClass;
static NPClass* NPNoScriptObjectClass = &noScriptClass;
-static bool _isSafeScript(JavaScriptObject* obj)
-{
- if (!obj->originRootObject || !obj->rootObject)
- return true;
-
- if (!obj->originRootObject->isValid() || !obj->rootObject->isValid())
- return false;
-
- return obj->rootObject->globalObject()->allowsAccessFrom(obj->originRootObject->globalObject());
-}
-
-NPObject* _NPN_CreateScriptObject(NPP npp, JSObject* imp, PassRefPtr<RootObject> originRootObject, PassRefPtr<RootObject> rootObject)
+NPObject* _NPN_CreateScriptObject(NPP npp, JSObject* imp, PassRefPtr<RootObject> rootObject)
{
JavaScriptObject* obj = (JavaScriptObject*)_NPN_CreateObject(npp, NPScriptObjectClass);
- obj->originRootObject = originRootObject.releaseRef();
obj->rootObject = rootObject.releaseRef();
if (obj->rootObject)
{
if (o->_class == NPScriptObjectClass) {
JavaScriptObject* obj = (JavaScriptObject*)o;
- if (!_isSafeScript(obj))
- return false;
VOID_TO_NPVARIANT(*result);
{
if (o->_class == NPScriptObjectClass) {
JavaScriptObject* obj = (JavaScriptObject*)o;
- if (!_isSafeScript(obj))
- return false;
PrivateIdentifier* i = (PrivateIdentifier*)methodName;
if (!i->isString)
if (o->_class == NPScriptObjectClass) {
JavaScriptObject* obj = (JavaScriptObject*)o;
- if (!_isSafeScript(obj))
- return false;
-
RootObject* rootObject = obj->rootObject;
if (!rootObject || !rootObject->isValid())
return false;
{
if (o->_class == NPScriptObjectClass) {
JavaScriptObject* obj = (JavaScriptObject*)o;
- if (!_isSafeScript(obj))
- return false;
RootObject* rootObject = obj->rootObject;
if (!rootObject || !rootObject->isValid())
{
if (o->_class == NPScriptObjectClass) {
JavaScriptObject* obj = (JavaScriptObject*)o;
- if (!_isSafeScript(obj))
- return false;
RootObject* rootObject = obj->rootObject;
if (!rootObject || !rootObject->isValid())
{
if (o->_class == NPScriptObjectClass) {
JavaScriptObject* obj = (JavaScriptObject*)o;
- if (!_isSafeScript(obj))
- return false;
RootObject* rootObject = obj->rootObject;
if (!rootObject || !rootObject->isValid())
{
if (o->_class == NPScriptObjectClass) {
JavaScriptObject* obj = (JavaScriptObject*)o;
- if (!_isSafeScript(obj))
- return false;
RootObject* rootObject = obj->rootObject;
if (!rootObject || !rootObject->isValid())
{
if (o->_class == NPScriptObjectClass) {
JavaScriptObject* obj = (JavaScriptObject*)o;
- if (!_isSafeScript(obj))
- return false;
PrivateIdentifier* i = (PrivateIdentifier*)methodName;
if (!i->isString)
{
if (o->_class == NPScriptObjectClass) {
JavaScriptObject* obj = (JavaScriptObject*)o;
- if (!_isSafeScript(obj))
- return false;
RootObject* rootObject = obj->rootObject;
if (!rootObject || !rootObject->isValid())
{
NPObject object;
KJS::JSObject* imp;
- KJS::Bindings::RootObject* originRootObject;
KJS::Bindings::RootObject* rootObject;
};
-NPObject* _NPN_CreateScriptObject(NPP npp, KJS::JSObject*, PassRefPtr<KJS::Bindings::RootObject> originRootObject, PassRefPtr<KJS::Bindings::RootObject> rootObject);
+NPObject* _NPN_CreateScriptObject(NPP npp, KJS::JSObject*, PassRefPtr<KJS::Bindings::RootObject> rootObject);
NPObject* _NPN_CreateNoScriptObject(void);
#endif
OBJECT_TO_NPVARIANT(obj, *result);
}
} else {
- JSGlobalObject* originGlobalObject = exec->dynamicGlobalObject();
- RootObject* originRootObject = findRootObject(originGlobalObject);
-
- JSGlobalObject* globalObject = 0;
- if (object->isGlobalObject())
- globalObject = static_cast<JSGlobalObject*>(object);
-
- if (!globalObject)
- globalObject = originGlobalObject;
+ JSGlobalObject* globalObject = exec->dynamicGlobalObject();
RootObject* rootObject = findRootObject(globalObject);
if (rootObject) {
- NPObject* npObject = _NPN_CreateScriptObject(0, object, originRootObject, rootObject);
+ NPObject* npObject = _NPN_CreateScriptObject(0, object, rootObject);
OBJECT_TO_NPVARIANT(npObject, *result);
}
}
+2007-12-14 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Darin and Geoff.
+
+ <rdar://problem/5619295>
+ REGRESSION: 303-304: Embedded YouTube video fails to render- JS errors (16150) (Flash 9)
+
+ Add cross frame plug/in test where a plug/in inside an iframe tries to access properties of the
+ top-level frame.
+
+ * http/tests/plugins/cross-frame-object-access-expected.txt: Added.
+ * http/tests/plugins/cross-frame-object-access.html: Added.
+ * http/tests/plugins/resources/cross-frame-object-access.html: Added.
+
2007-12-14 Oliver Hunt <oliver@apple.com>
Reviewed by Adam.
* svg/custom/inline-svg-in-xhtml-expected.checksum: Added.
* svg/custom/inline-svg-in-xhtml-expected.png: Added.
-2007-12-11 Anders Carlsson <andersca@apple.com>
+2007-12-12 Anders Carlsson <andersca@apple.com>
Reviewed by Sam.
--- /dev/null
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://127.0.0.1:8000/plugins/cross-frame-object-access.html from frame with URL http://localhost:8000/plugins/resources/cross-frame-object-access.html. Domains, protocols and ports must match.
+
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://127.0.0.1:8000/plugins/cross-frame-object-access.html from frame with URL http://localhost:8000/plugins/resources/cross-frame-object-access.html. Domains, protocols and ports must match.
+
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://127.0.0.1:8000/plugins/cross-frame-object-access.html from frame with URL http://localhost:8000/plugins/resources/cross-frame-object-access.html. Domains, protocols and ports must match.
+
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://127.0.0.1:8000/plugins/cross-frame-object-access.html from frame with URL http://localhost:8000/plugins/resources/cross-frame-object-access.html. Domains, protocols and ports must match.
+
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://127.0.0.1:8000/plugins/cross-frame-object-access.html from frame with URL http://localhost:8000/plugins/resources/cross-frame-object-access.html. Domains, protocols and ports must match.
+
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://127.0.0.1:8000/plugins/cross-frame-object-access.html from frame with URL http://localhost:8000/plugins/resources/cross-frame-object-access.html. Domains, protocols and ports must match.
+
+
+
+--------
+Frame: 'childFrame'
+--------
+
+This tests that plug-ins can access objects in other frames as allowed by the security model enforced in WebCore.
+SUCCESS
--- /dev/null
+<html>
+<head>
+<script>
+if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.dumpChildFramesAsText();
+}
+</script>
+<iframe name="childFrame" src="http://localhost:8000/plugins/resources/cross-frame-object-access.html"></iframe>
+</body>
+</html>
--- /dev/null
+<html>
+<head>
+<script>
+function debug(str) {
+ var li = document.createElement('li');
+ li.appendChild(document.createTextNode(str));
+ document.getElementById('console').appendChild(li)
+}
+
+function checkLocationObject(l)
+{
+ if (!l) {
+ debug('could not access top.location');
+ return false;
+ }
+
+ if (l.href) {
+ debug('could access top.location.href');
+ return false;
+ }
+
+ return true;
+}
+
+function runTest() {
+ var numErrors = 0;
+
+ // Try accessing childFrame.location using NPN_Evaluate
+ var l = document.plugin.testEvaluate('top.location')
+ if (!checkLocationObject(l))
+ numErrors++;
+
+ // Try getting childFrame.location.href using NPN_Evaluate
+ var href = document.plugin.testEvaluate('top.location.href');
+ if (href) {
+ debug("could access top.location.href")
+ numErrors++;
+ }
+
+ // Try accessing childFrame.location using NPN_GetProperty
+ var l = document.plugin.testGetProperty('top', 'location');
+ if (!checkLocationObject(l))
+ numErrors++;
+
+ var href = document.plugin.testGetProperty('top', 'location', 'href');
+ if (href) {
+ debug("could access top.location.href")
+ numErrors++;
+ }
+
+ // Try accessing top.document using NPN_EVALUATE
+ var l = document.plugin.testEvaluate('top.document')
+ if (l) {
+ debug('could access top.document');
+ numErrors++;
+ }
+
+ // Try accessing top.document using NPN_GetProperty
+ var l = document.plugin.testGetProperty('top', 'document')
+ if (l) {
+ debug('could access top.document');
+ numErrors++;
+ }
+
+ if (numErrors == 0)
+ document.getElementById('result').innerHTML = 'SUCCESS';
+}
+
+</script>
+</head>
+<body onload="runTest()">
+<embed name="plugin" type="application/x-webkit-test-netscape"></embed>
+<div>This tests that plug-ins can access objects in other frames as allowed by the security model enforced in WebCore.</div>
+<ul id="console">
+</ul>
+<div id="result">FAILURE</div>
+</body>
+</html>
+2007-12-14 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Darin and Geoff.
+
+ <rdar://problem/5619295>
+ REGRESSION: 303-304: Embedded YouTube video fails to render- JS errors (16150) (Flash 9)
+
+ _NPN_CreateScriptObject doesn't take an origin root object anymore.
+
+ * html/HTMLPlugInElement.cpp:
+ (WebCore::HTMLPlugInElement::createNPObject):
+ * page/Frame.cpp:
+ (WebCore::Frame::windowScriptNPObject):
+
2007-12-14 Dan Bernstein <mitz@apple.com>
Reviewed by Darin Adler.
// Wrap the JSObject in an NPObject
RootObject* rootObject = frame->bindingRootObject();
- return _NPN_CreateScriptObject(0, jsElementValue->getObject(), rootObject, rootObject);
+ return _NPN_CreateScriptObject(0, jsElementValue->getObject(), rootObject);
}
NPObject* HTMLPlugInElement::getNPObject()
KJS::JSObject* win = KJS::Window::retrieveWindow(this);
ASSERT(win);
KJS::Bindings::RootObject* root = bindingRootObject();
- d->m_windowScriptNPObject = _NPN_CreateScriptObject(0, win, root, root);
+ d->m_windowScriptNPObject = _NPN_CreateScriptObject(0, win, root);
} else {
// JavaScript is not enabled, so we cannot bind the NPObject to the JavaScript window object.
// Instead, we create an NPObject of a different class, one which is not bound to a JavaScript object.
+2007-12-14 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Darin and Geoff.
+
+ <rdar://problem/5619295>
+ REGRESSION: 303-304: Embedded YouTube video fails to render- JS errors (16150) (Flash 9)
+
+ Add property getting methods to the plug-in.
+
+ * DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.cpp:
+ (pluginInvoke):
+
2007-12-14 Kevin McCullough <kmccullough@apple.com>
Reviewed by Darin.
* DumpRenderTree/win/LayoutTestControllerWin.cpp:
(LayoutTestController::pathToLocalResource):
-2007-12-11 Anders Carlsson <andersca@apple.com>
+2007-12-12 Anders Carlsson <andersca@apple.com>
Reviewed by Sam.
#define ID_DESTROY_STREAM 6
#define ID_TEST_ENUMERATE 7
#define ID_TEST_GETINTIDENTIFIER 8
-#define NUM_METHOD_IDENTIFIERS 9
+#define ID_TEST_GET_PROPERTY 9
+#define ID_TEST_EVALUATE 10
+#define NUM_METHOD_IDENTIFIERS 11
static NPIdentifier pluginMethodIdentifiers[NUM_METHOD_IDENTIFIERS];
static const NPUTF8 *pluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = {
"testInvokeDefault",
"destroyStream",
"testEnumerate",
- "testGetIntIdentifier"
+ "testGetIntIdentifier",
+ "testGetProperty",
+ "testEvaluate",
};
static NPUTF8* createCStringFromNPVariant(const NPVariant *variant)
INT32_TO_NPVARIANT((int32)identifier, *result);
return true;
}
+ } else if (name == pluginMethodIdentifiers[ID_TEST_EVALUATE] &&
+ argCount == 1 && NPVARIANT_IS_STRING(args[0])) {
+ NPObject *windowScriptObject;
+ browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
+
+ NPString s = NPVARIANT_TO_STRING(args[0]);
+
+ bool retval = browser->evaluate(obj->npp, windowScriptObject, &s, result);
+ browser->releaseobject(windowScriptObject);
+ return retval;
+ } else if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY] &&
+ argCount > 0) {
+ NPObject *object;
+ browser->getvalue(obj->npp, NPNVWindowNPObject, &object);
+
+ for (uint32_t i = 0; i < argCount; i++) {
+ assert(NPVARIANT_IS_STRING(args[i]));
+ char *propertyString = createCStringFromNPVariant(&args[i]);
+ NPIdentifier propertyIdentifier = browser->getstringidentifier(propertyString);
+
+ NPVariant variant;
+ bool retval = browser->getproperty(obj->npp, object, propertyIdentifier, &variant);
+ browser->releaseobject(object);
+
+ if (!retval)
+ break;
+
+ if (i + 1 < argCount) {
+ assert(NPVARIANT_IS_OBJECT(variant));
+ object = NPVARIANT_TO_OBJECT(variant);
+ } else {
+ *result = variant;
+ return true;
+ }
+ }
+
+ VOID_TO_NPVARIANT(*result);
+ return false;
}
return false;