Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getOwnPropertyDescriptor() can be used to get access to raw values #20

Closed
ravijayaramappa opened this issue Aug 21, 2018 · 0 comments
Closed

Comments

@ravijayaramappa
Copy link
Contributor

ravijayaramappa commented Aug 21, 2018

Description

When an observable value has a configurable property, the reactive proxy and the readonly proxy can be bypassed to gain access to the underlying raw value.

This can be done using the getOwnPropertyDescriptor() to gain access to the raw descriptor of the raw value. In the case of the read-only proxy, the user can bypass the read only membrane and mutate the original object.

Further, the proxy implementation has to protection for descriptors that have a getter/setter.

Steps to Reproduce

const target = new ReactiveMembrane();
const todos = {};
const observable = {};
Object.defineProperty(todos, 'foo', {
    get() {
        return observable;
    },
    configurable: true
});

const proxy = target.getProxy(todos);
const desc = Object.getOwnPropertyDescriptor(proxy, 'foo');
const { get } = desc;
get(); // Will return the raw observable object. expected to see a reactive proxy
proxy.foo; // Will return a reactive proxy as expected
const target = new ReactiveMembrane();
const todos = {};
const observable = {};
Object.defineProperty(todos, 'foo', {
    value : observable,
    configurable: true
});

const proxy = target.getProxy(todos);

const desc = Object.getOwnPropertyDescriptor(proxy, 'foo');
const { value } = desc;
value; Will be the raw observable object, expected to be a proxy

Added tests as part of a PR: #21

Expected Results

Should not be able to evade the membrane containment using getOwnPropertyDescriptor()

Actual Results

Able to get out of the membrane

Browsers Affected

all

Version

0.25.0

Possible Solution

getOwnPropertyDescriptor(shadowTarget: ReactiveMembraneShadowTarget, key: PropertyKey): PropertyDescriptor | undefined {
    const { originalTarget, membrane, valueObserved } = this;

    // keys looked up via hasOwnProperty need to be reactive
    if (!isUndefined(valueObserved)) {
        valueObserved(originalTarget, key);
    }

    let desc = getOwnPropertyDescriptor(originalTarget, key);
    if (isUndefined(desc)) {
        return desc;
    }
    // Fix
    if(configurable) {
        return wrapDescriptor(membrane, desc);
    }
    // endFix
    const shadowDescriptor = getOwnPropertyDescriptor(shadowTarget, key);
    if (!desc.configurable && !shadowDescriptor) {
        // If descriptor from original target is not configurable,
        // We must copy the wrapped descriptor over to the shadow target.
        // Otherwise, proxy will throw an invariant error.
        // This is our last chance to lock the value.
        // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/getOwnPropertyDescriptor#Invariants
        desc = wrapDescriptor(membrane, desc);
        ObjectDefineProperty(shadowTarget, key, desc);
    }
    return shadowDescriptor || desc;
}

Additional context/Screenshots
Add any other context about the problem here. If applicable, add screenshots to help explain.

ravijayaramappa added a commit to ravijayaramappa/observable-membrane that referenced this issue Aug 21, 2018
ravijayaramappa added a commit to ravijayaramappa/observable-membrane that referenced this issue Aug 21, 2018
ravijayaramappa added a commit to ravijayaramappa/observable-membrane that referenced this issue Aug 21, 2018
Test to demostrate that membrane containment can be bypassed using getOwnPropertyDescriptor()
ravijayaramappa added a commit to ravijayaramappa/observable-membrane that referenced this issue Aug 21, 2018
Test to demostrate that membrane containment can be bypassed using getOwnPropertyDescriptor()
@ravijayaramappa ravijayaramappa changed the title getOwnPropertyDescriptor() can be used to get access to real raw values getOwnPropertyDescriptor() can be used to get access to raw values Aug 21, 2018
ravijayaramappa added a commit to ravijayaramappa/observable-membrane that referenced this issue Aug 21, 2018
Test to demostrate that membrane containment can be bypassed using getOwnPropertyDescriptor()
caridy added a commit that referenced this issue Sep 13, 2018
caridy added a commit that referenced this issue Sep 14, 2018
@caridy caridy closed this as completed in 4bd4751 Sep 16, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant