@@ -40,6 +40,32 @@ const BLOCKED_PROTO_PROPERTIES = new Set([
4040 '__lookupSetter__'
4141] ) ;
4242
43+ // Every function-constructor variant, along with the invocation helpers which
44+ // could otherwise reach them indirectly, e.g., `Function.call(0, 'code')()`
45+ /** @type {WeakSet<object> } */
46+ const BLOCKED_FUNCTIONS = new WeakSet ( [
47+ Function ,
48+ // eslint-disable-next-line no-empty-function -- Only need the constructor
49+ function * ( ) { } . constructor ,
50+ // eslint-disable-next-line no-empty-function -- Only need the constructor
51+ async function ( ) { } . constructor ,
52+ // eslint-disable-next-line no-empty-function -- Only need the constructor
53+ async function * ( ) { } . constructor ,
54+ Function . prototype . call ,
55+ Function . prototype . apply ,
56+ Function . prototype . bind ,
57+ Reflect . apply ,
58+ Reflect . construct
59+ ] ) ;
60+
61+ /**
62+ * @param {UnknownResult } value
63+ * @returns {boolean }
64+ */
65+ const isBlockedFunction = ( value ) => {
66+ return typeof value === 'function' && BLOCKED_FUNCTIONS . has ( value ) ;
67+ } ;
68+
4369/**
4470 * @typedef {Record<
4571 * string,
@@ -256,7 +282,10 @@ const SafeEval = {
256282 ) ;
257283 }
258284 const result = /** @type {Record<string, UnknownResult> } */ ( obj ) [ prop ] ;
259- if ( typeof result === 'function' && result !== Function ) {
285+ if ( isBlockedFunction ( result ) ) {
286+ throw new TypeError ( 'Function constructor is disabled' ) ;
287+ }
288+ if ( typeof result === 'function' ) {
260289 return result . bind ( obj ) ; // arrow functions aren't affected by bind.
261290 }
262291 return result ;
@@ -297,7 +326,10 @@ const SafeEval = {
297326 evalCallExpression ( ast , subs ) {
298327 const args = ast . arguments . map ( ( arg ) => SafeEval . evalAst ( arg , subs ) ) ;
299328 const func = SafeEval . evalAst ( ast . callee , subs ) ;
300- if ( func === Function ) {
329+ if (
330+ isBlockedFunction ( func ) ||
331+ args . some ( ( arg ) => isBlockedFunction ( arg ) )
332+ ) {
301333 throw new Error ( 'Function constructor is disabled' ) ;
302334 }
303335 return ( /** @type {(...args: AnyParameter[]) => UnknownResult } */ (
0 commit comments