VYPR
Medium severityNVD Advisory· Published Apr 7, 2025· Updated Apr 15, 2026

CVE-2025-32014

CVE-2025-32014

Description

estree-util-value-to-estree converts a JavaScript value to an ESTree expression. When generating an ESTree from a value with a property named __proto__, valueToEstree would generate an object that specifies a prototype instead. This vulnerability is fixed in 3.3.3.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
estree-util-value-to-estreenpm
< 3.3.33.3.3

Patches

2
d0c394fbc64b

Fix __proto__ property emit

3 files changed · +77 15
  • fixtures/object-proto-property/input.js+13 0 added
    @@ -0,0 +1,13 @@
    +// Used as input
    +// { preserveReferences: true }
    +export default {
    +  ['__proto__']: {}
    +}
    +
    +// -------------------------------------------------------------------------------------------------
    +
    +// Default output
    +// { preserveReferences: false }
    +const withoutPreserveReferences = {
    +  ['__proto__']: {}
    +}
    
  • fixtures/object-proto-property-recursive/input.js+27 0 added
    @@ -0,0 +1,27 @@
    +// Used as input
    +// { preserveReferences: true }
    +export default ((
    +  $1 = {
    +    name: '$1'
    +  },
    +  $0 = {
    +    ['__proto__']: $1,
    +    name: '$0'
    +  }
    +) => (
    +  Object.defineProperties($1, {
    +    ['__proto__']: {
    +      value: $0,
    +      configurable: true,
    +      enumerable: true,
    +      writable: true
    +    }
    +  }),
    +  $0
    +))()
    +
    +// -------------------------------------------------------------------------------------------------
    +
    +// Default output
    +// { preserveReferences: false }
    +// Recursive references are not supported without preserveReferences
    
  • src/estree-util-value-to-estree.ts+37 15 modified
    @@ -326,15 +326,15 @@ function symbolToEstree(symbol: symbol): Expression {
      *   The ESTree properry node.
      */
     function property(key: string | symbol, value: Expression): Property {
    -  const computed = typeof key !== 'string'
    +  const isString = typeof key === 'string'
     
       return {
         type: 'Property',
         method: false,
         shorthand: false,
    -    computed,
    +    computed: key === '__proto__' || !isString,
         kind: 'init',
    -    key: computed ? symbolToEstree(key) : literal(key),
    +    key: isString ? literal(key) : symbolToEstree(key),
         value
       }
     }
    @@ -794,7 +794,15 @@ export function valueToEstree(value: unknown, options: Options = {}): Expression
     
         const properties: Property[] = []
         if (Object.getPrototypeOf(val) == null) {
    -      properties.push(property('__proto__', literal(null)))
    +      properties.push({
    +        type: 'Property',
    +        method: false,
    +        shorthand: false,
    +        computed: false,
    +        kind: 'init',
    +        key: identifier('__proto__'),
    +        value: literal(null)
    +      })
         }
     
         const object = val as Record<string | symbol, unknown>
    @@ -826,17 +834,31 @@ export function valueToEstree(value: unknown, options: Options = {}): Expression
             childContext &&
             namedContexts.indexOf(childContext) >= namedContexts.indexOf(context)
           ) {
    -        childContext.assignment = {
    -          type: 'AssignmentExpression',
    -          operator: '=',
    -          left: {
    -            type: 'MemberExpression',
    -            computed: true,
    -            optional: false,
    -            object: identifier(context.name!),
    -            property: generate(key)
    -          },
    -          right: childContext.assignment || generate(child)
    +        if (key === '__proto__') {
    +          propertyDescriptors.push(
    +            property(key, {
    +              type: 'ObjectExpression',
    +              properties: [
    +                property('value', generate(child)),
    +                property('configurable', literal(true)),
    +                property('enumerable', literal(true)),
    +                property('writable', literal(true))
    +              ]
    +            })
    +          )
    +        } else {
    +          childContext.assignment = {
    +            type: 'AssignmentExpression',
    +            operator: '=',
    +            left: {
    +              type: 'MemberExpression',
    +              computed: true,
    +              optional: false,
    +              object: identifier(context.name!),
    +              property: generate(key)
    +            },
    +            right: childContext.assignment || generate(child)
    +          }
             }
           } else {
             properties.push(property(key, generate(child)))
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.