@@ -63,6 +63,7 @@ const {
6363
6464const {
6565 codes : {
66+ ERR_ASSERTION ,
6667 ERR_BUFFER_OUT_OF_BOUNDS ,
6768 ERR_INVALID_ARG_TYPE ,
6869 ERR_INVALID_ARG_VALUE ,
@@ -109,8 +110,13 @@ let poolSize, poolOffset, allocPool;
109110// do not own the ArrayBuffer allocator. Zero fill is always on in that case.
110111const zeroFill = bindingZeroFill || [ 0 ] ;
111112
113+ // Hardening Buffer enables Buffer constructor runtime deprecation,
114+ // disables pooling, and enables mandratory zero-fill. This is more secure, but
115+ // has potential performance impact, depending on the usecase.
116+ let hardened = false ;
117+
112118function createUnsafeBuffer ( size ) {
113- zeroFill [ 0 ] = 0 ;
119+ zeroFill [ 0 ] = hardened ? 1 : 0 ;
114120 try {
115121 return new FastBuffer ( size ) ;
116122 } finally {
@@ -140,6 +146,15 @@ const bufferWarning = 'Buffer() is deprecated due to security and usability ' +
140146 'Buffer.allocUnsafe(), or Buffer.from() methods instead.' ;
141147
142148function showFlaggedDeprecation ( ) {
149+ if ( hardened ) {
150+ if ( bufferWarningAlreadyEmitted ) return ;
151+ process . emitWarning (
152+ bufferWarning + ' Buffer() will soon throw in hardened mode.' ,
153+ 'DeprecationWarning' , 'DEP0XXX' ) ;
154+ bufferWarningAlreadyEmitted = true ;
155+ return ;
156+ }
157+
143158 if ( bufferWarningAlreadyEmitted ||
144159 ++ nodeModulesCheckCounter > 10000 ||
145160 ( ! require ( 'internal/options' ) . getOptionValue ( '--pending-deprecation' ) &&
@@ -157,6 +172,26 @@ function showFlaggedDeprecation() {
157172 bufferWarningAlreadyEmitted = true ;
158173}
159174
175+ // Calling this method does not affect existing buffers, only new ones.
176+ Buffer . harden = function ( ) {
177+ if ( hardened ) return ;
178+ if ( isInsideNodeModules ( ) ) {
179+ throw new ERR_ASSERTION (
180+ 'Buffer.harden() should be called only from the top-level module. ' +
181+ 'Calling Buffer.harden() from dependencies is not supported.'
182+ ) ;
183+ }
184+ hardened = true ;
185+ Object . defineProperty ( Buffer , 'poolSize' , {
186+ enumerable : true ,
187+ get : ( ) => 0 ,
188+ set : ( ) => { } ,
189+ } ) ;
190+ Object . freeze ( Buffer ) ;
191+ Object . freeze ( Buffer . prototype ) ;
192+ Object . freeze ( module . exports ) ;
193+ } ;
194+
160195function toInteger ( n , defaultVal ) {
161196 n = + n ;
162197 if ( ! Number . isNaN ( n ) &&
@@ -365,7 +400,7 @@ function allocate(size) {
365400 if ( size <= 0 ) {
366401 return new FastBuffer ( ) ;
367402 }
368- if ( size < ( Buffer . poolSize >>> 1 ) ) {
403+ if ( size < ( Buffer . poolSize >>> 1 ) && ! hardened ) {
369404 if ( size > ( poolSize - poolOffset ) )
370405 createPool ( ) ;
371406 const b = new FastBuffer ( allocPool , poolOffset , size ) ;
0 commit comments