New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@caridy/sjs

Package Overview
Dependencies
Maintainers
1
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@caridy/sjs - npm Package Compare versions

Comparing version 0.2.9 to 0.2.10

98

lib/blue.js

@@ -1,2 +0,2 @@

import { apply, assign, construct, ReflectSetPrototypeOf, freeze, isFunction, ObjectCreate, isUndefined, ReflectGetOwnPropertyDescriptor, ReflectDefineProperty, ErrorCreate, ReflectGetPrototypeOf, ReflectGet, ReflectSet, map, isNullOrUndefined, unconstruct, ownKeys, ReflectIsExtensible, ReflectPreventExtensions, deleteProperty, } from "./shared.js";
import { apply, assign, construct, ReflectSetPrototypeOf, freeze, isFunction, ObjectCreate, isUndefined, ReflectGetOwnPropertyDescriptor, ReflectDefineProperty, ErrorCreate, ReflectGetPrototypeOf, ReflectGet, ReflectSet, ReflectHas, map, isNull, isNullOrUndefined, unconstruct, ownKeys, ReflectIsExtensible, ReflectPreventExtensions, deleteProperty, hasOwnProperty, emptyArray, } from "./shared.js";
function renameFunction(provider, receiver) {

@@ -106,17 +106,2 @@ try {

}
get(shadowTarget, key, receiver) {
/**
* If the target has a non-configurable own data descriptor that was observed by the red side,
* and therefore installed in the shadowTarget, we might get into a situation where a writable,
* non-configurable value in the target is out of sync with the shadowTarget's value for the same
* key. This is fine because this does not violate the object invariants, and even though they
* are out of sync, the original descriptor can only change to something that is compatible with
* what was installed in shadowTarget, and in order to observe that, the getOwnPropertyDescriptor
* trap must be used, which will take care of synchronizing them again.
*/
return env.getBlueValue(ReflectGet(this.target, key, env.getRedValue(receiver)));
}
set(shadowTarget, key, value, receiver) {
return ReflectSet(this.target, key, env.getRedValue(value), env.getRedValue(receiver));
}
deleteProperty(shadowTarget, key) {

@@ -188,4 +173,83 @@ return deleteProperty(this.target, key);

}
/**
* This trap cannot just use `Reflect.get` directly on the `target` because
* the red object graph might have mutations that are only visible on the red side,
* which means looking into `target` directly is not viable. Instead, we need to
* implement a more crafty solution that looks into target's own properties, or
* in the red proto chain when needed.
*/
get(shadowTarget, key, receiver) {
/**
* If the target has a non-configurable own data descriptor that was observed by the red side,
* and therefore installed in the shadowTarget, we might get into a situation where a writable,
* non-configurable value in the target is out of sync with the shadowTarget's value for the same
* key. This is fine because this does not violate the object invariants, and even though they
* are out of sync, the original descriptor can only change to something that is compatible with
* what was installed in shadowTarget, and in order to observe that, the getOwnPropertyDescriptor
* trap must be used, which will take care of synchronizing them again.
*/
const { target } = this;
const redDescriptor = ReflectGetOwnPropertyDescriptor(target, key);
if (isUndefined(redDescriptor)) {
// looking in the blue proto chain to avoid switching sides
const blueProto = getBlueValue(ReflectGetPrototypeOf(target));
if (isNull(blueProto)) {
return;
}
return ReflectGet(blueProto, key, receiver);
}
if (hasOwnProperty(redDescriptor, 'get')) {
// Knowing that it is an own getter, we can't still not use Reflect.get
// because there might be a distortion for such getter, and from the blue
// side, we should not be subject to those distortions.
return apply(getBlueValue(redDescriptor.get), receiver, emptyArray);
}
// if it is not an accessor property, is either a setter only accessor
// or a data property, in which case we could return undefined or the blue value
return getBlueValue(redDescriptor.value);
}
/**
* This trap cannot just use `Reflect.set` directly on the `target` on the
* red side because the red object graph might have mutations that are only visible
* on the red side, which means looking into `target` directly is not viable.
* Instead, we need to implement a more crafty solution that looks into target's
* own properties, or in the blue proto chain when needed.
*/
set(shadowTarget, key, value, receiver) {
const { target } = this;
const redDescriptor = ReflectGetOwnPropertyDescriptor(target, key);
if (isUndefined(redDescriptor)) {
// looking in the blue proto chain to avoid switching sides
const blueProto = getBlueValue(ReflectGetPrototypeOf(target));
if (!isNull(blueProto)) {
return ReflectSet(blueProto, key, value, receiver);
}
}
else if (hasOwnProperty(redDescriptor, 'set')) {
// even though the setter function exists, we can't use Reflect.set because there might be
// a distortion for that setter function, and from the blue side, we should not be subject
// to those distortions.
apply(getBlueValue(redDescriptor.set), receiver, [value]);
return true; // if there is a callable setter, it either throw or we can assume the value was set
}
// if it is not an accessor property, is either a getter only accessor
// or a data property, in which case we use Reflect.set to set the value,
// and no receiver is needed since it will simply set the data property or nothing
return ReflectSet(target, key, env.getRedValue(value));
}
/**
* This trap cannot just use `Reflect.has` or the `in` operator directly on the
* red side because the red object graph might have mutations that are only visible
* on the red side, which means looking into `target` directly is not viable.
* Instead, we need to implement a more crafty solution that looks into target's
* own properties, or in the blue proto chain when needed.
*/
has(shadowTarget, key) {
return key in this.target;
const { target } = this;
if (hasOwnProperty(target, key)) {
return true;
}
// looking in the blue proto chain to avoid switching sides
const blueProto = getBlueValue(ReflectGetPrototypeOf(target));
return !isNull(blueProto) && ReflectHas(blueProto, key);
}

@@ -192,0 +256,0 @@ ownKeys(shadowTarget) {

33

lib/browser-realm.js
import { SecureEnvironment } from "./environment.js";
import { ReflectGetPrototypeOf, ReflectSetPrototypeOf, getOwnPropertyDescriptors, construct, ErrorCreate, WeakMapCreate, isUndefined, ObjectCreate, WeakMapGet, assign, ownKeys, } from "./shared.js";
import { ReflectGetPrototypeOf, ReflectSetPrototypeOf, getOwnPropertyDescriptors, construct, ErrorCreate, WeakMapCreate, isUndefined, ObjectCreate, WeakMapGet, assign, ownKeys, unapply, ReflectGetOwnPropertyDescriptor, } from "./shared.js";
;

@@ -121,10 +121,28 @@ const cachedGlobalMap = WeakMapCreate();

const IFRAME_SANDBOX_ATTRIBUTE_VALUE = 'allow-same-origin allow-scripts';
export default function createSecureEnvironment(distortionMap, endowments) {
const appendChildCall = unapply(Node.prototype.appendChild);
const removeCall = unapply(Element.prototype.remove);
const isConnectedGetterCall = unapply(ReflectGetOwnPropertyDescriptor(Node.prototype, 'isConnected').get);
const nodeLastChildGetterCall = unapply(ReflectGetOwnPropertyDescriptor(Node.prototype, 'lastChild').get);
const documentBodyGetterCall = unapply(ReflectGetOwnPropertyDescriptor(Document.prototype, 'body').get);
const createElementCall = unapply(document.createElement);
function createDetachableIframe() {
// @ts-ignore document global ref - in browsers
const iframe = document.createElement('iframe');
const iframe = createElementCall(document, 'iframe');
iframe.setAttribute('allow', IFRAME_ALLOW_ATTRIBUTE_VALUE);
iframe.setAttribute('sandbox', IFRAME_SANDBOX_ATTRIBUTE_VALUE);
iframe.style.display = 'none';
// @ts-ignore document global ref - in browsers
document.body.appendChild(iframe);
const parent = documentBodyGetterCall(document) || nodeLastChildGetterCall(document);
appendChildCall(parent, iframe);
return iframe;
}
function removeIframe(iframe) {
// In Chrome debugger statements will be ignored when the iframe is removed
// from the document. Other browsers like Firefox and Safari work as expected.
// https://bugs.chromium.org/p/chromium/issues/detail?id=1015462
if (isConnectedGetterCall(iframe)) {
removeCall(iframe);
}
}
export default function createSecureEnvironment(distortionMap, endowments) {
const iframe = createDetachableIframe();
// For Chrome we evaluate the `window` object to kickstart the realm so that

@@ -136,6 +154,3 @@ // `window` persists when the iframe is removed from the document.

const blueGlobalThis = globalThis;
// In Chrome debugger statements will be ignored when the iframe is removed
// from the document. Other browsers like Firefox and Safari work as expected.
// https://bugs.chromium.org/p/chromium/issues/detail?id=1015462
iframe.remove();
removeIframe(iframe);
const blueRefs = getCachedReferences(blueGlobalThis);

@@ -142,0 +157,0 @@ const redRefs = getCachedReferences(redGlobalThis);

@@ -11,2 +11,3 @@ export const serializedRedEnvSourceText = (function redEnvFactory(blueEnv, hooks) {

const noop = () => undefined;
const emptyArray = [];
const map = unapply(Array.prototype.map);

@@ -57,2 +58,3 @@ const WeakMapGet = unapply(WeakMap.prototype.get);

if (typeof blue === 'undefined') {
// @ts-ignore blue at this point is type T because of the previous condition
return undefined;

@@ -292,7 +294,12 @@ }

const redProto = getRedValue(getPrototypeOf(target));
if (isNull(redProto)) {
return undefined;
}
return ReflectGet(redProto, key, receiver);
}
if (hasOwnPropertyCall(blueDescriptor, 'get')) {
// TODO: add a note here
return apply(getRedValue(blueDescriptor.get), receiver, []);
// Knowing that it is an own getter, we can't still not use Reflect.get
// because there might be a distortion for such getter, in which case we
// must get the red getter, and call it.
return apply(getRedValue(blueDescriptor.get), receiver, emptyArray);
}

@@ -317,3 +324,3 @@ // if it is not an accessor property, is either a setter only accessor

const redProto = getRedValue(getPrototypeOf(target));
return ReflectHas(redProto, key);
return !isNull(redProto) && ReflectHas(redProto, key);
}

@@ -370,5 +377,7 @@ function redProxyDynamicOwnKeysTrap(shadowTarget) {

if (hasOwnPropertyCall(blueDescriptor, 'set')) {
// TODO: add the note about the set being a proxy that returns false on the set trap
// even though the setter function exists, we can't use Reflect.set because there might be
// a distortion for that setter function, in which case we must resolve the red setter
// and call it instead.
apply(getRedValue(blueDescriptor.set), receiver, [value]);
return true; // because we don't know if the setter actually sets the value, we assume it does it
return true; // if there is a callable setter, it either throw or we can assume the value was set
}

@@ -530,3 +539,4 @@ // if it is not an accessor property, is either a getter only accessor

catch (_a) {
// TODO: target is a revoked proxy. This could be optimized if Meta becomes available here.
// target is either a revoked proxy, or a proxy that throws on the has trap,
// in which case going with the arrow function seems appropriate.
shadowTarget = () => { };

@@ -533,0 +543,0 @@ }

export const { isArray: ArrayIsArray } = Array;
export const { assign, create: ObjectCreate, defineProperty: ObjectDefineProperty, getOwnPropertyDescriptors, freeze, seal, isSealed, isFrozen, } = Object;
export const { apply, construct, getPrototypeOf: ReflectGetPrototypeOf, setPrototypeOf: ReflectSetPrototypeOf, defineProperty: ReflectDefineProperty, isExtensible: ReflectIsExtensible, getOwnPropertyDescriptor: ReflectGetOwnPropertyDescriptor, ownKeys, preventExtensions: ReflectPreventExtensions, deleteProperty, get: ReflectGet, set: ReflectSet, } = Reflect;
export const { apply, construct, getPrototypeOf: ReflectGetPrototypeOf, setPrototypeOf: ReflectSetPrototypeOf, defineProperty: ReflectDefineProperty, isExtensible: ReflectIsExtensible, getOwnPropertyDescriptor: ReflectGetOwnPropertyDescriptor, ownKeys, preventExtensions: ReflectPreventExtensions, deleteProperty, has: ReflectHas, get: ReflectGet, set: ReflectSet, } = Reflect;
const ErrorCreate = unconstruct(Error);

@@ -5,0 +5,0 @@ const SetCreate = unconstruct(Set);

{
"name": "@caridy/sjs",
"version": "0.2.9",
"version": "0.2.10",
"description": "Experimental JS Library to create a sandboxed JavaScript environment in browsers and node",

@@ -13,3 +13,3 @@ "module": "lib/index.js",

"debug": "karma start karma.config.js --browsers Chrome",
"karma": "karma start karma.config.js --single-run --browsers Chrome"
"karma": "karma start karma.config.js --single-run --browsers ChromeHeadless,FirefoxHeadless"
},

@@ -37,2 +37,3 @@ "files": [

"karma-safari-launcher": "^1.0.0",
"puppeteer": "^3.1.0",
"rollup": "^1.21.3",

@@ -39,0 +40,0 @@ "ts-jest": "^24.2.0",

import { MembraneBroker } from './types';
export declare function blueProxyFactory(env: MembraneBroker): (red: any) => any;
export declare function blueProxyFactory(env: MembraneBroker): <T>(red: T) => T;

@@ -17,3 +17,3 @@ export declare const ArrayIsArray: (arg: any) => arg is any[];

}, seal: <T>(o: T) => T, isSealed: (o: any) => boolean, isFrozen: (o: any) => boolean;
export declare const apply: typeof Reflect.apply, construct: typeof Reflect.construct, ReflectGetPrototypeOf: typeof Reflect.getPrototypeOf, ReflectSetPrototypeOf: typeof Reflect.setPrototypeOf, ReflectDefineProperty: typeof Reflect.defineProperty, ReflectIsExtensible: typeof Reflect.isExtensible, ReflectGetOwnPropertyDescriptor: typeof Reflect.getOwnPropertyDescriptor, ownKeys: typeof Reflect.ownKeys, ReflectPreventExtensions: typeof Reflect.preventExtensions, deleteProperty: typeof Reflect.deleteProperty, ReflectGet: typeof Reflect.get, ReflectSet: typeof Reflect.set;
export declare const apply: typeof Reflect.apply, construct: typeof Reflect.construct, ReflectGetPrototypeOf: typeof Reflect.getPrototypeOf, ReflectSetPrototypeOf: typeof Reflect.setPrototypeOf, ReflectDefineProperty: typeof Reflect.defineProperty, ReflectIsExtensible: typeof Reflect.isExtensible, ReflectGetOwnPropertyDescriptor: typeof Reflect.getOwnPropertyDescriptor, ownKeys: typeof Reflect.ownKeys, ReflectPreventExtensions: typeof Reflect.preventExtensions, deleteProperty: typeof Reflect.deleteProperty, ReflectHas: typeof Reflect.has, ReflectGet: typeof Reflect.get, ReflectSet: typeof Reflect.set;
declare const ErrorCreate: Function;

@@ -20,0 +20,0 @@ declare const SetCreate: Function;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc