25

Because Tor Browser Bundle is just a patched version of Firefox, it seems that it should be possible to use a FirefoxDriver with Tor Browser. This is what I've tried so far:

String torPath = "C:\\Users\\My User\\Desktop\\Tor Browser\\Start Tor Browser.exe";
String profilePath = "C:\\Users\\My User\\Desktop\\Tor Browser\\Data\\Browser\\profile.default";
FirefoxProfile profile = new FirefoxProfile(new File(profilePath));
FirefoxBinary binary = new FirefoxBinary(new File(torPath));
FirefoxDriver driver = new FirefoxDriver(binary, profile);
driver.get("http://www.google.com");

This results in a blank Tor Browser page opening with a popup message: Your Firefox profile cannot be loaded. It may be missing or inaccessible.

I know that the profile is valid/compatible because I can successfully start the browser and profile with:

binary.startProfile(profile, profilePath, ""));

I don't know how to send commands to a browser opened in such a manner, however.

I've found similar questions, but I'm specifically looking for a Java solution, preferably tested on Windows.

I'm using a standalone Selenium library that can be downloaded here and the Tor Browser Bundle that can be downloaded here.

Joel Christophel
  • 2,604
  • 4
  • 30
  • 49
  • According to the [Tor browser design page](https://www.torproject.org/projects/torbrowser/design/), the patches compiled into the version of Firefox prevent extensions from executing. Since the "remote end" of the Firefox driver is implemented as a browser extension, might this affect your ability to use WebDriver to drive the Tor browser? – JimEvans Apr 21 '14 at 11:37
  • I've though of that too, but it appears that it was achieved by Mimi below. Also, I've got it working on Linux. – Joel Christophel Apr 21 '14 at 16:49
  • One difference between your code and the code specified below is that you're launching "Start Tor Browser.exe" while the other code is launching the embedded Firefox executable. If I change your `FirefoxBinary` to point to `C:\Users\\Desktop\Tor Browser\Browser\firefox.exe`, I'm able to launch the browser without error, but the WebDriver extension most assuredly does not load. – JimEvans Apr 21 '14 at 20:10
  • I've tried that, but I get the same result. – Joel Christophel Apr 21 '14 at 20:44

5 Answers5

19

Because Tor Browser Bundle wasn't letting me use the WebDriver extension, I found a workaround in which I ran Tor from a regular Firefox browser. With this method, as long as the Tor Browser is open, you can use Tor with a regular Firefox browser.

  • Open Tor Browser:

    File torProfileDir = new File(
            "...\\Tor Browser\\Data\\Browser\\profile.default");
    FirefoxBinary binary = new FirefoxBinary(new File(
            "...\\Tor Browser\\Start Tor Browser.exe"));
    FirefoxProfile torProfile = new FirefoxProfile(torProfileDir);
    torProfile.setPreference("webdriver.load.strategy", "unstable");
    
    try {
        binary.startProfile(torProfile, torProfileDir, "");
    } catch (IOException e) {
        e.printStackTrace();
    }
    
  • Open Firefox with some configurations:

    FirefoxProfile profile = new FirefoxProfile();
    profile.setPreference("network.proxy.type", 1);
    profile.setPreference("network.proxy.socks", "127.0.0.1");
    profile.setPreference("network.proxy.socks_port", 9150);
    FirefoxDriver = new FirefoxDriver(profile);
    
  • Close browsers. Note that if you plan on doing a lot of closing and reopening (useful in obtaining a new IP address), I advise setting the profile preference toolkit.startup.max_resumed_crashes to a high value like 9999.

    private void killFirefox() {
        Runtime rt = Runtime.getRuntime();
    
        try {
            rt.exec("taskkill /F /IM firefox.exe");
            while (processIsRunning("firefox.exe")) {
                Thread.sleep(100);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    private boolean processIsRunning(String process) {
        boolean processIsRunning = false;
        String line;
        try {
            Process proc = Runtime.getRuntime().exec("wmic.exe");
            BufferedReader input = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            OutputStreamWriter oStream = new OutputStreamWriter(proc.getOutputStream());
            oStream.write("process where name='" + process + "'");
            oStream.flush();
            oStream.close();
            while ((line = input.readLine()) != null) {
                if (line.toLowerCase().contains("caption")) {
                    processIsRunning = true;
                    break;
                }
            }
            input.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return processIsRunning;
    }
    
Joel Christophel
  • 2,604
  • 4
  • 30
  • 49
  • 3
    I was trying to follow this steps, but Im getting error while executing TOR, when the browser starts, a pop up saying, **TOR failed to start** is displayed. – Jose Bernhardt Aug 25 '16 at 15:22
  • @JoseBernhardt do you have a full code please? GitHub maybe? or in a private email? –  Sep 07 '17 at 12:22
  • 1
    Warning: you should *almost never* attempt to use tor to browse the web through anything other than tor browser. Following this solution is a terrible idea and you should expect zero anonymity if you use it. Yes, tor browser is "just" a modified firefox. However, it has been modified in such a way as to prevent the browser from leaking your information or identity. Vanilla firefox does not make any such attempts. – nullUser Jan 25 '18 at 16:29
  • @nullUser Sounds like sage advice but what modifications are you referring to? Can you throw us a bone? – Robino Apr 28 '18 at 16:01
  • 1
    @Robino Read https://www.torproject.org/projects/torbrowser/design/ and the links that goes on from there. Yes, there are pretty many changes. – deviantfan Jan 27 '19 at 17:17
  • To repeat nullUser: **This answer is dangerous** because it gives up most of the anonymity Tor offers. The tor version of firefox is not a web development environment, Selenium has no business existing there. – deviantfan Jan 27 '19 at 17:19
3

I would try specifying the path of one of the existing profiles and initialize your profile instance for Tor so your code would look something like:

String torPath = "..\\Tor Browser\\Browser\\firefox.exe";
String profilePath = "..\\Tor Browser\\Data\Browser\\profile.default";
FirefoxProfile profile = new FirefoxProfile(new File(profilePath));
FirefoxBinary binary = new FirefoxBinary(new File(torPath));
FirefoxDriver driver = new FirefoxDriver(binary, profile);
driver.get("http://www.google.com");

I didn't try this since I don't have WebDriver setup at home, but this should allow you to specify a profile.

Dan Snell
  • 2,185
  • 3
  • 21
  • 35
  • 1
    You may want to take a look at the following question. http://stackoverflow.com/questions/15316304/open-tor-browser-with-selenium?rq=1 – Dan Snell Apr 11 '14 at 16:26
  • I'm still getting: *Your Firefox profile cannot be loaded. It may be missing or inaccessible.* – Joel Christophel Apr 15 '14 at 22:03
  • I would double check the path to the profile is indeed valid. – Dan Snell Apr 16 '14 at 03:56
  • 1
    Just to make absolutely sure, can you give it the absolute path instead of using the relative path and see if that makes any difference? The other possibility is it's not able to parse the profile files for the Tor implementation - they may be using a different format. Do you have a diff tool? Maybe do a quick glance and compare a FF profile directory to the tor profile directory. I recommend BeyondCompare, you can compare individual files and entire folder structures. – Adam Plocher Apr 18 '14 at 20:14
  • In my example, I provided only the portion on the path that would be constant for everyone, but I'm actually using the absolute path in my own implementation. The contents of the profile directories look pretty similar, and *profiles.ini* is pretty much identical for both. (You could always give it a whirl and see what happens. I've provided all of the download links necessary.) – Joel Christophel Apr 19 '14 at 03:00
2

I downloaded TorBrowser and I was able to call it without any problem, with the following code (it's Mac OS). So I think there shouldn't be any problem about compatibility between the firefox webdriver and the latest version of Tor Browser.

String torPath = "/Volumes/DATA/Downloads/Tor.app/Contents/MacOS/TorBrowser.app/Contents/MacOS/firefox";
String profilePath = "/Users/mimitantono/Library/Application Support/Firefox/Profiles/1vps9kas.default-1384778906995";
FirefoxProfile profile = new FirefoxProfile(new File(profilePath));
FirefoxBinary binary = new FirefoxBinary(new File(torPath));
FirefoxDriver driver = new FirefoxDriver(binary, profile);
driver.get("http://www.google.com/webhp?complete=1&hl=en");

I know that you already tested the path of your profile with binary.startProfile but I think you could try again to use slash instead of backslash to specify the path, cross check whether that file exists -> profile.default, and to use absolute path instead of relative -> ../.

  • I was actually using the full, absolute paths in my implementation. I've shown the absolute paths now to avoid confusion. As for backslashses, they are used on Windows computers, so that's definitely not the problem. One thing that sticks out is that you've used the default Firefox profile instead of the one Tor provides. I tried that, but it didn't work either. – Joel Christophel Apr 19 '14 at 15:08
1

This code also is working pretty good in ubuntu. Here is an example (JUnit4):

package qa2all;

import java.io.File;
import java.util.concurrent.TimeUnit;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxBinary;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;


public class HTMLUnit {
    private WebDriver driver;
    private String baseUrl;
    private StringBuffer verificationErrors = new StringBuffer();

    @Before
    public void setUp() throws Exception {
        //driver = new HtmlUnitDriver();    
        //driver = new FirefoxDriver();
        String torPath = "/home/user/Dropbox/Data/TorBrowser/Linux/32/start-tor-browser";
        String profilePath = "/home/user/Dropbox/Data/TorBrowser/Linux/32/TorBrowser/Data/Browser/profile.default/";
        FirefoxProfile profile = new FirefoxProfile(new File(profilePath));
        FirefoxBinary binary = new FirefoxBinary(new File(torPath));
        driver = new FirefoxDriver(binary, profile);        
        baseUrl = "https://qa2all.wordpress.com";
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
    }

    @Test
    public void testUntitled() throws Exception {
        driver.get(baseUrl + "/");

    }

    @After
    public void tearDown() throws Exception {
        driver.quit();
        String verificationErrorString = verificationErrors.toString();
        if (!"".equals(verificationErrorString)) {
            fail(verificationErrorString);
        }
    }

    private void fail(String verificationErrorString) {
        // TODO Auto-generated method stub

    }
}
0

If you mostly care about remote-controlling a browser using Tor (and would maybe prefer to use the Tor Browser instead of vanilla Firefox), you can use Mozilla's Marionette. Use like

To use with the Tor Browser, enable marionette at startup via

Browser/firefox -marionette

(inside the bundle). Then, you can connect via

from marionette import Marionette
client = Marionette('localhost', port=2828);
client.start_session()

and load a new page for example via

url='http://mozilla.org'
client.navigate(url);

For more examples, there is a tutorial along with more documentation.

(copy)

Community
  • 1
  • 1
serv-inc
  • 35,772
  • 9
  • 166
  • 188