@@ -594,3 +594,59 @@ ObjectDefineProperties(regex, {
594594});
595595console .log (RegExpPrototypeSymbolReplace (regex, ' foo' , ' a' )); // 'faa'
596596```
597+
598+ ### Defining object own properties
599+
600+ When defining property descriptor (to add or update an own property to a
601+ JavaScript object), be sure to always use a null-prototype object to avoid
602+ prototype pollution.
603+
604+ ``` js
605+ // User-land
606+ Object .prototype .get = function get () {};
607+
608+ // Core
609+ try {
610+ ObjectDefineProperty ({}, ' someProperty' , { value: 0 });
611+ } catch (err) {
612+ console .log (err); // TypeError: Invalid property descriptor.
613+ }
614+ ```
615+
616+ ``` js
617+ // User-land
618+ Object .prototype .get = function get () {};
619+
620+ // Core
621+ ObjectDefineProperty ({}, ' someProperty' , { __proto__: null , value: 0 });
622+ console .log (' no errors' ); // no errors.
623+ ```
624+
625+ Same applies when trying to modify an existing property, e.g. trying to make a
626+ read-only property enumerable:
627+
628+ ``` js
629+ // User-land
630+ Object .prototype .value = ' Unrelated user-provided data' ;
631+
632+ // Core
633+ class SomeClass {
634+ get readOnlyProperty () { return ' genuine data' ; }
635+ }
636+ ObjectDefineProperty (SomeClass .prototype , ' readOnlyProperty' , { enumerable: true });
637+ console .log (new SomeClass ().readOnlyProperty ); // Unrelated user-provided data
638+ ```
639+
640+ ``` js
641+ // User-land
642+ Object .prototype .value = ' Unrelated user-provided data' ;
643+
644+ // Core
645+ const kEnumerableProperty = { __proto__: null , enumerable: true };
646+ // In core, use const {kEnumerableProperty} = require('internal/util');
647+ class SomeClass {
648+ get readOnlyProperty () { return ' genuine data' ; }
649+ }
650+ ObjectDefineProperty (SomeClass .prototype , ' readOnlyProperty' , kEnumerableProperty);
651+ console .log (new SomeClass ().readOnlyProperty ); // genuine data
652+ ```
0 commit comments