Mitigation Strategy: Object.freeze() and Object.seal() on Inherited Prototypes
Description:
- Identify Target Prototypes: Immediately after using
inherits(SubClass, BaseClass)
to establish the inheritance relationship, identify the prototypes you need to protect. This always includesSubClass.prototype
and usuallyBaseClass.prototype
. - Apply
Object.freeze()
: CallObject.freeze(SubClass.prototype)
andObject.freeze(BaseClass.prototype)
. This makes these prototypes non-writable, non-configurable, and non-extensible. This prevents any subsequent modification, including adding new properties or changing existing ones. - Consider
Object.seal()
(Less Secure): If you absolutely must allow modification of existing property values on the prototype (but not adding or deleting properties), useObject.seal()
instead ofObject.freeze()
. This is less secure, soObject.freeze()
is strongly preferred. - Critical Timing: The timing is crucial. Apply
Object.freeze()
orObject.seal()
immediately after theinherits
call and before any untrusted code or data can interact with instances ofSubClass
orBaseClass
.
Threats Mitigated:
- Prototype Pollution: (Severity: Critical) - This directly prevents prototype pollution on the prototypes that are frozen or sealed. Since
inherits
sets up the prototype chain, this mitigation is directly tied to its use. If an attacker tries to modify a frozen prototype, aTypeError
will be thrown (in strict mode).
Impact:
- Prototype Pollution: Risk is eliminated for the frozen/sealed prototypes. This is the most effective mitigation for prototype pollution specifically related to the inheritance chain established by
inherits
.
Currently Implemented:
- Implemented for the
BaseEntity
class and its direct subclasses (User
,Product
). The prototypes are frozen immediately after theinherits
call.
Missing Implementation:
- Missing for the
Comment
class, which inherits fromBaseEntity
indirectly. The intermediate class andComment.prototype
are not frozen.
Mitigation Strategy: Prevent Circular Inheritance (When Using inherits
Dynamically)
Description:
- Avoid Dynamic
inherits
: The best mitigation is to avoid usinginherits
dynamically based on untrusted input. If the inheritance structure is known at development time, define it statically. - Depth-Limited
inherits
(If Dynamic is Unavoidable): If you must useinherits
dynamically (which is a high-risk pattern), implement a strict depth limit. This means tracking how many timesinherits
has been called in a chain and throwing an error if a predefined limit is exceeded. This prevents an attacker from causing a stack overflow by providing input that creates a deeply nested or circular inheritance chain.- Maintain a counter (e.g., in a closure or a dedicated module) to track the inheritance depth.
- Increment the counter before each call to
inherits
. - Check if the counter exceeds a predefined maximum depth (e.g., 10).
- If the limit is exceeded, throw an error before calling
inherits
. - Decrement the counter after the
inherits
call (in afinally
block to ensure it's always decremented).
Threats Mitigated:
- Denial of Service (DoS) via Circular Inheritance: (Severity: Medium) - Prevents a specific type of DoS attack where an attacker could cause a stack overflow by crafting input that leads to a circular inheritance chain when
inherits
is used dynamically.
Impact:
- DoS: Risk is significantly reduced or eliminated, depending on the implementation of the depth limit.
Currently Implemented:
- The application's inheritance structure is defined statically;
inherits
is not used dynamically based on any external input.
Missing Implementation:
- No specific missing implementation, as the current design avoids dynamic use of
inherits
. If dynamic usage were introduced, the depth-limiting strategy would be essential.