{"id":27979298,"url":"https://github.com/apeleghq/lot","last_synced_at":"2025-05-08T02:51:57.372Z","repository":{"id":163067550,"uuid":"637527573","full_name":"ApelegHQ/lot","owner":"ApelegHQ","description":"Sandbox for isolating ECMAScript code","archived":false,"fork":false,"pushed_at":"2025-03-23T06:27:49.000Z","size":770,"stargazers_count":29,"open_issues_count":3,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-05-08T02:51:49.469Z","etag":null,"topics":["browser","csp","deno","ecmascript","iframe","isolation","nodejs","sandbox","security","vm","webworker","worker"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@apeleghq/lot","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ApelegHQ.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["Exact-Realty"]}},"created_at":"2023-05-07T20:30:11.000Z","updated_at":"2025-04-07T11:05:17.000Z","dependencies_parsed_at":"2023-10-02T23:39:09.636Z","dependency_job_id":"b034128e-1a6b-49d9-a245-0311e4dff509","html_url":"https://github.com/ApelegHQ/lot","commit_stats":{"total_commits":134,"total_committers":2,"mean_commits":67.0,"dds":0.007462686567164201,"last_synced_commit":"2b34b1ad2f276064c33b3a17a4d0db164f38d867"},"previous_names":["exact-realty/lot","exact-realty/ecmascript-sandbox","apeleghq/lot"],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ApelegHQ%2Flot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ApelegHQ%2Flot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ApelegHQ%2Flot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ApelegHQ%2Flot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ApelegHQ","download_url":"https://codeload.github.com/ApelegHQ/lot/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252989941,"owners_count":21836666,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["browser","csp","deno","ecmascript","iframe","isolation","nodejs","sandbox","security","vm","webworker","worker"],"created_at":"2025-05-08T02:51:56.726Z","updated_at":"2025-05-08T02:51:57.366Z","avatar_url":"https://github.com/ApelegHQ.png","language":"TypeScript","funding_links":["https://github.com/sponsors/Exact-Realty"],"categories":[],"sub_categories":[],"readme":"# 🏜️ @apeleghq/lot 🏖️\r\n\r\n [![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=Exact-Realty_ecmascript-sandbox\u0026metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=Exact-Realty_ecmascript-sandbox)\r\n [![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=Exact-Realty_ecmascript-sandbox\u0026metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=Exact-Realty_ecmascript-sandbox)\r\n [![Bugs](https://sonarcloud.io/api/project_badges/measure?project=Exact-Realty_ecmascript-sandbox\u0026metric=bugs)](https://sonarcloud.io/summary/new_code?id=Exact-Realty_ecmascript-sandbox)\r\n [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=Exact-Realty_ecmascript-sandbox\u0026metric=security_rating)](https://sonarcloud.io/summary/new_code?id=Exact-Realty_ecmascript-sandbox)\r\n [![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=Exact-Realty_ecmascript-sandbox\u0026metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=Exact-Realty_ecmascript-sandbox)\r\n ![NPM Downloads](https://img.shields.io/npm/dw/@apeleghq/lot?style=flat-square)\r\n\r\nWelcome to `@apeleghq/lot` — the versatile ECMAScript sandbox\r\nyou've been looking for!\r\n\r\nOur sandbox supports multiple runtimes and allows for bidirectional\r\ncommunication, ensuring you have the flexibility and security to run your code\r\nin various environments. \r\n\r\n### 🚀 Features\r\n\r\n- Support for multiple runtimes:\r\n    * Browser (using an iframe with a worker inside or just an iframe)\r\n    * Dedicated worker (can run in the browser or with Deno)\r\n    * Node.js\r\n- Browser isolation using Content Security Policy (CSP)\r\n- Message passing using the `MessageEvent` class and event listeners for secure\r\n  communication using the structured clone algorithm\r\n- Hardening of global variables, including `Function` and `eval`, to prevent\r\n  direct code execution\r\n- Bidirectional communication, enabling the parent to call into the sandbox and\r\n  vice versa\r\n\r\n### 💻 Installation\r\n\r\nTo install, run:\r\n\r\n```sh\r\nnpm install \"@apeleghq/lot\"\r\n```\r\n\r\n```sh\r\nyarn add \"@apeleghq/lot\"\r\n```\r\n\r\n### 📚 Usage\r\n\r\nUsing our sandbox is easy! First, import the desired sandbox function, then call\r\nit with your code and any additional parameters. Here's an example using\r\n`browserSandbox`:\r\n\r\n```js\r\nimport { browserSandbox } from '@apeleghq/lot';\r\n\r\nconst sandbox = await browserSandbox(`\r\n  /* sandboxed code*/;\r\n  module.exports={hello:(name)=\u003e\\`Hello, ${name}!\\`}; \r\n`);\r\nconst result = await sandbox('hello', 'World');\r\nconsole.log(result); // Output: \"Hello, World!\"\r\n```\r\n\r\nOur sandbox provides two interfaces:\r\n\r\n```typescript\r\nexport interface IPerformTask {\r\n  (op: string, ...args: unknown[]): Promise\u003cunknown\u003e;\r\n}\r\n\r\nexport interface ISandbox {\r\n  (\r\n    script: string,\r\n    allowedGlobals?: string[] | undefined | null,\r\n    externalMethods?: Record\u003cstring, unknown\u003e | null,\r\n    abort?: AbortSignal,\r\n    options?: TSandboxOptions,\r\n  ): Promise\u003cIPerformTask\u003e;\r\n}\r\n\r\nexport type TSandboxOptions = {\r\n\tbrowserRequireWorker?: boolean;\r\n\tworkerType?: WorkerOptions['type'];\r\n}\r\n```\r\n\r\n`ISandbox` is an interface for the `browserSandbox`, `nodejsSandbox` and\r\n`workerSandbox` functions. It takes a string `script` representing the code to\r\nbe sandboxed, an optional array of allowed global variables `allowedGlobals`, an\r\noptional object of external methods `externalMethods`, and an optional\r\nAbortSignal `abort`. It returns a promise that resolves to an implementation of\r\n`IPerformTask`.\r\n\r\n`IPerformTask` is an interface for the result of the various sandbox function.\r\nIt takes a string `op` representing the function name and a list of arguments,\r\nand it returns a promise that resolves to the result of the task.\r\n\r\nThe script to be sandboxed, `script`, must expose an object in `module.exports`\r\nwith a dictionary of the different functions that can be called from outside.\r\nThe type of `module.exports` is `Record\u003cstring, typeof Function.prototype\u003e`.\r\n\r\n### 🤝 Contributing\r\n\r\nWe welcome any contributions and feedback! Please feel free to submit pull\r\nrequests, bug reports or feature requests to our GitHub repository.\r\n\r\n### ❗️ Disclaimer\r\n\r\n⚠️ Please note that even though we have implemented several security measures,\r\nit's important to understand that sandbox escapes are always a possibility.\r\nRunning untrusted code in Node.js is especially risky due to its inherent\r\nplatform limitations. Our sandbox relies on `node:vm`, which was not designed\r\nfor running untrusted code.\r\n\r\nTo mitigate these risks, we strongly recommend taking a security-in-depth\r\napproach and relying on additional security mechanisms such as process\r\nisolation, `seccomp(2)`, `pledge(2)`, `ProcessSystemCallDisablePolicy` and\r\nSELinux, to name a few. Where feasible, we also recommend static code analysis\r\nand code reviews, as well as adequate auditing and logging.\r\n\r\nNote that the sandbox does not prevent denial-of-service attacks such as\r\ninfinite loops or memory exhaustion. It's important to take appropriate measures\r\nto prevent these types of attacks, such as setting resource limits or using\r\ntimeouts.\r\n\r\n### 📜 License\r\n\r\nThis project is released under the ISC license. Check out the `LICENSE` file for\r\nmore information.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapeleghq%2Flot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapeleghq%2Flot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapeleghq%2Flot/lists"}