Skip to content

Prototype pollution protection breaks decorator functionality #5131

@holgerkoser

Description

@holgerkoser

I'm trying to implement protection against prototype pollution in my SinglePageApp that uses xterm.js. I'm using the following code at initialization:

[
  Object,
  Object.prototype,
  Function,
  Function.prototype,
  Array,
  Array.prototype,
  String,
  String.prototype,
  Number,
  Number.prototype,
  Boolean,
  Boolean.prototype,
].forEach(Object.freeze)

However, this causes an error when xterm.js tries to create a decorator:

TypeError: Cannot assign to read only property 'toString' of function 'function(e4, t3, n) {
            if (3 !== arguments.length) throw new Error("@IServiceName-decorator can only...<omitted>... }'
    at t2.createDecorator (@xterm_xterm.js?v=0e3f3914:5833:29)

The error seems to originate from this line in ServiceRegistry.ts:
https://github.com/xtermjs/xterm.js/blob/master/src/common/services/ServiceRegistry.ts#L36
It appears that the decorator creation is trying to modify Function.prototype, which is no longer allowed due to the Object.freeze() call.

To reproduce the problem more simply:

Object.freeze(Function.prototype)
const decorator = function () {}
decorator.toString = () => 1

This returns the same error.

decorator.toString = () => 1
                   ^

TypeError: Cannot assign to read only property 'toString' of function 'function () {}'

Proposed solution:
Instead of using toString to store the id, consider using a different property name (e.g., decorator._id = 1) or a Symbol. This would allow the decorator to function without modifying Function.prototype.
Is it possible to implement the decorator functionality using one of these alternative approaches? This would allow users to implement stronger prototype pollution protections without breaking xterm.js functionality.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions