Universal XSS in JSObject::putInlineSlow and JSValue::putToPrimitive
authorysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 10 Aug 2019 01:20:22 +0000 (01:20 +0000)
committerysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 10 Aug 2019 01:20:22 +0000 (01:20 +0000)
commit2cea47c12b0e73fb90d3686b4d21aaa4faf3e20d
tree5b7a319d5d3b2c3c0a77183ff2e957aabad61784
parent554d7865a0874704c5da383553be2b321a41970b
Universal XSS in JSObject::putInlineSlow and JSValue::putToPrimitive
https://bugs.webkit.org/show_bug.cgi?id=199864

Reviewed by Saam Barati.

Source/JavaScriptCore:

Our JSObject::put implementation is not correct in term of the spec. Our [[Put]] implementation is something like this.

    JSObject::put(object):
        if (can-do-fast-path(object))
            return fast-path(object);
        // slow-path
        do {
            object-put-check-and-setter-calls(object); // (1)
            object = object->prototype;
        } while (is-object(object));
        return do-put(object);

Since JSObject::put is registered in the methodTable, the derived classes can override it. Some of classes are adding
extra checks to this put.

    Derived::put(object):
        if (do-extra-check(object))
            fail
        return JSObject::put(object)

The problem is that Derived::put is only called when the |this| object is the Derived class. When traversing [[Prototype]] in
JSObject::put, at (1), we do not perform the extra checks added in Derived::put even if `object` is Derived one. This means that
we skip the check.

Currently, JSObject::put and WebCore checking mechanism are broken. JSObject::put should call getOwnPropertySlot at (1) to
perform the additional checks. This behavior is matching against the spec. However, currently, our JSObject::getOwnPropertySlot
does not propagate setter information. This is required to cache cacheable [[Put]] at (1) for CustomValue, CustomAccessor, and
Accessors. We also need to reconsider how to integrate static property setters to this mechanism. So, basically, this involves
large refactoring to renew our JSObject::put and JSObject::getOwnPropertySlot.

To work-around for now, we add a new TypeInfo flag, HasPutPropertySecurityCheck . And adding this flag to DOM objects
that implements the addition checks. We also add doPutPropertySecurityCheck method hook to perform the check in JSObject.
When we found this flag at (1), we perform doPutPropertySecurityCheck to properly perform the checks.

Since our JSObject::put code is old and it does not match against the spec now, we should refactor it largely. This is tracked separately in [1].

[1]: https://bugs.webkit.org/show_bug.cgi?id=200562

* runtime/ClassInfo.h:
* runtime/JSCJSValue.cpp:
(JSC::JSValue::putToPrimitive):
* runtime/JSCell.cpp:
(JSC::JSCell::doPutPropertySecurityCheck):
* runtime/JSCell.h:
* runtime/JSObject.cpp:
(JSC::JSObject::putInlineSlow):
(JSC::JSObject::getOwnPropertyDescriptor):
* runtime/JSObject.h:
(JSC::JSObject::doPutPropertySecurityCheck):
* runtime/JSTypeInfo.h:
(JSC::TypeInfo::hasPutPropertySecurityCheck const):

Source/WebCore:

Test: http/tests/security/cross-frame-access-object-put-optimization.html

* bindings/js/JSDOMWindowCustom.cpp:
(WebCore::JSDOMWindow::doPutPropertySecurityCheck):
* bindings/js/JSLocationCustom.cpp:
(WebCore::JSLocation::doPutPropertySecurityCheck):
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateHeader):
* bindings/scripts/test/JS/JSTestActiveDOMObject.h:

LayoutTests:

* http/tests/security/cross-frame-access-object-put-optimization-expected.txt: Added.
* http/tests/security/cross-frame-access-object-put-optimization.html: Added.
* http/tests/security/resources/cross-frame-iframe-for-object-put-optimization-test.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@248494 268f45cc-cd09-0410-ab3c-d52691b4dbfc
17 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/security/cross-frame-access-object-put-optimization-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/cross-frame-access-object-put-optimization.html [new file with mode: 0644]
LayoutTests/http/tests/security/resources/cross-frame-iframe-for-object-put-optimization-test.html [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/ClassInfo.h
Source/JavaScriptCore/runtime/JSCJSValue.cpp
Source/JavaScriptCore/runtime/JSCell.cpp
Source/JavaScriptCore/runtime/JSCell.h
Source/JavaScriptCore/runtime/JSObject.cpp
Source/JavaScriptCore/runtime/JSObject.h
Source/JavaScriptCore/runtime/JSTypeInfo.h
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/JSDOMWindowCustom.cpp
Source/WebCore/bindings/js/JSLocationCustom.cpp
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/bindings/scripts/test/JS/JSTestActiveDOMObject.h