diff --git a/lib/dns.js b/lib/dns.js index 1301cbd2ce9..110a19298ea 100644 --- a/lib/dns.js +++ b/lib/dns.js @@ -83,7 +83,7 @@ const { validateNumber, validateOneOf, validatePort, - validateString, + validateStringWithoutNullBytes, } = require('internal/validators'); const { @@ -147,7 +147,7 @@ function lookup(hostname, options, callback) { // Parse arguments if (hostname) { - validateString(hostname, 'hostname'); + validateStringWithoutNullBytes(hostname, 'hostname'); } if (typeof options === 'function') { diff --git a/lib/internal/dns/promises.js b/lib/internal/dns/promises.js index 57943e1f658..0b6914500b2 100644 --- a/lib/internal/dns/promises.js +++ b/lib/internal/dns/promises.js @@ -70,6 +70,7 @@ const { validateOneOf, validatePort, validateString, + validateStringWithoutNullBytes, } = require('internal/validators'); const kPerfHooksDnsLookupContext = Symbol('kPerfHooksDnsLookupContext'); @@ -200,7 +201,7 @@ function lookup(hostname, options) { // Parse arguments if (hostname) { - validateString(hostname, 'hostname'); + validateStringWithoutNullBytes(hostname, 'hostname'); } if (typeof options === 'number') { diff --git a/lib/internal/validators.js b/lib/internal/validators.js index db36251e56f..668e17c13da 100644 --- a/lib/internal/validators.js +++ b/lib/internal/validators.js @@ -16,6 +16,7 @@ const { ObjectPrototypeHasOwnProperty, RegExpPrototypeExec, String, + StringPrototypeIncludes, StringPrototypeToUpperCase, StringPrototypeTrim, } = primordials; @@ -166,6 +167,14 @@ const validateString = hideStackFrames((value, name) => { throw new ERR_INVALID_ARG_TYPE(name, 'string', value); }); +/** @type {validateString} */ +const validateStringWithoutNullBytes = hideStackFrames((value, name) => { + validateString(value, name); + if (StringPrototypeIncludes(value, '\u0000')) { + throw new ERR_INVALID_ARG_VALUE(name, value, 'must be a string without null bytes'); + } +}); + /** * @callback validateNumber * @param {*} value @@ -678,6 +687,7 @@ module.exports = { validatePort, validateSignalName, validateString, + validateStringWithoutNullBytes, validateUint32, validateUndefined, validateUnion, diff --git a/lib/net.js b/lib/net.js index ee4bc9943e4..6acce9e7169 100644 --- a/lib/net.js +++ b/lib/net.js @@ -137,6 +137,7 @@ const { validateNumber, validatePort, validateString, + validateStringWithoutNullBytes, } = require('internal/validators'); const kLastWriteQueueSize = Symbol('lastWriteQueueSize'); const { getOptionValue } = require('internal/options'); @@ -1389,7 +1390,7 @@ function lookupAndConnect(self, options) { const host = options.host || 'localhost'; let { port, autoSelectFamilyAttemptTimeout, autoSelectFamily } = options; - validateString(host, 'options.host'); + validateStringWithoutNullBytes(host, 'options.host'); if (localAddress && !isIP(localAddress)) { throw new ERR_INVALID_IP_ADDRESS(localAddress); diff --git a/test/parallel/test-dns-lookup.js b/test/parallel/test-dns-lookup.js index 8d1526903d7..3aa7b5a4494 100644 --- a/test/parallel/test-dns-lookup.js +++ b/test/parallel/test-dns-lookup.js @@ -23,6 +23,17 @@ const dnsPromises = dns.promises; assert.throws(() => dnsPromises.lookup(1, {}), err); } +{ + const err = { + code: 'ERR_INVALID_ARG_VALUE', + name: 'TypeError', + message: /The argument 'hostname' must be a string without null bytes\./, + }; + + assert.throws(() => dns.lookup('127.0.0.1\u0000.allowed.example', {}), err); + assert.throws(() => dnsPromises.lookup('127.0.0.1\u0000.allowed.example', {}), err); +} + // This also verifies different expectWarning notations. common.expectWarning({ // For 'internal/test/binding' module. diff --git a/test/parallel/test-net-connect-options-invalid.js b/test/parallel/test-net-connect-options-invalid.js index 3c748b15161..fadbedf3594 100644 --- a/test/parallel/test-net-connect-options-invalid.js +++ b/test/parallel/test-net-connect-options-invalid.js @@ -37,3 +37,16 @@ const net = require('net'); name: 'TypeError', }); } + +{ + assert.throws(() => { + net.createConnection({ + host: '127.0.0.1\u0000.allowed.example', + port: 8080, + }); + }, { + code: 'ERR_INVALID_ARG_VALUE', + name: 'TypeError', + message: /The property 'options\.host' must be a string without null bytes\./, + }); +}