🐛 should keep the property writable while it only have setter accessor (#2302)

This commit is contained in:
Kuitos 2022-10-13 21:37:43 +08:00 committed by GitHub
parent 4e7bfd2732
commit 9df1bf9c83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 2 deletions

View File

@ -409,6 +409,55 @@ it('native window function calling should always be bound with window', () => {
expect(proxy.nativeWindowFunction()).toBe('success');
});
describe('should work well while the property existed in global context before', () => {
it('should not write value while the readonly property existed in global context but not in sandbox', () => {
Object.defineProperty(window, 'readonlyPropertyInGlobalContext', {
value: 123,
writable: false,
configurable: true,
});
const { proxy } = new ProxySandbox('readonly-sandbox');
proxy.readonlyPropertyInGlobalContext = 456;
expect(proxy.readonlyPropertyInGlobalContext).toBe(123);
Object.defineProperty(window, 'readonlyPropertyInGlobalContext', {
get() {
return '123';
},
configurable: true,
});
const { proxy: proxy2 } = new ProxySandbox('readonly-sandbox');
proxy2.readonlyPropertyInGlobalContext = 456;
expect(proxy2.readonlyPropertyInGlobalContext).toBe(123);
});
it('should write value while the writable property existed in global context but not in sandbox', () => {
Object.defineProperty(window, 'readonlyPropertyInGlobalContext', {
value: 123,
writable: true,
configurable: true,
});
const { proxy } = new ProxySandbox('readonly-sandbox');
proxy.readonlyPropertyInGlobalContext = 456;
proxy.readonlyPropertyInGlobalContext = 789;
expect(proxy.readonlyPropertyInGlobalContext).toBe(789);
Object.defineProperty(window, 'readonlyPropertyInGlobalContext', {
get() {
return '123';
},
set() {
// do nothing
},
configurable: true,
});
const { proxy: proxy2 } = new ProxySandbox('readonly-sandbox');
proxy2.readonlyPropertyInGlobalContext = 456;
proxy2.readonlyPropertyInGlobalContext = 789;
expect(proxy2.readonlyPropertyInGlobalContext).toBe(789);
});
});
describe('variables in whitelist', () => {
it('should restore window properties (primitive values) that in whitelisted variables', () => {
const original = {

View File

@ -183,8 +183,13 @@ export default class ProxySandbox implements SandBox {
// We must keep its description while the property existed in globalContext before
if (!target.hasOwnProperty(p) && globalContext.hasOwnProperty(p)) {
const descriptor = Object.getOwnPropertyDescriptor(globalContext, p);
const { writable, configurable, enumerable } = descriptor!;
Object.defineProperty(target, p, { configurable, enumerable, writable, value });
const { writable, configurable, enumerable, set } = descriptor!;
// only writable property can be overwritten
// here we ignored accessor descriptor of globalContext as it makes no sense to trigger its logic(which might make sandbox escaping instead)
// we force to set value by data descriptor
if (writable || set) {
Object.defineProperty(target, p, { configurable, enumerable, writable: true, value });
}
} else {
target[p] = value;
}