Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent IP leak. WebRTC #4149

Closed
TomasKavaliauskas opened this issue Mar 10, 2019 · 14 comments
Closed

Prevent IP leak. WebRTC #4149

TomasKavaliauskas opened this issue Mar 10, 2019 · 14 comments

Comments

@TomasKavaliauskas
Copy link

I have installed TOR in my server, and using it as proxy server for puppeteer. It is running on port 9060

// Dependencies
const puppeteer = require('puppeteer');
const fs = require('fs');
const request = require('request');

const USER_AGENTS = [
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0'
];

const SS_PATH = '/var/www/storage/app/public/images/';

// Variables
let page = null;

let response = {success: true, screenshot: null, message: null};

async function register()
{
    
    try 
    {
        
        const extensionPath = 'extensions/webrtc';

        await puppeteer.launch({ userDataDir: './cache', slowMo: 10, headless: true, args:[ 
            `--disable-extensions-except=${extensionPath}`,
            `--load-extension=${extensionPath}`,
            '--lang=en-US,en',
            '--no-sandbox',
            '--disable-setuid-sandbox',
            '--disable-infobars',
            '--proxy-server=socks5://127.0.0.1:9060'],
            ignoreHTTPSErrors: true, dumpio: false 
        }).then(async browser => {
            
            await createTab(browser);
            
            await page.evaluateOnNewDocument(() => {
                chrome.privacy.network.webRTCIPHandlingPolicy.set({
                    value: "default_public_interface_only" 
                });
            });

            await page.goto('https://www.expressvpn.com/webrtc-leak-test');

            await page.waitFor(20000);

            let screenshotName5 = `ipleak${Date.now()}.jpg`;
            response.screenshot = screenshotName5;
            await takeScreenshot(screenshotName5, page);

            process.exit();
            await browser.close();

        });

    } catch(err) {

        console.log(err);

    }
  
}

register().then(function()
{

    console.log(JSON.stringify(response));
    process.exit();

});

// Creates new tab
async function createTab(browser)
{

	page = await browser.newPage();
	page.on('error', err=> {});
    page.on('pageerror', err=> {});
    
    await page.deleteCookie(...cookies);
    await page._client.send('Network.clearBrowserCookies');
    await page.setViewport({
        width: 1920,
        height: 1080
    });
    await page.setUserAgent(
        USER_AGENTS[Math.floor(Math.random()*USER_AGENTS.length)]
    );
    await page.setExtraHTTPHeaders({
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/png,*/*;q=0.8',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'en;q=0.9',
        'Connection': 'keep-alive'
    });

}

// Takes screenshot
async function takeScreenshot(name, page)
{

    let options = {
        path: SS_PATH+'/'+name,
        fullPage: true
    }
    await page.screenshot(options);  

}

Tell us about your environment:

  • Puppeteer version: 1.13 (I guess, I installed newest version a month ago)
  • Platform / OS version: Ubuntu 18.04
  • URLs (if applicable):
  • Node.js version: v10.11.0

What is the expected result?

See that my public sever's IP is not leaking.

What happens instead?

I see this:

Untitled

Even tough I am using TOR, i see that my real IP address is leaking through WebRTC.

Im sure that TOR proxy is working cause puppeteer works fine and if I go to whatismyip.com I see a different IP addres than mine's.

As you can see I tried to use this:
#2878

as a solution, but it didn't help. (I assume extension works fine, cause I get no errors while running the code).

So my question is, how can I disable WebRTC so it won't leak my public IP address?

@TomasKavaliauskas
Copy link
Author

I noticed that headless mode does not support extensions. At least that was 9 months ago, is there any improvement in this? If not, is there any way to prevent leaking IP address through webrtc without extension? Thank you.

@tobeorla
Copy link

tobeorla commented Mar 11, 2019

Have you tried --load-extension argument to load an extension? (https://peter.sh/experiments/chromium-command-line-switches/)
Maybe it lets you run the one you wanted. It seems that there is no disable webrtc argument :(

@aslushnikov
Copy link
Contributor

(I assume extension works fine, cause I get no errors while running the code).

@dudeperfect95 as you noticed later, headless doesn't support extensions and probably won't in a foreseeable future. You can run headful though - it should solve the issue.

If not, is there any way to prevent leaking IP address through webrtc without extension?

This I'm not sure about. What's the extension and what does it do?

@TomasKavaliauskas
Copy link
Author

TomasKavaliauskas commented Mar 15, 2019

I used headless: false and it works fine. Extension is webrtc disabler. Cant find exact link where did I get it. I have another question, if I want to load more than one extension, how should I declare path?

I have such folder tree:

root/
...extensions/
......webrtc/
......another/

const extensionPath = 'extensions/webrtc';

    await puppeteer.launch({ 
        slowMo: 10,
        headless: false,
        args:[ 
            `--disable-extensions-except=${extensionPath}`,
            `--load-extension=${extensionPath}`,

... trimmed

This code works fine, but If I want to add another extension, what should I do? If I change extension path to /extensions/ none of them works.

@aslushnikov
Copy link
Contributor

@dudeperfect95 you can pass a comma-separated list of paths for both --disable-extensions-except and --load-extension flags.

@flogiston
Copy link

Blocking all outgoing UDP traffic except DNS can help in headless mode.

@ediweissmann
Copy link

Another way to do it:

await page.evaluateOnNewDocument(
        `navigator.mediaDevices.getUserMedia = navigator.webkitGetUserMedia = navigator.mozGetUserMedia = navigator.getUserMedia = webkitRTCPeerConnection = RTCPeerConnection = MediaStreamTrack = undefined;`
      );

@kumargaf
Copy link

@ediweissmann I used your solution but its not helping . some how my local ip is being exposed

@s3rgeym
Copy link

s3rgeym commented Aug 31, 2020

Another way to do it:

await page.evaluateOnNewDocument(
        `navigator.mediaDevices.getUserMedia = navigator.webkitGetUserMedia = navigator.mozGetUserMedia = navigator.getUserMedia = webkitRTCPeerConnection = RTCPeerConnection = MediaStreamTrack = undefined;`
      );

Doesn't work

@gegewepeez
Copy link

Another way to do it:

await page.evaluateOnNewDocument(
        `navigator.mediaDevices.getUserMedia = navigator.webkitGetUserMedia = navigator.mozGetUserMedia = navigator.getUserMedia = webkitRTCPeerConnection = RTCPeerConnection = MediaStreamTrack = undefined;`
      );

It works. Thanks

@hungfhp
Copy link

hungfhp commented Jun 22, 2022

Thank @ediweissmann
It works

@abacaj
Copy link

abacaj commented Oct 12, 2022

the example for evaluateOnNewDocument didn't work for me

but this works for me even with headless: true (if you don't mind disabling rtc):

Object.defineProperty(window, 'RTCPeerConnection', {
  get: () => {
    return {};
  },
});
Object.defineProperty(window, 'RTCDataChannel', {
  get: () => {
    return {};
  },
});

browserleak

@aditodkar
Copy link

await page.evaluateOnNewDocument(
navigator.mediaDevices.getUserMedia = navigator.webkitGetUserMedia = navigator.mozGetUserMedia = navigator.getUserMedia = webkitRTCPeerConnection = RTCPeerConnection = MediaStreamTrack = undefined;
);

Thanks it worked with latest new headless puppeteer

@tbm98
Copy link

tbm98 commented Aug 21, 2023

Another way to do it:

await page.evaluateOnNewDocument(
        `navigator.mediaDevices.getUserMedia = navigator.webkitGetUserMedia = navigator.mozGetUserMedia = navigator.getUserMedia = webkitRTCPeerConnection = RTCPeerConnection = MediaStreamTrack = undefined;`
      );

It works for me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests