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

feat: SES lockdown v1.0.0 (Android Hermes) #8161

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import { AppRegistry, LogBox } from 'react-native';
import Root from './app/components/Views/Root';
import { name } from './app.json';

// Object.defineProperty(Object.prototype, 'test', { value: true });

// List of warnings that we're ignoring
LogBox.ignoreLogs([
'{}',
Expand Down
267 changes: 116 additions & 151 deletions ses.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -7663,7 +7663,7 @@ function tameErrorConstructor(
})()
,
// === functors[38] ===
({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, importMeta: $h‍____meta, }) => (function () { let ReferenceError,TypeError,Map,Set,arrayJoin,arrayMap,arrayPush,create,freeze,mapGet,mapHas,mapSet,setAdd,promiseCatch,promiseThen,values,weakmapGet,assert;$h‍_imports([["./commons.js", [["ReferenceError", [$h‍_a => (ReferenceError = $h‍_a)]],["TypeError", [$h‍_a => (TypeError = $h‍_a)]],["Map", [$h‍_a => (Map = $h‍_a)]],["Set", [$h‍_a => (Set = $h‍_a)]],["arrayJoin", [$h‍_a => (arrayJoin = $h‍_a)]],["arrayMap", [$h‍_a => (arrayMap = $h‍_a)]],["arrayPush", [$h‍_a => (arrayPush = $h‍_a)]],["create", [$h‍_a => (create = $h‍_a)]],["freeze", [$h‍_a => (freeze = $h‍_a)]],["mapGet", [$h‍_a => (mapGet = $h‍_a)]],["mapHas", [$h‍_a => (mapHas = $h‍_a)]],["mapSet", [$h‍_a => (mapSet = $h‍_a)]],["setAdd", [$h‍_a => (setAdd = $h‍_a)]],["promiseCatch", [$h‍_a => (promiseCatch = $h‍_a)]],["promiseThen", [$h‍_a => (promiseThen = $h‍_a)]],["values", [$h‍_a => (values = $h‍_a)]],["weakmapGet", [$h‍_a => (weakmapGet = $h‍_a)]]]],["./error/assert.js", [["assert", [$h‍_a => (assert = $h‍_a)]]]]]);
({ imports: $h‍_imports, liveVar: $h‍_live, onceVar: $h‍_once, importMeta: $h‍____meta, }) => (function () { let ReferenceError,TypeError,Map,Set,arrayJoin,arrayMap,arrayPush,create,freeze,mapGet,mapHas,mapSet,setAdd,promiseThen,values,weakmapGet,assert;$h‍_imports([["./commons.js", [["ReferenceError", [$h‍_a => (ReferenceError = $h‍_a)]],["TypeError", [$h‍_a => (TypeError = $h‍_a)]],["Map", [$h‍_a => (Map = $h‍_a)]],["Set", [$h‍_a => (Set = $h‍_a)]],["arrayJoin", [$h‍_a => (arrayJoin = $h‍_a)]],["arrayMap", [$h‍_a => (arrayMap = $h‍_a)]],["arrayPush", [$h‍_a => (arrayPush = $h‍_a)]],["create", [$h‍_a => (create = $h‍_a)]],["freeze", [$h‍_a => (freeze = $h‍_a)]],["mapGet", [$h‍_a => (mapGet = $h‍_a)]],["mapHas", [$h‍_a => (mapHas = $h‍_a)]],["mapSet", [$h‍_a => (mapSet = $h‍_a)]],["setAdd", [$h‍_a => (setAdd = $h‍_a)]],["promiseThen", [$h‍_a => (promiseThen = $h‍_a)]],["values", [$h‍_a => (values = $h‍_a)]],["weakmapGet", [$h‍_a => (weakmapGet = $h‍_a)]]]],["./error/assert.js", [["assert", [$h‍_a => (assert = $h‍_a)]]]]]);

Copy link
Member Author

@leotm leotm Dec 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only promiseCatch removed in refactor



Expand Down Expand Up @@ -7775,7 +7775,7 @@ const loadRecord= (
return moduleRecord;
};

const loadWithoutErrorAnnotation= async(
const loadWithoutErrorAnnotation= (
compartmentPrivateFields,
moduleAliases,
compartment,
Expand Down Expand Up @@ -7815,102 +7815,104 @@ const loadWithoutErrorAnnotation= async(
}
// Behold: recursion.
// eslint-disable-next-line no-use-before-define
const aliasRecord= await memoizedLoadWithErrorAnnotation(
return memoizedLoadWithErrorAnnotation(
compartmentPrivateFields,
moduleAliases,
alias.compartment,
alias.specifier,
pendingJobs,
moduleLoads,
errors);

mapSet(moduleRecords, moduleSpecifier, aliasRecord);
return aliasRecord;
errors).
then((aliasRecord)=>{
mapSet(moduleRecords, moduleSpecifier, aliasRecord);
return aliasRecord;
});
}

if( mapHas(moduleRecords, moduleSpecifier)) {
return mapGet(moduleRecords, moduleSpecifier);
return Promise.resolve(mapGet(moduleRecords, moduleSpecifier));
}

const staticModuleRecord= await importHook(moduleSpecifier);

if( staticModuleRecord=== null|| typeof staticModuleRecord!== 'object') {
Fail `importHook must return a promise for an object, for module ${q(
moduleSpecifier)
} in compartment ${q(compartment.name)}`;
}
return importHook(moduleSpecifier).then((staticModuleRecord)=>{
if( staticModuleRecord=== null|| typeof staticModuleRecord!== 'object') {
Fail `importHook must return a promise for an object, for module ${q(
moduleSpecifier)
} in compartment ${q(compartment.name)}`;
}

// check if record is a RedirectStaticModuleInterface
if( staticModuleRecord.specifier!== undefined) {
// check if this redirect with an explicit record
if( staticModuleRecord.record!== undefined) {
// ensure expected record shape
if( staticModuleRecord.compartment!== undefined) {
throw TypeError(
'Cannot redirect to an explicit record with a specified compartment');
// check if record is a RedirectStaticModuleInterface
if( staticModuleRecord.specifier!== undefined) {
// check if this redirect with an explicit record
if( staticModuleRecord.record!== undefined) {
// ensure expected record shape
if( staticModuleRecord.compartment!== undefined) {
throw TypeError(
'Cannot redirect to an explicit record with a specified compartment');

}
const {
compartment: aliasCompartment= compartment,
specifier: aliasSpecifier= moduleSpecifier,
record: aliasModuleRecord,
importMeta}=
staticModuleRecord;

const aliasRecord= loadRecord(
compartmentPrivateFields,
moduleAliases,
aliasCompartment,
aliasSpecifier,
aliasModuleRecord,
pendingJobs,
moduleLoads,
errors,
importMeta);

mapSet(moduleRecords, moduleSpecifier, aliasRecord);
return aliasRecord;
}
const {
compartment: aliasCompartment= compartment,
specifier: aliasSpecifier= moduleSpecifier,
record: aliasModuleRecord,
importMeta}=
staticModuleRecord;

const aliasRecord= loadRecord(
compartmentPrivateFields,
moduleAliases,
aliasCompartment,
aliasSpecifier,
aliasModuleRecord,
pendingJobs,
moduleLoads,
errors,
importMeta);

mapSet(moduleRecords, moduleSpecifier, aliasRecord);
return aliasRecord;
}

// check if this redirect with an explicit compartment
if( staticModuleRecord.compartment!== undefined) {
// ensure expected record shape
if( staticModuleRecord.importMeta!== undefined) {
throw TypeError(
'Cannot redirect to an implicit record with a specified importMeta');
// check if this redirect with an explicit compartment
if( staticModuleRecord.compartment!== undefined) {
// ensure expected record shape
if( staticModuleRecord.importMeta!== undefined) {
throw TypeError(
'Cannot redirect to an implicit record with a specified importMeta');

}
// Behold: recursion.
// eslint-disable-next-line no-use-before-define
return memoizedLoadWithErrorAnnotation(
compartmentPrivateFields,
moduleAliases,
staticModuleRecord.compartment,
staticModuleRecord.specifier,
pendingJobs,
moduleLoads,
errors).
then((aliasRecord)=>{
mapSet(moduleRecords, moduleSpecifier, aliasRecord);
return aliasRecord;
});
}
// Behold: recursion.
// eslint-disable-next-line no-use-before-define
const aliasRecord= await memoizedLoadWithErrorAnnotation(
compartmentPrivateFields,
moduleAliases,
staticModuleRecord.compartment,
staticModuleRecord.specifier,
pendingJobs,
moduleLoads,
errors);

mapSet(moduleRecords, moduleSpecifier, aliasRecord);
return aliasRecord;
throw TypeError('Unnexpected RedirectStaticModuleInterface record shape');
}

throw TypeError('Unnexpected RedirectStaticModuleInterface record shape');
}

return loadRecord(
compartmentPrivateFields,
moduleAliases,
compartment,
moduleSpecifier,
staticModuleRecord,
pendingJobs,
moduleLoads,
errors);
return loadRecord(
compartmentPrivateFields,
moduleAliases,
compartment,
moduleSpecifier,
staticModuleRecord,
pendingJobs,
moduleLoads,
errors);

});
};

const memoizedLoadWithErrorAnnotation= async(
const memoizedLoadWithErrorAnnotation= (
compartmentPrivateFields,
moduleAliases,
compartment,
Expand All @@ -7932,30 +7934,28 @@ const memoizedLoadWithErrorAnnotation= async(
}
let moduleLoading= mapGet(compartmentLoading, moduleSpecifier);
if( moduleLoading!== undefined) {
return moduleLoading;
return Promise.resolve(moduleLoading);
}

moduleLoading= promiseCatch(
loadWithoutErrorAnnotation(
compartmentPrivateFields,
moduleAliases,
compartment,
moduleSpecifier,
pendingJobs,
moduleLoads,
errors),

(error)=>{
// eslint-disable-next-line @endo/no-polymorphic-call
assert.note(
error,
d `${error.message}, loading ${q(moduleSpecifier)} in compartment ${q(
compartmentName)
}`);
moduleLoading= loadWithoutErrorAnnotation(
compartmentPrivateFields,
moduleAliases,
compartment,
moduleSpecifier,
pendingJobs,
moduleLoads,
errors).

throw error;
});
catch((error)=>{
// eslint-disable-next-line @endo/no-polymorphic-call
assert.note(
error,
d `${error.message}, loading ${q(moduleSpecifier)} in compartment ${q(
compartmentName)
}`);

throw error;
});

mapSet(compartmentLoading, moduleSpecifier, moduleLoading);

Expand All @@ -7969,7 +7969,7 @@ const memoizedLoadWithErrorAnnotation= async(
* compartment and the specifier of the module within its own compartment.
* This graph is then ready to be synchronously linked and executed.
*/
const load= async(
const load= (
compartmentPrivateFields,
moduleAliases,
compartment,
Expand Down Expand Up @@ -8009,7 +8009,7 @@ const load= async(
// `errors` accumulator.
for( const job of pendingJobs) {
// eslint-disable-next-line no-await-in-loop
await job;
job;
}

// Throw an aggregate error if there were any errors.
Expand Down Expand Up @@ -9361,34 +9361,9 @@ const getAnonymousIntrinsics= ()=> {

const Generator= GeneratorFunction.prototype;

// 25.3.1 The AsyncGeneratorFunction Constructor

// eslint-disable-next-line no-empty-function
async function* AsyncGeneratorFunctionInstance() { }
const AsyncGeneratorFunction= getConstructorOf(
AsyncGeneratorFunctionInstance);


// 25.3.2.2 AsyncGeneratorFunction.prototype
const AsyncGenerator= AsyncGeneratorFunction.prototype;
// 25.5.1 Properties of the AsyncGenerator Prototype Object
const AsyncGeneratorPrototype= AsyncGenerator.prototype;
const AsyncIteratorPrototype= getPrototypeOf(AsyncGeneratorPrototype);

// 25.7.1 The AsyncFunction Constructor

// eslint-disable-next-line no-empty-function
async function AsyncFunctionInstance() { }
const AsyncFunction= getConstructorOf(AsyncFunctionInstance);

const intrinsics= {
'%InertFunction%': InertFunction,
'%ArrayIteratorPrototype%': ArrayIteratorPrototype,
'%InertAsyncFunction%': AsyncFunction,
'%AsyncGenerator%': AsyncGenerator,
'%InertAsyncGeneratorFunction%': AsyncGeneratorFunction,
'%AsyncGeneratorPrototype%': AsyncGeneratorPrototype,
'%AsyncIteratorPrototype%': AsyncIteratorPrototype,
'%Generator%': Generator,
'%InertGeneratorFunction%': GeneratorFunction,
'%IteratorPrototype%': IteratorPrototype,
Expand All @@ -9412,17 +9387,6 @@ const getAnonymousIntrinsics= ()=> {

}

if( globalThis.AsyncIterator) {
intrinsics['%AsyncIteratorHelperPrototype%']= getPrototypeOf(
// eslint-disable-next-line @endo/no-polymorphic-call
globalThis.AsyncIterator.from([]).take(0));

intrinsics['%WrapForValidAsyncIteratorPrototype%']= getPrototypeOf(
// eslint-disable-next-line @endo/no-polymorphic-call
globalThis.AsyncIterator.from({ next() { }}));

}

return intrinsics;
};$h‍_once.getAnonymousIntrinsics(getAnonymousIntrinsics);
})()
Expand Down Expand Up @@ -9739,7 +9703,7 @@ const repairIntrinsics= (options= {})=> {
// trace retained:
priorRepairIntrinsics.stack;

assertDirectEvalAvailable();
// assertDirectEvalAvailable();

/**
* Because of packagers and bundlers, etc, multiple invocations of lockdown
Expand Down Expand Up @@ -9802,12 +9766,12 @@ const repairIntrinsics= (options= {})=> {
addIntrinsics(tameDateConstructor(dateTaming));
addIntrinsics(tameErrorConstructor(errorTaming, stackFiltering));
addIntrinsics(tameMathObject(mathTaming));
addIntrinsics(tameRegExpConstructor(regExpTaming));
addIntrinsics(tameSymbolConstructor());
// addIntrinsics(tameRegExpConstructor(regExpTaming));
// addIntrinsics(tameSymbolConstructor());

addIntrinsics(getAnonymousIntrinsics());

completePrototypes();
// completePrototypes();

const intrinsics= finalIntrinsics();

Expand Down Expand Up @@ -9852,7 +9816,7 @@ const repairIntrinsics= (options= {})=> {
// Remove non-standard properties.
// All remaining function encountered during whitelisting are
// branded as honorary native functions.
whitelistIntrinsics(intrinsics, markVirtualizedNativeFunction);
// whitelistIntrinsics(intrinsics, markVirtualizedNativeFunction);

// Initialize the powerful initial global, i.e., the global of the
// start compartment, from the intrinsics.
Expand Down Expand Up @@ -9918,19 +9882,20 @@ const repairIntrinsics= (options= {})=> {

// Finally register and optionally freeze all the intrinsics. This
// must be the operation that modifies the intrinsics.
tamedHarden(intrinsics);

// Harden evaluators
tamedHarden(globalThis.Function);
tamedHarden(globalThis.eval);
// @ts-ignore Compartment does exist on globalThis
tamedHarden(globalThis.Compartment);

// Harden Symbol and properties for initialGlobalPropertyNames in the host realm
tamedHarden(globalThis.Symbol);
for( const prop of getOwnPropertyNames(initialGlobalPropertyNames)) {
tamedHarden(globalThis[prop]);
}
// tamedHarden(intrinsics); // Causing app infinite loading

// // Harden evaluators
// Taming globals below causes: Uncaught TypeError: Cannot assign to read-only property 'toString', js engine: hermes
// tamedHarden(globalThis.Function);
// tamedHarden(globalThis.eval); // Still needed for Hermes?
// // @ts-ignore Compartment does exist on globalThis
// tamedHarden(globalThis.Compartment); // Still needed for Hermes?

// // Harden Symbol and properties for initialGlobalPropertyNames in the host realm
// tamedHarden(globalThis.Symbol);
// for( const prop of getOwnPropertyNames(initialGlobalPropertyNames)) {
// tamedHarden(globalThis[prop]); // Uncaught TypeError: Cannot assign to read-only property 'constructor', js engine: hermes
// }

return tamedHarden;
};
Expand Down
Loading