Skip to content

dns: setServers has super-linear regex #20443

@davisjam

Description

@davisjam
  • Version
./out/Release/node  --version
v11.0.0-pre
  • Platform
(20:24:36) jamie@woody ~/Desktop/floss/node $ uname -a
Linux woody 4.13.0-38-generic #43~16.04.1-Ubuntu SMP Wed Mar 14 17:48:43 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
  • Subsystem

DNS

Problematic behavior

I recently scanned lib/ with my vuln-regex-detector tools and found a super-linear regex in lib/dns.js.

Here is a demo:

(20:20:05) jamie@woody ~ $ cat /tmp/node-dns-poc.js
#!/usr/bin/env node

const dns = require('dns');

const badServer = '['.repeat(100000);
console.log('Setting badServer');
try {
    dns.setServers([badServer]);
} catch (e) {}
console.log('Done');

(20:20:06) jamie@woody ~ $ time /tmp/node-dns-poc.js
Setting badServer
Done

real    0m6.330s <------- Ouch.
user    0m6.326s
sys    0m0.004s

The long execution time is due to this unsafe regex:

Resolver.prototype.setServers = setServers;
function setServers(servers) {
  // cache the original servers because in the event of an error setting the
  // servers cares won't have any servers available for resolution
  const orig = this._handle.getServers();
  const newSet = [];
  const IPv6RE = /\[(.*)\]/; <---------- Quadratic complexity

I submitted this via HackerOne for assessment and it was deemed not a likely threat vector. I agree with this assessment, since I really hope most users aren't letting clients set their DNS servers.

However, this is still a potential performance bug. I am working on a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions