@@ -23,6 +23,14 @@ import * as dotenv from 'dotenv';
2323import { z } from 'zod/v4' ;
2424import { OpenRouter , ToolType } from '../src/index.js' ;
2525
26+ // Type declaration for ShadowRealm (TC39 Stage 3 proposal)
27+ // See: https://tc39.es/proposal-shadowrealm/
28+ declare class ShadowRealm {
29+ constructor ( ) ;
30+ evaluate ( sourceText : string ) : unknown ;
31+ importValue ( specifier : string , bindingName : string ) : Promise < unknown > ;
32+ }
33+
2634dotenv . config ( ) ;
2735
2836const client = new OpenRouter ( {
@@ -168,21 +176,28 @@ async function generatorToolExample() {
168176 *
169177 * ShadowRealm provides a secure, isolated JavaScript execution environment
170178 * that prevents access to the host realm's globals (no access to DOM, fetch,
171- * filesystem, etc.). This makes it safe for evaluating untrusted expressions.
179+ * filesystem, etc.). Combined with input validation, this makes it safe for
180+ * evaluating untrusted math expressions.
181+ *
182+ * Note: ShadowRealm isolates from host APIs but does not prevent DoS vectors
183+ * like infinite loops. For production use, consider additional safeguards.
172184 *
173185 * Browser support: Chrome 124+, Edge 124+, Firefox 128+, Safari 18+
174186 * Node.js support: Available behind --experimental-shadow-realm flag (v19+)
175187 * See: https://tc39.es/proposal-shadowrealm/
176188 */
177- async function safeEvaluateMath ( expression : string ) : Promise < number > {
178- // ShadowRealm is a TC39 Stage 3 proposal for isolated JavaScript execution
179- // It creates a separate realm with its own global object, preventing access
180- // to the host environment's APIs (no DOM, no Node.js APIs, no fetch, etc.)
189+ function safeEvaluateMath ( expression : string ) : number {
190+ // Only allow digits, whitespace, basic operators, decimal point, and parentheses
191+ if ( ! / ^ [ \d \s + \- * / . ( ) ] + $ / . test ( expression ) ) {
192+ throw new Error ( 'Expression contains invalid characters' ) ;
193+ }
194+
195+ // ShadowRealm creates a separate realm with its own global object, preventing
196+ // access to the host environment's APIs (no DOM, no Node.js APIs, no fetch, etc.)
181197 const realm = new ShadowRealm ( ) ;
182198
183- // The expression is evaluated in complete isolation - even if malicious code
184- // is injected, it cannot access anything outside the shadow realm
185- const result = await realm . evaluate ( `(${ expression } )` ) ;
199+ // The expression is evaluated in complete isolation
200+ const result = realm . evaluate ( expression ) ;
186201
187202 if ( typeof result !== 'number' || ! Number . isFinite ( result ) ) {
188203 throw new Error ( 'Expression did not evaluate to a finite number' ) ;
@@ -233,7 +248,7 @@ async function manualToolExample() {
233248
234249 // Safely evaluate the math expression using ShadowRealm
235250 try {
236- const _result = await safeEvaluateMath ( expression ) ;
251+ const _result = safeEvaluateMath ( expression ) ;
237252 } catch ( _error ) { }
238253 }
239254 }
0 commit comments