git.schokokeks.org
Repositories
Help
Report an Issue
tor-webwml.git
Code
Commits
Branches
Tags
Suche
Strukturansicht:
129bcf444
Branches
Tags
bridges
docs-debian
jobs
master
press-clips
tor-webwml.git
torbutton
design
design.xml
add torbutton design dir from git.
Andrew Lewman
commited
129bcf444
at 2009-12-31 03:42:43
design.xml
Blame
History
Raw
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "file:///usr/share/sgml/docbook/xml-dtd-4.4-1.0-30.1/docbookx.dtd"> <article id="design"> <articleinfo> <title>Torbutton Design Documentation</title> <author> <firstname>Mike</firstname><surname>Perry</surname> <affiliation> <address><email>mikeperry.fscked/org</email></address> </affiliation> </author> <pubdate>Dec 15 2009</pubdate> </articleinfo> <sect1> <title>Introduction</title> <para> This document describes the goals, operation, and testing procedures of the Torbutton Firefox extension. It is current as of Torbutton 1.2.4. </para> <sect2 id="adversary"> <title>Adversary Model</title> <para> A Tor web browser adversary has a number of goals, capabilities, and attack types that can be used to guide us towards a set of requirements for the Torbutton extension. Let's start with the goals. </para> <sect3 id="adversarygoals"> <title>Adversary Goals</title> <orderedlist> <!-- These aren't really commands.. But it's the closest I could find in an acceptable style.. Don't really want to make my own stylesheet --> <listitem><command>Bypassing proxy settings</command> <para>The adversary's primary goal is direct compromise and bypass of Tor, causing the user to directly connect to an IP of the adversary's choosing.</para> </listitem> <listitem><command>Correlation of Tor vs Non-Tor Activity</command> <para>If direct proxy bypass is not possible, the adversary will likely happily settle for the ability to correlate something a user did via Tor with their non-Tor activity. This can be done with cookies, cache identifiers, javascript events, and even CSS. Sometimes the fact that a user uses Tor may be enough for some authorities.</para> </listitem> <listitem><command>History disclosure</command> <para> The adversary may also be interested in history disclosure: the ability to query a user's history to see if they have issued certain censored search queries, or visited censored sites. </para> </listitem> <listitem><command>Location information</command> <para> Location information such as timezone and locality can be useful for the adversary to determine if a user is in fact originating from one of the regions they are attempting to control, or to zero-in on the geographical location of a particular dissident or whistleblower. </para> </listitem> <listitem><command>Miscellaneous anonymity set reduction</command> <para> Anonymity set reduction is also useful in attempting to zero in on a particular individual. If the dissident or whistleblower is using a rare build of Firefox for an obscure operating system, this can be very useful information for tracking them down, or at least <link linkend="fingerprinting">tracking their activities</link>. </para> </listitem> <listitem><command>History records and other on-disk information</command> <para> In some cases, the adversary may opt for a heavy-handed approach, such as seizing the computers of all Tor users in an area (especially after narrowing the field by the above two pieces of information). History records and cache data are the primary goals here. </para> </listitem> </orderedlist> </sect3> <sect3 id="adversarypositioning"> <title>Adversary Capabilities - Positioning</title> <para> The adversary can position themselves at a number of different locations in order to execute their attacks. </para> <orderedlist> <listitem><command>Exit Node or Upstream Router</command> <para> The adversary can run exit nodes, or alternatively, they may control routers upstream of exit nodes. Both of these scenarios have been observed in the wild. </para> </listitem> <listitem><command>Adservers and/or Malicious Websites</command> <para> The adversary can also run websites, or more likely, they can contract out ad space from a number of different adservers and inject content that way. For some users, the adversary may be the adservers themselves. It is not inconceivable that adservers may try to subvert or reduce a user's anonymity through Tor for marketing purposes. </para> </listitem> <listitem><command>Local Network/ISP/Upstream Router</command> <para> The adversary can also inject malicious content at the user's upstream router when they have Tor disabled, in an attempt to correlate their Tor and Non-Tor activity. </para> </listitem> <listitem><command>Physical Access</command> <para> Some users face adversaries with intermittent or constant physical access. Users in Internet cafes, for example, face such a threat. In addition, in countries where simply using tools like Tor is illegal, users may face confiscation of their computer equipment for excessive Tor usage or just general suspicion. </para> </listitem> </orderedlist> </sect3> <sect3 id="attacks"> <title>Adversary Capabilities - Attacks</title> <para> The adversary can perform the following attacks from a number of different positions to accomplish various aspects of their goals. It should be noted that many of these attacks (especially those involving IP address leakage) are often performed by accident by websites that simply have Javascript, dynamic CSS elements, and plugins. Others are performed by adservers seeking to correlate users' activity across different IP addresses, and still others are performed by malicious agents on the Tor network and at national firewalls. </para> <orderedlist> <listitem><command>Inserting Javascript</command> <para> If not properly disabled, Javascript event handlers and timers can cause the browser to perform network activity after Tor has been disabled, thus allowing the adversary to correlate Tor and Non-Tor activity and reveal a user's non-Tor IP address. Javascript also allows the adversary to execute <ulink url="http://whattheinternetknowsaboutyou.com/">history disclosure attacks</ulink>: to query the history via the different attributes of 'visited' links to search for particular google queries, sites, or even to <ulink url="http://www.mikeonads.com/2008/07/13/using-your-browser-url-history-estimate-gender/">profile users based on gender and other classifications</ulink>. Finally, Javascript can be used to query the user's timezone via the <function>Date()</function> object, and to reduce the anonymity set by querying the <function>navigator</function> object for operating system, CPU, locale, and user agent information. </para> </listitem> <listitem><command>Inserting Plugins</command> <para> Plugins are abysmal at obeying the proxy settings of the browser. Every plugin capable of performing network activity that the author has investigated is also capable of performing network activity independent of browser proxy settings - and often independent of its own proxy settings. Sites that have plugin content don't even have to be malicious to obtain a user's Non-Tor IP (it usually leaks by itself), though <ulink url="http://decloak.net">plenty of active exploits</ulink> are possible as well. In addition, plugins can be used to store unique identifiers that are more difficult to clear than standard cookies. <ulink url="http://epic.org/privacy/cookies/flash.html">Flash-based cookies</ulink> fall into this category, but there are likely numerous other examples. </para> </listitem> <listitem><command>Inserting CSS</command> <para> CSS can also be used to correlate Tor and Non-Tor activity and reveal a user's Non-Tor IP address, via the usage of <ulink url="http://www.tjkdesign.com/articles/css%20pop%20ups/">CSS popups</ulink> - essentially CSS-based event handlers that fetch content via CSS's onmouseover attribute. If these popups are allowed to perform network activity in a different Tor state than they were loaded in, they can easily correlate Tor and Non-Tor activity and reveal a user's IP address. In addition, CSS can also be used without Javascript to perform <ulink url="http://ha.ckers.org/weird/CSS-history.cgi">CSS-only history disclosure attacks</ulink>. </para> </listitem> <listitem><command>Read and insert cookies</command> <para> An adversary in a position to perform MITM content alteration can inject document content elements to both read and inject cookies for arbitrary domains. In fact, many "SSL secured" websites are vulnerable to this sort of <ulink url="http://seclists.org/bugtraq/2007/Aug/0070.html">active sidejacking</ulink>. </para> </listitem> <listitem><command>Create arbitrary cached content</command> <para> Likewise, the browser cache can also be used to <ulink url="http://crypto.stanford.edu/sameorigin/safecachetest.html">store unique identifiers</ulink>. Since by default the cache has no same-origin policy, these identifiers can be read by any domain, making them an ideal target for adserver-class adversaries. </para> </listitem> <listitem id="fingerprinting"><command>Fingerprint users based on browser attributes</command> <para> There is an absurd amount of information available to websites via attributes of the browser. This information can be used to reduce anonymity set, or even <ulink url="http://mandark.fr/0x000000/articles/Total_Recall_On_Firefox..html">uniquely fingerprint individual users</ulink>. </para> <para> For illustration, let's perform a back-of-the-envelope calculation on the number of anonymity sets for just the resolution information available in the <ulink url="http://developer.mozilla.org/en/docs/DOM:window">window</ulink> and <ulink url="http://developer.mozilla.org/en/docs/DOM:window.screen">window.screen</ulink> objects. Browser window resolution information provides something like (1280-640)*(1024-480)=348160 different anonymity sets. Desktop resolution information contributes about another factor of 5 (for about 5 resolutions in typical use). In addition, the dimensions and position of the desktop taskbar are available, which can reveal hints on OS information. This boosts the count by a factor of 5 (for each of the major desktop taskbars - Windows, OSX, KDE and Gnome, and None). Subtracting the browser content window size from the browser outer window size provide yet more information. Firefox toolbar presence gives about a factor of 8 (3 toolbars on/off give 2<superscript>3</superscript>=8). Interface effects such as titlebar fontsize and window manager settings gives a factor of about 9 (say 3 common font sizes for the titlebar and 3 common sizes for browser GUI element fonts). Multiply this all out, and you have (1280-640)*(1024-480)*5*5*8*9 ~= 2<superscript>29</superscript>, or a 29 bit identifier based on resolution information alone. </para> <para> Of course, this space is non-uniform and prone to incremental changes. However, if a bit vector space consisting of the above extracted attributes were used instead of the hash approach from <ulink url="http://mandark.fr/0x000000/articles/Total_Recall_On_Firefox..html">The Hacker Webzine article above</ulink>, minor changes in browser window resolution will no longer generate totally new identifiers. </para> <para> To add insult to injury, <ulink url="http://pseudo-flaw.net/content/tor/torbutton/">chrome URL disclosure attacks</ulink> mean that each and every extension on <ulink url="https://addons.mozilla.org">addons.mozilla.org</ulink> adds another bit to that 2<superscript>29</superscript>. With hundreds of popular extensions and thousands of extensions total, it is easy to see that this sort of information is an impressively powerful identifier if used properly by a competent and determined adversary such as an ad network. Again, a nearest-neighbor bit vector space approach here would also gracefully handle incremental changes to installed extensions. </para> </listitem> <listitem><command>Remotely or locally exploit browser and/or OS</command> <para> Last, but definitely not least, the adversary can exploit either general browser vulnerabilities, plugin vulnerabilities, or OS vulnerabilities to install malware and surveillance software. An adversary with physical access can perform similar actions. Regrettably, this last attack capability is outside of Torbutton's ability to defend against, but it is worth mentioning for completeness. </para> </listitem> </orderedlist> </sect3> </sect2> <sect2 id="requirements"> <title>Torbutton Requirements</title> <note> Since many settings satisfy multiple requirements, this design document is organized primarily by Torbutton components and settings. However, if you are the type that would rather read the document from the requirements perspective, it is in fact possible to search for each of the following requirement phrases in the text to find the relevant features that help meet that requirement. </note> <para> From the above Adversary Model, a number of requirements become clear. </para> <orderedlist> <!-- These aren't really commands.. But it's the closest I could find in an acceptable style.. Don't really want to make my own stylesheet --> <listitem id="proxy"><command>Proxy Obedience</command> <para>The browser MUST NOT bypass Tor proxy settings for any content.</para></listitem> <listitem id="isolation"><command>Network Isolation</command> <para>Pages MUST NOT perform any network activity in a Tor state different from the state they were originally loaded in.</para></listitem> <listitem id="state"><command>State Separation</command> <para>Browser state (cookies, cache, history, 'DOM storage'), accumulated in one Tor state MUST NOT be accessible via the network in another Tor state.</para></listitem> <listitem id="undiscoverability"><command>Tor Undiscoverability</command><para>With the advent of bridge support in Tor 0.2.0.x, there are now a class of Tor users whose network fingerprint does not obviously betray the fact that they are using Tor. This should extend to the browser as well - Torbutton MUST NOT reveal its presence while Tor is disabled.</para></listitem> <listitem id="disk"><command>Disk Avoidance</command><para>The browser SHOULD NOT write any Tor-related state to disk, or store it in memory beyond the duration of one Tor toggle.</para></listitem> <listitem id="location"><command>Location Neutrality</command><para>The browser SHOULD NOT leak location-specific information, such as timezone or locale via Tor.</para></listitem> <listitem id="setpreservation"><command>Anonymity Set Preservation</command><para>The browser SHOULD NOT leak any other anonymity set reducing information (such as user agent, extension presence, and resolution information) automatically via Tor. The assessment of the attacks above should make it clear that anonymity set reduction is a very powerful method of tracking and eventually identifying anonymous users. </para></listitem> <listitem id="updates"><command>Update Safety</command><para>The browser SHOULD NOT perform unauthenticated updates or upgrades via Tor.</para></listitem> <listitem id="interoperate"><command>Interoperability</command><para>Torbutton SHOULD interoperate with third-party proxy switchers that enable the user to switch between a number of different proxies. It MUST provide full Tor protection in the event a third-party proxy switcher has enabled the Tor proxy settings.</para></listitem> </orderedlist> </sect2> <sect2 id="layout"> <title>Extension Layout</title> <para>Firefox extensions consist of two main categories of code: 'Components' and 'Chrome'. Components are a fancy name for classes that implement a given interface or interfaces. In Firefox, components <ulink url="https://developer.mozilla.org/en/XPCOM">can be written</ulink> in C++, Javascript, or a mixture of both. Components have two identifiers: their '<ulink url="http://www.mozilla.org/projects/xpcom/book/cxc/html/quicktour2.html#1005005">Contract ID</ulink>' (a human readable path-like string), and their '<ulink url="http://www.mozilla.org/projects/xpcom/book/cxc/html/quicktour2.html#1005329">Class ID</ulink>' (a GUID hex-string). In addition, the interfaces they implement each have a hex 'Interface ID'. It is possible to 'hook' system components - to reimplement their interface members with your own wrappers - but only if the rest of the browser refers to the component by its Contract ID. If the browser refers to the component by Class ID, it bypasses your hooks in that use case. Technically, it may be possible to hook Class IDs by unregistering the original component, and then re-registering your own, but this relies on obsolete and deprecated interfaces and has proved to be less than stable.</para> <para>'Chrome' is a combination of XML and Javascript used to describe a window. Extensions are allowed to create 'overlays' that are 'bound' to existing XML window definitions, or they can create their own windows. The DTD for this XML is called <ulink url="http://developer.mozilla.org/en/docs/XUL_Reference">XUL</ulink>.</para> </sect2> </sect1> <sect1> <title>Components</title> <para> Torbutton installs components for two purposes: hooking existing components to reimplement their interfaces; and creating new components that provide services to other pieces of the extension. </para> <sect2> <title>Hooked Components</title> <para>Torbutton makes extensive use of Contract ID hooking, and implements some of its own standalone components as well. Let's discuss the hooked components first.</para> <sect3 id="sessionstore"> <title><ulink url="http://developer.mozilla.org/en/docs/nsISessionStore">@mozilla.org/browser/sessionstore;1</ulink> - <ulink url="https://git.torproject.org/checkout/torbutton/master/src/components/nsSessionStore36.js">components/nsSessionStore36.js</ulink></title> <para>These components address the <link linkend="disk">Disk Avoidance</link> requirements of Torbutton. As stated in the requirements, Torbutton needs to prevent Tor tabs from being written to disk by the Firefox session store for a number of reasons, primary among them is the fact that Firefox can crash at any time, and a restart can cause you to fetch tabs in the incorrect Tor state.</para> <para>These components illustrate a complication with Firefox hooking: you can only hook member functions of a class if they are published in an interface that the class implements. Unfortunately, the sessionstore has no published interface that is amenable to disabling the writing out of Tor tabs in specific. As such, Torbutton had to include the <emphasis>entire</emphasis> nsSessionStore from both Firefox 2.0, 3.0, 3.5 and 3.6 with a couple of modifications to prevent tabs that were loaded with Tor enabled from being written to disk, and some version detection code to determine which component to load. The <ulink url="https://git.torproject.org/checkout/torbutton/master/src/components/nsSessionStore36.diff">diff against the original session store</ulink> is included in the git repository.</para> </sect3> <sect3 id="appblocker"> <title><ulink url="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/components/%40mozilla.org/uriloader/external-protocol-service%3B1">@mozilla.org/uriloader/external-protocol-service;1 </ulink>, <ulink url="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/components/%40mozilla.org/uriloader/external-helper-app-service%3B1">@mozilla.org/uriloader/external-helper-app-service;1</ulink>, and <ulink url="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/components/%40mozilla.org/mime%3B1">@mozilla.org/mime;1</ulink> - <ulink url="https://git.torproject.org/checkout/torbutton/master/src/components/external-app-blocker.js">components/external-app-blocker.js</ulink></title> <para> Due to <link linkend="FirefoxBugs">Firefox Bug</link> <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=440892">440892</ulink> allowing Firefox 3.x to automatically launch some applications without user intervention, Torbutton had to wrap the three components involved in launching external applications to provide user confirmation before doing so while Tor is enabled. Since external applications do not obey proxy settings, they can be manipulated to automatically connect back to arbitrary servers outside of Tor with no user intervention. Fixing this issue helps to satisfy Torbutton's <link linkend="proxy">Proxy Obedience</link> Requirement. </para> </sect3> <sect3> <title><ulink url="http://lxr.mozilla.org/seamonkey/source/browser/components/sessionstore/src/nsSessionStartup.js">@mozilla.org/browser/sessionstartup;1</ulink> - <ulink url="https://git.torproject.org/checkout/torbutton/master/src/components/crash-observer.js">components/crash-observer.js</ulink></title> <para>This component wraps the Firefox Session Startup component that is in charge of <ulink url="http://developer.mozilla.org/en/docs/Session_store_API">restoring saved sessions</ulink>. The wrapper's only job is to intercept the <function>doRestore()</function> function, which is called by Firefox if it is determined that the browser crashed and the session needs to be restored. The wrapper notifies the Torbutton chrome that the browser crashed by setting the pref <command>extensions.torbutton.crashed</command>, or that it is a normal startup via the pref <command>extensions.torbutton.noncrashed</command>. The Torbutton Chrome <ulink url="https://developer.mozilla.org/en/NsIPrefBranch2#addObserver.28.29">listens for a preference change</ulink> for this value and then does the appropriate cleanup. This includes setting the Tor state to the one the user selected for crash recovery in the preferences window (<command>extensions.torbutton.restore_tor</command>), and restoring cookies for the corresponding cookie jar, if it exists.</para> <para>By performing this notification, this component assists in the <link linkend="proxy">Proxy Obedience</link>, and <link linkend="isolation">Network Isolation</link> requirements. </para> </sect3> <sect3> <title><ulink url="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/components/%40mozilla.org/browser/global-history;2">@mozilla.org/browser/global-history;2</ulink> - <ulink url="https://git.torproject.org/checkout/torbutton/master/src/components/ignore-history.js">components/ignore-history.js</ulink></title> <para>This component was contributed by <ulink url="http://www.collinjackson.com/">Collin Jackson</ulink> as a method for defeating CSS and Javascript-based methods of history disclosure. The global-history component is what is used by Firefox to determine if a link was visited or not (to apply the appropriate style to the link). By hooking the <ulink url="https://developer.mozilla.org/en/nsIGlobalHistory2#isVisited.28.29">isVisited</ulink> and <ulink url="https://developer.mozilla.org/en/nsIGlobalHistory2#addURI.28.29">addURI</ulink> methods, Torbutton is able to selectively prevent history items from being added or being displayed as visited, depending on the Tor state and the user's preferences. </para> <para> This component helps satisfy the <link linkend="state">State Separation</link> and <link linkend="disk">Disk Avoidance</link> requirements of Torbutton. </para> </sect3> <sect3 id="livemarks"> <title><ulink url="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/components/%40mozilla.org/browser/livemark-service;2">@mozilla.org/browser/livemark-service;2</ulink> - <ulink url="https://git.torproject.org/checkout/torbutton/master/src/components/block-livemarks.js">components/block-livemarks.js</ulink></title> <para> The <ulink url="http://www.mozilla.com/en-US/firefox/livebookmarks.html">livemark</ulink> service is started by a timer that runs 5 seconds after Firefox startup. As a result, we cannot simply call the stopUpdateLivemarks() method to disable it. We must wrap the component to prevent this start() call from firing in the event the browser starts in Tor mode. </para> <para> This component helps satisfy the <link linkend="isolation">Network Isolation</link> and <link linkend="setpreservation">Anonymity Set Preservation</link> requirements. </para> </sect3> </sect2> <sect2> <title>New Components</title> <para>Torbutton creates four new components that are used throughout the extension. These components do not hook any interfaces, nor are they used anywhere besides Torbutton itself.</para> <sect3> <title><ulink url="https://git.torproject.org/checkout/torbutton/master/src/components/cookie-jar-selector.js">@torproject.org/cookie-jar-selector;2 - components/cookie-jar-selector.js</ulink></title> <para>The cookie jar selector (also based on code from <ulink url="http://www.collinjackson.com/">Collin Jackson</ulink>) is used by the Torbutton chrome to switch between Tor and Non-Tor cookies. Its operations are simple: sync cookies to disk, then move the current cookies.txt file to the appropriate backup location (cookies-tor.txt or cookies-nontor.txt), and then moving the other cookie jar into place.</para> <para> This component helps to address the <link linkend="state">State Isolation</link> requirement of Torbutton. </para> </sect3> <sect3> <title><ulink url="https://git.torproject.org/checkout/torbutton/master/src/components/torbutton-logger.js">@torproject.org/torbutton-logger;1 - components/torbutton-logger.js</ulink></title> <para>The torbutton logger component allows on-the-fly redirection of torbutton logging messages to either Firefox stderr (<command>extensions.torbutton.logmethod=0</command>), the Javascript error console (<command>extensions.torbutton.logmethod=1</command>), or the DebugLogger extension (if available - <command>extensions.torbutton.logmethod=2</command>). It also allows you to change the loglevel on the fly by changing <command>extensions.torbutton.loglevel</command> (1-5, 1 is most verbose). </para> </sect3> <sect3 id="windowmapper"> <title><ulink url="https://git.torproject.org/checkout/torbutton/master/src/components/window-mapper.js">@torproject.org/content-window-mapper;1 - components/window-mapper.js</ulink></title> <para>Torbutton tags Firefox <ulink url="https://developer.mozilla.org/en/XUL_Tutorial/Tabboxes">tabs</ulink> with a special variable that indicates the Tor state the tab was most recently used under to fetch a page. The problem is that for many Firefox events, it is not possible to determine the tab that is actually receiving the event. The Torbutton window mapper allows the Torbutton chrome and other components to look up a <ulink url="https://developer.mozilla.org/en/XUL/tabbrowser">browser tab</ulink> for a given <ulink url="https://developer.mozilla.org/en/nsIDOMWindow">HTML content window</ulink>. It does this by traversing all windows and all browsers, until it finds the browser with the requested <ulink url="https://developer.mozilla.org/en/XUL/tabbrowser#p-contentWindow">contentWindow</ulink> element. Since the content policy and page loading in general can generate hundreds of these lookups, this result is cached inside the component. </para> </sect3> <sect3 id="contentpolicy"> <title><ulink url="https://git.torproject.org/checkout/torbutton/master/src/components/cssblocker.js">@torproject.org/cssblocker;1 - components/cssblocker.js</ulink></title> <para>This is a key component to Torbutton's security measures. When Tor is toggled, Javascript is disabled, and pages are instructed to stop loading. However, CSS is still able to perform network operations by loading styles for onmouseover events and other operations. In addition, favicons can still be loaded by the browser. The cssblocker component prevents this by implementing and registering an <ulink url="https://developer.mozilla.org/en/nsIContentPolicy">nsIContentPolicy</ulink>. When an nsIContentPolicy is registered, Firefox checks every attempted network request against its <ulink url="https://developer.mozilla.org/en/nsIContentPolicy#shouldLoad()">shouldLoad</ulink> member function to determine if the load should proceed. In Torbutton's case, the content policy looks up the appropriate browser tab using the <link linkend="windowmapper">window mapper</link>, and checks that tab's load tag against the current Tor state. If the tab was loaded in a different state than the current state, the fetch is denied. Otherwise, it is allowed.</para> This helps to achieve the <link linkend="isolation">Network Isolation</link> requirements of Torbutton. <para>In addition, the content policy also blocks website javascript from <ulink url="http://pseudo-flaw.net/content/tor/torbutton/">querying for versions and existence of extension chrome</ulink> while Tor is enabled, and also masks the presence of Torbutton to website javascript while Tor is disabled. </para> <para> Finally, some of the work that logically belongs to the content policy is instead handled by the <command>torbutton_http_observer</command> and <command>torbutton_weblistener</command> in <ulink url="https://git.torproject.org/checkout/torbutton/master/src/chrome/content/torbutton.js">torbutton.js</ulink>. These two objects handle blocking of Firefox 3 favicon loads, popups, and full page plugins, which for whatever reason are not passed to the Firefox content policy itself (see Firefox Bugs <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=437014">437014</ulink> and <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=401296">401296</ulink>). </para> <!-- FIXME: Hrmm, the content policy doesn't really lend itself well to display this way.. People looking for this much detail should consult the source. <para> <table rowheader="firstcol" frame='all'><title>Access Permissions Table</title> <tgroup cols='5' align='left' colsep='1' rowsep='1'> <tbody> <row> <entry></entry> <entry>chrome/resource</entry> <entry>a3</entry> <entry>a4</entry> <entry>a5</entry> </row> <row> <entry>file</entry> <entry>b2</entry> <entry>b3</entry> <entry>b4</entry> <entry>b5</entry> </row> <row> <entry>c1</entry> <entry>c2</entry> <entry>c3</entry> <entry>c4</entry> <entry>c5</entry> </row> <row> <entry>d1</entry> <entry>d2</entry> <entry>d3</entry> <entry>d4</entry> <entry>d5</entry> </row> </tbody> </tgroup> </table> </para> --> <para> This helps to fulfill both the <link linkend="setpreservation">Anonymity Set Preservation</link> and the <link linkend="undiscoverability">Tor Undiscoverability</link> requirements of Torbutton.</para> </sect3> </sect2> </sect1> <sect1> <title>Chrome</title> <para>The chrome is where all the torbutton graphical elements and windows are located. Each window is described as an <ulink url="http://developer.mozilla.org/en/docs/XUL_Reference">XML file</ulink>, with zero or more Javascript files attached. The scope of these Javascript files is their containing window.</para> <sect2 id="browseroverlay"> <title>Browser Overlay - <ulink url="https://git.torproject.org/checkout/torbutton/master/src/chrome/content/torbutton.xul">torbutton.xul</ulink></title> <para>The browser overlay, torbutton.xul, defines the toolbar button, the status bar, and events for toggling the button. The overlay code is in <ulink url="https://git.torproject.org/checkout/torbutton/master/src/chrome/content/torbutton.js">chrome/content/torbutton.js</ulink>. It contains event handlers for preference update, shutdown, upgrade, and location change events.</para> <para>The <ulink url="https://developer.mozilla.org/en/nsIWebProgressListener#onLocationChange">location change</ulink> <ulink url="https://developer.mozilla.org/en/nsIWebProgress">webprogress listener</ulink>, <command>torbutton_weblistener</command> is one of the most important parts of the chrome from a security standpoint. It is a <ulink url="https://developer.mozilla.org/en/nsIWebProgressListener">webprogress listener</ulink> that handles receiving an event every time a page load or iframe load occurs. This class eventually calls down to <function>torbutton_update_tags()</function> and <function>torbutton_hookdoc()</function>, which apply the browser Tor load state tags, plugin permissions, and install the Javascript hooks to hook the <ulink url="https://developer.mozilla.org/en/DOM/window.screen">window.screen</ulink> object to obfuscate browser and desktop resolution information. </para> <para> The browser overlay helps to satisfy a number of Torbutton requirements. These are better enumerated in each of the Torbutton preferences below. However, there are also a number of Firefox preferences set in <function>torbutton_update_status()</function> that aren't governed by any Torbutton setting. These are: </para> <orderedlist> <!-- Not set any more. <listitem><ulink url="http://kb.mozillazine.org/Browser.bookmarks.livemark_refresh_seconds">browser.bookmarks.livemark_refresh_seconds</ulink> <para> This pref is set in an attempt to disable the fetching of LiveBookmarks via Tor. Since users can potentially collect a large amount of live bookmarks to very personal sites (blogs of friends, wikipedia articles they maintain, comment feeds of their own blog), it is not possible to cleanly isolate these fetches and they are simply disabled during Tor usage. This helps to address the <link linkend="state">State Separation</link> requirement. Unfortunately <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=436250">Firefox Bug 436250</ulink> prevents this from functioning completely correctly. </para> </listitem> --> <listitem><ulink url="http://kb.mozillazine.org/Network.security.ports.banned">network.security.ports.banned</ulink> <para> Torbutton sets this setting to add ports 8123, 8118, 9050 and 9051 (which it reads from <command>extensions.torbutton.banned_ports</command>) to the list of ports Firefox is forbidden to access. These ports are Polipo, Privoxy, Tor, and the Tor control port, respectively. This is set for both Tor and Non-Tor usage, and prevents websites from attempting to do http fetches from these ports to see if they are open, which addresses the <link linkend="undiscoverability">Tor Undiscoverability</link> requirement. </para> </listitem> <listitem><ulink url="http://kb.mozillazine.org/Browser.send_pings">browser.send_pings</ulink> <para> This setting is currently always disabled. If anyone ever complains saying that they *want* their browser to be able to send ping notifications to a page or arbitrary link, I'll make this a pref or Tor-only. But I'm not holding my breath. I haven't checked if the content policy is called for pings, but if not, this setting helps with meeting the <link linkend="isolation">Network Isolation</link> requirement. </para> </listitem> <listitem><ulink url="http://kb.mozillazine.org/Browser.safebrowsing.remoteLookups">browser.safebrowsing.remoteLookups</ulink> <para> Likewise for this setting. I find it hard to imagine anyone who wants to ask Google in real time if each URL they visit is safe, especially when the list of unsafe URLs is downloaded anyway. This helps fulfill the <link linkend="disk">Disk Avoidance</link> requirement, by preventing your entire browsing history from ending up on Google's disks. </para> </listitem> <listitem><ulink url="http://kb.mozillazine.org/Browser.safebrowsing.enabled">browser.safebrowsing.enabled</ulink> <para> Safebrowsing does <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=360387">unauthenticated updates under Firefox 2</ulink>, so it is disabled during Tor usage. This helps fulfill the <link linkend="updates">Update Safety</link> requirement. Firefox 3 has the fix for that bug, and so safebrowsing updates are enabled during Tor usage. </para> </listitem> <listitem><ulink url="http://kb.mozillazine.org/Network.protocol-handler.warn-external.%28protocol%29">network.protocol-handler.warn-external.(protocol)</ulink> <para> If Tor is enabled, we need to prevent random external applications from launching without at least warning the user. This group of settings only partially accomplishes this, however. Applications can still be launched via plugins. The mechanisms for handling this are described under the "Disable Plugins During Tor Usage" preference. This helps fulfill the <link linkend="proxy">Proxy Obedience</link> requirement, by preventing external applications from accessing network resources at the command of Tor-fetched pages. Unfortunately, due to <link linkend="FirefoxBugs">Firefox Bug</link> <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=440892">440892</ulink>, these prefs are no longer obeyed. They are set still anyway out of respect for the dead. </para> </listitem> <listitem><ulink url="http://kb.mozillazine.org/Browser.sessionstore.max_tabs_undo">browser.sessionstore.max_tabs_undo</ulink> <para> To help satisfy the Torbutton <link linkend="state">State Separation</link> and <link linkend="isolation">Network Isolation</link> requirements, Torbutton needs to purge the Undo Tab history on toggle to prevent repeat "Undo Close" operations from accidentally restoring tabs from a different Tor State. This purge is accomplished by setting this preference to 0 and then restoring it to the previous user value upon toggle. </para> </listitem> <listitem><command>security.enable_ssl2</command> <para> TLS Session IDs can persist for an indefinite duration, providing an identifier that is sent to TLS sites that can be used to link activity. This is particularly troublesome now that we have certificate verification in place in Firefox 3: The OCSP server can use this Session ID to build a history of TLS sites someone visits, and also correlate their activity as users move from network to network (such as home to work to coffee shop, etc), inside and outside of Tor. To handle this and to help satisfy our <link linkend="state">State Separation Requirement</link>, we currently toggle <command>security.enable_ssl2</command>, which clears the SSL Session ID cache via the pref observer at <ulink url="http://mxr.mozilla.org/security/source/security/manager/ssl/src/nsNSSComponent.cpp#2134">nsNSSComponent.cpp line 2134</ulink>. This is an arcane and potentially fragile fix. It would be better if there were a more standard interface for accomplishing the same thing. <link linkend="FirefoxBugs">Firefox Bug</link> <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=448747">448747</ulink> has been filed for this. </para> </listitem> <listitem><command><ulink url="http://www.mozilla.com/en-US/firefox/geolocation/">geo.enabled</ulink></command> <para> Torbutton disables Geolocation support in Firefox 3.5 and above whenever tor is enabled. This helps Torbutton maintain its <link linkend="location">Location Neutrality</link> requirement. While Firefox does prompt before divulging geolocational information, the assumption is that Tor users will never want to give their location away during Tor usage, and even allowing websites to prompt them to do so will only cause confusion and accidents to happen. Moreover, just because users may approve a site to know their location in non-Tor mode does not mean they want it divulged during Tor mode. </para> </listitem> <listitem><command><ulink url="http://kb.mozillazine.org/Browser.zoom.siteSpecific">browser.zoom.siteSpecific</ulink></command> <para> Firefox actually remembers your zoom settings for certain sites. CSS and Javascript rule can use this to recognize previous visitors to a site. This helps Torbutton fulfill its <link linkend="state">State Separation</link> requirement. </para> </listitem> <listitem><command><ulink url="https://developer.mozilla.org/en/controlling_dns_prefetching">network.dns.disablePrefetch</ulink></command> <para> Firefox 3.5 and above implement prefetching of DNS resolution for hostnames in links on a page to decrease page load latency. While Firefox does typically disable this behavior when proxies are enabled, we set this pref for added safety during Tor usage. Additionally, to prevent Tor-loaded tabs from having their links prefetched after a toggle to Non-Tor mode occurs, we also set the docShell attribute <ulink url="http://www.oxymoronical.com/experiments/apidocs/interface/nsIDocShell"> allowDNSPrefetch</ulink> to false on Tor loaded tabs. This happens in the same positions in the code as those for disabling plugins via the allowPlugins docShell attribute. This helps Torbutton fulfill its <link linkend="isolation">Network Isolation</link> requirement. </para> </listitem> <listitem><command><ulink url="http://kb.mozillazine.org/Browser.cache.offline.enable">browser.cache.offline.enable</ulink></command> <para> Firefox has the ability to store web applications in a special cache to allow them to continue to operate while the user is offline. Since this subsystem is actually different than the normal disk cache, it must be dealt with separately. Thus, Torbutton sets this preference to false whenever Tor is enabled. This helps Torbutton fulfill its <link linkend="disk">Disk Avoidance</link> and <link linkend="state">State Separation</link> requirements. </para> </listitem> <!-- FIXME: We should make it possible to search for ALL modified FF prefs --> </orderedlist> </sect2> <sect2> <title>Preferences Window - <ulink url="https://git.torproject.org/checkout/torbutton/master/src/chrome/content/preferences.xul">preferences.xul</ulink></title> <para>The preferences window of course lays out the Torbutton preferences, with handlers located in <ulink url="https://git.torproject.org/checkout/torbutton/master/src/chrome/content/preferences.js">chrome/content/preferences.js</ulink>.</para> </sect2> <sect2> <title>Other Windows</title> <para>There are additional windows that describe popups for right clicking on the status bar, the toolbutton, and the about page.</para> </sect2> </sect1> <sect1> <title>Toggle Code Path</title> <para> The act of toggling is connected to <function>torbutton_toggle()</function> via the <ulink url="https://git.torproject.org/checkout/torbutton/master/src/chrome/content/torbutton.xul">torbutton.xul</ulink> and <ulink url="https://git.torproject.org/checkout/torbutton/master/src/chrome/content/popup.xul">popup.xul</ulink> overlay files. Most of the work in the toggling process is present in <ulink url="https://git.torproject.org/checkout/torbutton/master/src/chrome/content/torbutton.js">torbutton.js</ulink> </para> <para> Toggling is a 3 stage process: Button Click, Proxy Update, and Settings Update. These stages are reflected in the prefs <command>extensions.torbutton.tor_enabled</command>, <command>extensions.torbutton.proxies_applied</command>, and <command>extensions.torbutton.settings_applied</command>. The reason for the three stage preference update is to ensure immediate enforcement of <link linkend="isolation">Network Isolation</link> via the <link linkend="contentpolicy">content policy</link>. Since the content window javascript runs on a different thread than the chrome javascript, it is important to properly convey the stages to the content policy to avoid race conditions and leakage, especially with <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=409737">Firefox Bug 409737</ulink> unfixed. The content policy does not allow any network activity whatsoever during this three stage transition. </para> <sect2> <title>Button Click</title> <para> This is the first step in the toggling process. When the user clicks the toggle button or the toolbar, <function>torbutton_toggle()</function> is called. This function checks the current Tor status by comparing the current proxy settings to the selected Tor settings, and then sets the proxy settings to the opposite state, and sets the pref <command>extensions.torbutton.tor_enabled</command> to reflect the new state. It is this proxy pref update that gives notification via the <ulink url="https://developer.mozilla.org/en/NsIPrefBranch2#addObserver.28.29">pref observer</ulink> <command>torbutton_unique_pref_observer</command> to perform the rest of the toggle. </para> </sect2> <sect2> <title>Proxy Update</title> <para> When Torbutton receives any proxy change notifications via its <command>torbutton_unique_pref_observer</command>, it calls <function>torbutton_set_status()</function> which checks against the Tor settings to see if the Tor proxy settings match the current settings. If so, it calls <function>torbutton_update_status()</function>, which determines if the Tor state has actually changed, and sets <command>extensions.torbutton.proxies_applied</command> to the appropriate Tor state value, and ensures that <command>extensions.torbutton.tor_enabled</command> is also set to the correct value. This is decoupled from the button click functionalty via the pref observer so that other addons (such as SwitchProxy) can switch the proxy settings between multiple proxies. </para> </sect2> <sect2> <title>Settings Update</title> <para> The next stage is also handled by <function>torbutton_update_status()</function>. This function sets scores of Firefox preferences, saving the original values to prefs under <command>extensions.torbutton.saved.*</command>, and performs the history clearing, cookie jaring, and ssl certificate jaring work of Torbutton. At the end of its work, it sets <command>extensions.torbutton.settings_applied</command>, which signifies the completion of the toggle operation to the <link linkend="contentpolicy">content policy</link>. </para> </sect2> </sect1> <sect1> <title>Description of Options</title> <!-- FIXME: Review+update these during FF3.5 audit --> <para>This section provides a detailed description of Torbutton's options. Each option is presented as the string from the preferences window, a summary, the preferences it touches, and the effect this has on the components, chrome, and browser properties.</para> <sect2> <title>Test Settings</title> <para> This button under the Proxy Settings tab provides a way to verify that the proxy settings are correct, and actually do route through the Tor network. It performs this check by issuing an <ulink url="http://developer.mozilla.org/en/docs/XMLHttpRequest">XMLHTTPRequest</ulink> for <ulink url="https://check.torproject.org/?TorButton=True">https://check.torproject.org/?Torbutton=True</ulink>. This is a special page that returns very simple, yet well-formed XHTML that Torbutton can easily inspect for a hidden link with an id of <command>TorCheckResult</command> and a target of <command>success</command> or <command>failure</command> to indicate if the user hit the page from a Tor IP, a non-Tor IP. This check is handled in <function>torbutton_test_settings()</function> in <ulink url="https://git.torproject.org/checkout/torbutton/master/src/chrome/content/torbutton.js">torbutton.js</ulink>. Presenting the results to the user is handled by the <ulink url="https://git.torproject.org/checkout/torbutton/master/src/chrome/content/preferences.xul">preferences window</ulink> callback <function>torbutton_prefs_test_settings()</function> in <ulink url="https://git.torproject.org/checkout/torbutton/master/src/chrome/content/preferences.js">preferences.js</ulink>. </para> </sect2> <sect2 id="plugins"> <title>Disable plugins on Tor Usage (crucial)</title> <para>Option: <command>extensions.torbutton.no_tor_plugins</command></para> <para>Java and plugins <ulink url="http://java.sun.com/j2se/1.5.0/docs/api/java/net/class-use/NetworkInterface.html">can query</ulink> the <ulink url="http://www.rgagnon.com/javadetails/java-0095.html">local IP address</ulink> and report it back to the remote site. They can also <ulink url="http://decloak.net">bypass proxy settings</ulink> and directly connect to a remote site without Tor. Every browser plugin we have tested with Firefox has some form of network capability, and every one ignores proxy settings or worse - only partially obeys them. This includes but is not limited to: QuickTime, Windows Media Player, RealPlayer, mplayerplug-in, AcroRead, and Flash. </para> <para> Enabling this preference causes the above mentioned Torbutton chrome web progress listener <command>torbutton_weblistener</command> to disable Java via <command>security.enable_java</command> and to disable plugins via the browser <ulink url="https://developer.mozilla.org/en/XUL%3aProperty%3adocShell">docShell</ulink> attribute <command>allowPlugins</command>. These flags are set every time a new window is created (<function>torbutton_tag_new_browser()</function>), every time a web load event occurs (<function>torbutton_update_tags()</function>), and every time the tor state is changed (<function>torbutton_update_status()</function>). As a backup measure, plugins are also prevented from loading by the content policy in <ulink url="https://git.torproject.org/checkout/torbutton/master/src/components/cssblocker.js">@torproject.org/cssblocker;1</ulink> if Tor is enabled and this option is set. </para> <para>All of this turns out to be insufficient if the user directly clicks on a plugin-handled mime-type. <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=401296">In this case</ulink>, the browser decides that maybe it should ignore all these other settings and load the plugin anyways, because maybe the user really did want to load it (never mind this same load-style could happen automatically with meta-refresh or any number of other ways..). To handle these cases, Torbutton stores a list of plugin-handled mime-types, and sets the pref <command>plugin.disable_full_page_plugin_for_types</command> to this list. Additionally, (since nothing can be assumed when relying on Firefox preferences and internals) if it detects a load of one of them from the web progress listener, it cancels the request, tells the associated DOMWindow to stop loading, clears the document, AND throws an exception. Anything short of all this and the plugin managed to find some way to load. </para> <!-- FIXME: Hrmm, technically this behavior is not covered by this pref. <para> Furthermore, with version 3.0 and above, Firefox <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=440892">began ignoring</ulink> <ulink url="http://kb.mozillazine.org/Network.protocol-handler.warn-external.%28protocol%29">network.protocol-handler.warn-external.(protocol)</ulink> prefs, which caused us to have to <link linkend="appblocker">wrap the external app launcher components</link> to prevent external apps from being loaded to bypass proxy settings. </para> --> <para> All this could be avoided, of course, if Firefox would either <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=401296">obey allowPlugins</ulink> for directly visited URLs, or notify its content policy for such loads either <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=309524">via</ulink> <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=380556">shouldProcess</ulink> or shouldLoad. The fact that it does not is not very encouraging. </para> <para> Since most plugins completely ignore browser proxy settings, the actions performed by this setting are crucial to satisfying the <link linkend="proxy">Proxy Obedience</link> requirement. </para> </sect2> <sect2> <title>Isolate Dynamic Content to Tor State (crucial)</title> <para>Option: <command>extensions.torbutton.isolate_content</command></para> <para>Enabling this preference is what enables the <ulink url="https://git.torproject.org/checkout/torbutton/master/src/components/cssblocker.js">@torproject.org/cssblocker;1</ulink> content policy mentioned above, and causes it to block content load attempts in pages an opposite Tor state from the current state. Freshly loaded <ulink url="https://developer.mozilla.org/en/XUL/tabbrowser">browser tabs</ulink> are tagged with a <command>__tb_load_state</command> member in <function>torbutton_update_tags()</function> and this value is compared against the current tor state in the content policy.</para> <para>It also kills all Javascript in each page loaded under that state by toggling the <command>allowJavascript</command> <ulink url="https://developer.mozilla.org/en/XUL%3aProperty%3adocShell">docShell</ulink> property, and issues a <ulink url="https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIWebNavigation#stop()">webNavigation.stop(webNavigation.STOP_ALL)</ulink> to each browser tab (the equivalent of hitting the STOP button).</para> <para> Unfortunately, <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=409737">Firefox bug 409737</ulink> prevents <command>docShell.allowJavascript</command> from killing all event handlers, and event handlers registered with <ulink url="http://developer.mozilla.org/en/docs/DOM:element.addEventListener">addEventListener()</ulink> are still able to execute. The <link linkend="contentpolicy">Torbutton Content Policy</link> should prevent such code from performing network activity within the current tab, but activity that happens via a popup window or via a Javascript redirect can still slip by. For this reason, Torbutton blocks popups by checking for a valid <ulink url="http://developer.mozilla.org/en/docs/DOM:window.opener">window.opener</ulink> attribute in <function>torbutton_check_progress()</function>. If the window has an opener from a different Tor state, its load is blocked. The content policy also takes similar action to prevent Javascript redirects. This also has the side effect/feature of preventing the user from following any links from a page loaded in an opposite Tor state. </para> <para> This setting is responsible for satisfying the <link linkend="isolation">Network Isolation</link> requirement. </para> </sect2> <sect2 id="jshooks"> <title>Hook Dangerous Javascript</title> <para>Option: <command>extensions.torbutton.kill_bad_js</command></para> <para>This setting enables injection of the <ulink url="https://git.torproject.org/checkout/torbutton/master/src/chrome/content/jshooks.js">Javascript hooking code</ulink>. This is done in the chrome in <function>torbutton_hookdoc()</function>, which is called ultimately by both the <ulink url="https://developer.mozilla.org/en/nsIWebProgressListener">webprogress listener</ulink> <command>torbutton_weblistener</command> and the <link linkend="contentpolicy">content policy</link> (the latter being a hack to handle javascript: urls). In the Firefox 2 days, this option did a lot more than it does now. It used to be responsible for timezone and improved useragent spoofing, and history object cloaking. However, now it only provides obfuscation of the <ulink url="https://developer.mozilla.org/en/DOM/window.screen">window.screen</ulink> object to mask your browser and desktop resolution. The resolution hooks effectively make the Firefox browser window appear to websites as if the renderable area takes up the entire desktop, has no toolbar or other GUI element space, and the desktop itself has no toolbars. These hooks drastically reduce the amount of information available to do <link linkend="fingerprinting">anonymity set reduction attacks</link> and help to meet the <link linkend="setpreservation">Anonymity Set Preservation</link> requirements. Unfortunately, Gregory Fleischer discovered it is still possible to retrieve the original screen values by using <ulink url="http://pseudo-flaw.net/tor/torbutton/unmask-sandbox-xpcnativewrapper.html">XPCNativeWrapper</ulink> or <ulink url="http://pseudo-flaw.net/tor/torbutton/unmask-components-lookupmethod.html">Components.lookupMethod</ulink>. We are still looking for a workaround as of Torbutton 1.2.4. <!-- FIXME: Don't forget to update this --> </para> </sect2> <sect2> <title>Resize windows to multiples of 50px during Tor usage (recommended)</title> <para>Option: <command>extensions.torbutton.resize_windows</command></para> <para> This option drastically cuts down on the number of distinct anonymity sets that divide the Tor web userbase. Without this setting, the dimensions for a typical browser window range from 600-1200 horizontal pixels and 400-1000 vertical pixels, or about 600x600 = 360000 different sets. Resizing the browser window to multiples of 50 on each side reduces the number of sets by 50^2, bringing the total number of sets to 144. Of course, the distribution among these sets are not uniform, but scaling by 50 will improve the situation due to this non-uniformity for users in the less common resolutions. Obviously the ideal situation would be to lie entirely about the browser window size, but this will likely cause all sorts of rendering issues, and is also not implementable in a foolproof way from extension land. </para> <para> The implementation of this setting is spread across a couple of different locations in the Torbutton javascript <link linkend="browseroverlay">browser overlay</link>. Since resizing minimized windows causes them to be restored, and since maximized windows remember their previous size to the pixel, windows must be resized before every document load (at the time of browser tagging) via <function>torbutton_check_round()</function>, called by <function>torbutton_update_tags()</function>. To prevent drift, the extension tracks the original values of the windows and uses this to perform the rounding on document load. In addition, to prevent the user from resizing a window to a non-50px multiple, a resize listener (<function>torbutton_do_resize()</function>) is installed on every new browser window to record the new size and round it to a 50px multiple while Tor is enabled. In all cases, the browser's contentWindow.innerWidth and innerHeight are set. This ensures that there is no discrepancy between the 50 pixel cutoff and the actual renderable area of the browser (so that it is not possible to infer toolbar size/presence by the distance to the nearest 50 pixel roundoff). </para> <para> This setting helps to meet the <link linkend="setpreservation">Anonymity Set Preservation</link> requirements. </para> </sect2> <sect2> <title>Disable Updates During Tor</title> <para>Option: <command>extensions.torbutton.no_updates</command></para> <para>This setting causes Torbutton to disable the four <ulink url="http://wiki.mozilla.org/Update:Users/Checking_For_Updates#Preference_Controls_and_State">Firefox update settings</ulink> during Tor usage: <command>extensions.update.enabled</command>, <command>app.update.enabled</command>, <command>app.update.auto</command>, and <command>browser.search.update</command>. These prevent the browser from updating extensions, checking for Firefox upgrades, and checking for search plugin updates while Tor is enabled. </para> <para> This setting satisfies the <link linkend="updates">Update Safety</link> requirement. </para> </sect2> <sect2> <title>Disable Search Suggestions during Tor (recommended)</title> <para>Option: <command>extensions.torbutton.no_search</command></para> <para> This setting causes Torbutton to disable <ulink url="http://kb.mozillazine.org/Browser.search.suggest.enabled"><command>browser.search.suggest.enabled</command></ulink> during Tor usage. This governs if you get Google search suggestions during Tor usage. Your Google cookie is transmitted with google search suggestions, hence this is recommended to be disabled. </para> <para> While this setting doesn't satisfy any Torbutton requirements, the fact that cookies are transmitted for partially typed queries does not seem desirable for Tor usage. </para> </sect2> <sect2> <title>Disable livemarks updates during Tor usage (recommended)</title> <para>Option: <simplelist> <member><command>extensions.torbutton.disable_livemarks</command></member> </simplelist> </para> <para> This option causes Torbutton to prevent Firefox from loading <ulink url="http://www.mozilla.com/firefox/livebookmarks.html">Livemarks</ulink> during Tor usage. Because people often have very personalized Livemarks (such as RSS feeds of Wikipedia articles they maintain, etc). This is accomplished both by <link linkend="livemarks">wrapping the livemark-service component</link> and by calling stopUpdateLivemarks() on the <ulink url="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/components/%40mozilla.org/browser/livemark-service;2">Livemark service</ulink> when Tor is enabled. </para> <para> This helps satisfy the <link linkend="isolation">Network Isolation</link> and <link linkend="setpreservation">Anonymity Set Preservation</link> requirements. </para> </sect2> <sect2> <title>Block Tor/Non-Tor access to network from file:// urls (recommended)</title> <para>Options: <simplelist> <member><command>extensions.torbutton.block_tor_file_net</command></member> <member><command>extensions.torbutton.block_nontor_file_net</command></member> </simplelist> </para> <para> These settings prevent file urls from performing network operations during the respective Tor states. Firefox 2's implementation of same origin policy allows file urls to read and <ulink url="http://www.gnucitizen.org/blog/content-disposition-hacking/">submit arbitrary files from the local filesystem</ulink> to arbitrary websites. To make matters worse, the 'Content-Disposition' header can be injected arbitrarily by exit nodes to trick users into running arbitrary html files in the local context. These preferences cause the <link linkend="contentpolicy">content policy</link> to block access to any network resources from File urls during the appropriate Tor state. </para> <para> This preference helps to ensure Tor's <link linkend="isolation">Network Isolation</link> requirement, by preventing file urls from executing network operations in opposite Tor states. Also, allowing pages to submit arbitrary files to arbitrary sites just generally seems like a bad idea. </para> </sect2> <sect2> <title>Close all Tor/Non-Tor tabs and windows on toggle (optional)</title> <para>Options: <simplelist> <member><command>extensions.torbutton.close_nontor</command></member> <member><command>extensions.torbutton.close_tor</command></member> </simplelist> </para> <para> These settings cause Torbutton to enumerate through all windows and close all tabs in each window for the appropriate Tor state. This code can be found in <function>torbutton_update_status()</function>. The main reason these settings exist is as a backup mechanism in the event of any Javascript or content policy leaks due to <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=409737">Firefox Bug 409737</ulink>. Torbutton currently tries to block all Javascript network activity via the content policy, but until that bug is fixed, there is some risk that there are alternate ways to bypass the policy. This option is available as an extra assurance of <link linkend="isolation">Network Isolation</link> for those who would like to be sure that when Tor is toggled all page activity has ceased. It also serves as a potential future workaround in the event a content policy failure is discovered, and provides an additional level of protection for the <link linkend="disk">Disk Avoidance</link> protection so that browser state is not sitting around waiting to be swapped out longer than necessary. </para> <para> While this setting doesn't satisfy any Torbutton requirements, the fact that cookies are transmitted for partially typed queries does not seem desirable for Tor usage. </para> </sect2> <sect2> <title>Isolate Access to History navigation to Tor state (crucial)</title> <para>Option: <command>extensions.torbutton.block_js_history</command></para> <para> This setting determines if Torbutton installs an <ulink url="http://www.oxymoronical.com/experiments/apidocs/interface/nsISHistoryListener">nsISHistoryListener</ulink> attached to the <ulink url="http://www.oxymoronical.com/experiments/apidocs/interface/nsISHistory">sessionHistory</ulink> of of each browser's <ulink url="https://developer.mozilla.org/en/XUL%3aProperty%3awebNavigation">webNavigatator</ulink>. The nsIShistoryListener is instantiated with a reference to the containing browser window and blocks the back, forward, and reload buttons on the browser navigation bar when Tor is in an opposite state than the one to load the current tab. In addition, Tor clears the session history during a new document load if this setting is enabled. </para> <para> This is marked as a crucial setting in part because Javascript access to the history object is indistinguishable from user clicks, and because <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=409737">Firefox Bug 409737</ulink> allows javascript to execute in opposite Tor states, javascript can issue reloads after Tor toggle to reveal your original IP. Even without this bug, however, Javascript is still able to access previous pages in your session history that may have been loaded under a different Tor state, to attempt to correlate your activity. </para> <para> This setting helps to fulfill Torbutton's <link linkend="state">State Separation</link> and (until Bug 409737 is fixed) <link linkend="isolation">Network Isolation</link> requirements. </para> </sect2> <sect2> <title>History Access Settings</title> <para>Options: <simplelist> <member><command>extensions.torbutton.block_thread</command></member> <member><command>extensions.torbutton.block_nthread</command></member> <member><command>extensions.torbutton.block_thwrite</command></member> <member><command>extensions.torbutton.block_nthwrite</command></member> </simplelist> </para> <para>These four settings govern the behavior of the <ulink url="https://git.torproject.org/checkout/torbutton/master/src/components/ignore-history.js">components/ignore-history.js</ulink> history blocker component mentioned above. By hooking the browser's view of the history itself via the <ulink url="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/components/%40mozilla.org/browser/global-history;2">@mozilla.org/browser/global-history;2</ulink> and <ulink url="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/components/%40mozilla.org/browser/nav-history-service;1">@mozilla.org/browser/nav-history-service;1</ulink> components, this mechanism defeats all document-based <ulink url="http://whattheinternetknowsaboutyou.com/">history disclosure attacks</ulink>, including <ulink url="http://ha.ckers.org/weird/CSS-history.cgi">CSS-only attacks</ulink>. The component also hooks functions involved in writing history to disk via both the <ulink url="http://developer.mozilla.org/en/docs/Places_migration_guide#History">Places Database</ulink> and the older Firefox 2 mechanisms. </para> <para> This setting helps to satisfy the <link linkend="state">State Separation</link> and <link linkend="disk">Disk Avoidance</link> requirements. </para> </sect2> <sect2> <title>Clear History During Tor Toggle (optional)</title> <para>Option: <command>extensions.torbutton.clear_history</command></para> <para>This setting governs if Torbutton calls <ulink url="https://developer.mozilla.org/en/nsIBrowserHistory#removeAllPages.28.29">nsIBrowserHistory.removeAllPages</ulink> and <ulink url="http://www.oxymoronical.com/experiments/apidocs/interface/nsISHistory">nsISHistory.PurgeHistory</ulink> for each tab on Tor toggle.</para> <para> This setting is an optional way to help satisfy the <link linkend="state">State Separation</link> requirement. </para> </sect2> <sect2> <title>Block Password+Form saving during Tor/Non-Tor</title> <para>Options: <simplelist> <member><command>extensions.torbutton.block_tforms</command></member> <member><command>extensions.torbutton.block_ntforms</command></member> </simplelist> </para> <para>These settings govern if Torbutton disables <command>browser.formfill.enable</command> and <command>signon.rememberSignons</command> during Tor and Non-Tor usage. Since form fields can be read at any time by Javascript, this setting is a lot more important than it seems. </para> <para> This setting helps to satisfy the <link linkend="state">State Separation</link> and <link linkend="disk">Disk Avoidance</link> requirements. </para> </sect2> <sect2> <title>Block Tor disk cache and clear all cache on Tor Toggle</title> <para>Option: <command>extensions.torbutton.clear_cache</command> </para> <para>This option causes Torbutton to call <ulink url="https://developer.mozilla.org/en/nsICacheService#evictEntries.28.29">nsICacheService.evictEntries(0)</ulink> on Tor toggle to remove all entries from the cache. In addition, this setting causes Torbutton to set <ulink url="http://kb.mozillazine.org/Browser.cache.disk.enable">browser.cache.disk.enable</ulink> to false. </para> <para> This setting helps to satisfy the <link linkend="state">State Separation</link> and <link linkend="disk">Disk Avoidance</link> requirements. </para> </sect2> <sect2> <title>Block disk and memory cache during Tor</title> <para>Option: <command>extensions.torbutton.block_cache</command></para> <para>This setting causes Torbutton to set <ulink url="http://kb.mozillazine.org/Browser.cache.memory.enable">browser.cache.memory.enable</ulink>, <ulink url="http://kb.mozillazine.org/Browser.cache.disk.enable">browser.cache.disk.enable</ulink> and <ulink url="http://kb.mozillazine.org/Network.http.use-cache">network.http.use-cache</ulink> to false during tor usage. </para> <para> This setting helps to satisfy the <link linkend="state">State Separation</link> and <link linkend="disk">Disk Avoidance</link> requirements. </para> </sect2> <sect2> <title>Clear Cookies on Tor Toggle</title> <para>Option: <command>extensions.torbutton.clear_cookies</command> </para> <para> This setting causes Torbutton to call <ulink url="https://developer.mozilla.org/en/nsICookieManager#removeAll.28.29">nsICookieManager.removeAll()</ulink> on every Tor toggle. In addition, this sets <ulink url="http://kb.mozillazine.org/Network.cookie.lifetimePolicy">network.cookie.lifetimePolicy</ulink> to 2 for Tor usage, which causes all cookies to be demoted to session cookies, which prevents them from being written to disk. </para> <para> This setting helps to satisfy the <link linkend="state">State Separation</link> and <link linkend="disk">Disk Avoidance</link> requirements. </para> </sect2> <sect2> <title>Store Non-Tor cookies in a protected jar</title> <para>Option: <command>extensions.torbutton.cookie_jars</command> </para> <para> This setting causes Torbutton to use <ulink url="https://git.torproject.org/checkout/torbutton/master/src/components/cookie-jar-selector.js">@torproject.org/cookie-jar-selector;2</ulink> to store non-tor cookies in a cookie jar during Tor usage, and clear the Tor cookies before restoring the jar. </para> <para> This setting also sets <ulink url="http://kb.mozillazine.org/Network.cookie.lifetimePolicy">network.cookie.lifetimePolicy</ulink> to 2 for Tor usage, which causes all cookies to be demoted to session cookies, which prevents them from being written to disk. </para> <para> This setting helps to satisfy the <link linkend="state">State Separation</link> and <link linkend="disk">Disk Avoidance</link> requirements. </para> </sect2> <sect2> <title>Store both Non-Tor and Tor cookies in a protected jar (dangerous)</title> <para>Option: <command>extensions.torbutton.dual_cookie_jars</command> </para> <para> This setting causes Torbutton to use <ulink url="https://git.torproject.org/checkout/torbutton/master/src/components/cookie-jar-selector.js">@torproject.org/cookie-jar-selector;2</ulink> to store both Tor and Non-Tor cookies into protected jars. </para> <para> This setting helps to satisfy the <link linkend="state">State Separation</link> requirement. </para> </sect2> <sect2> <title>Manage My Own Cookies (dangerous)</title> <para>Options: None</para> <para>This setting disables all Torbutton cookie handling by setting the above cookie prefs all to false.</para> </sect2> <sect2> <sect2> <title>Do not write Tor/Non-Tor cookies to disk</title> <para>Options: <simplelist> <member><command>extensions.torbutton.tor_memory_jar</command></member> <member><command>extensions.torbutton.nontor_memory_jar</command></member> </simplelist> </para> <para> These settings (contributed by arno) cause Torbutton to set <ulink url="http://kb.mozillazine.org/Network.cookie.lifetimePolicy">network.cookie.lifetimePolicy</ulink> to 2 during the appropriate Tor state, and to store cookies acquired in that state into a Javascript <ulink url="http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Processing_XML_with_E4X">E4X</ulink> object as opposed to writing them to disk. </para> <para> This allows Torbutton to provide an option to preserve a user's cookies while still satisfying the <link linkend="disk">Disk Avoidance</link> requirement. </para> </sect2> <title>Disable DOM Storage during Tor usage (crucial)</title> <para>Option: <command>extensions.torbutton.disable_domstorage</command> </para> <para> This setting causes Torbutton to toggle <command>dom.storage.enabled</command> during Tor usage to prevent <ulink url="http://developer.mozilla.org/en/docs/DOM:Storage">DOM Storage</ulink> from being used to store persistent information across Tor states.</para> <para> This setting helps to satisfy the <link linkend="state">State Separation</link> requirement. </para> </sect2> <sect2> <title>Clear HTTP Auth on Tor Toggle (recommended)</title> <para>Option: <command>extensions.torbutton.clear_http_auth</command> </para> <para> This setting causes Torbutton to call <ulink url="http://www.oxymoronical.com/experiments/apidocs/interface/nsIHttpAuthManager">nsIHttpAuthManager.clearAll()</ulink> every time Tor is toggled. </para> <para> This setting helps to satisfy the <link linkend="state">State Separation</link> requirement. </para> </sect2> <sect2> <title>Clear cookies on Tor/Non-Tor shutdown</title> <para>Option: <command>extensions.torbutton.shutdown_method</command> </para> <para> This option variable can actually take 3 values: 0, 1, and 2. 0 means no cookie clearing, 1 means clear only during Tor-enabled shutdown, and 2 means clear for both Tor and Non-Tor shutdown. When set to 1 or 2, Torbutton listens for the <ulink url="http://developer.mozilla.org/en/docs/Observer_Notifications#Application_shutdown">quit-application-granted</ulink> event in <function>torbutton_uninstall_observer()</function> and use <ulink url="https://git.torproject.org/checkout/torbutton/master/src/components/cookie-jar-selector.js">@torproject.org/cookie-jar-selector;2</ulink> to clear out all cookies and all cookie jars upon shutdown. </para> <para> This setting helps to satisfy the <link linkend="state">State Separation</link> requirement. </para> </sect2> <sect2> <title>Reload cookie jar/clear cookies on Firefox crash</title> <para>Options: <simplelist> <member><command>extensions.torbutton.reload_crashed_jar</command></member> <member><command>extensions.torbutton.crashed</command></member> </simplelist> </para> <para>This is no longer a user visible option, and is enabled by default. In the event of a crash, the Torbutton <ulink url="https://git.torproject.org/checkout/torbutton/master/src/components/crash-observer.js">components/crash-observer.js</ulink> component will notify the Chrome (via the <command>extensions.torbutton.crashed</command> pref and a <ulink url="https://developer.mozilla.org/en/NsIPrefBranch2#addObserver.28.29">pref observer</ulink> in the chrome that listens for this update), and Torbutton will load the correct jar for the current Tor state via the <ulink url="https://git.torproject.org/checkout/torbutton/master/src/components/cookie-jar-selector.js">@torproject.org/cookie-jar-selector;2</ulink> component.</para> <para> This setting helps to satisfy the <link linkend="state">State Separation</link> requirement in the event of Firefox crashes. </para> </sect2> <sect2> <title>On crash recovery or session restored startup, restore via: Tor, Non-Tor</title> <para>Options: <simplelist> <member><command>extensions.torbutton.restore_tor</command></member> <member><command>extensions.torbutton.crashed</command></member> <member><command>extensions.torbutton.normal_exit</command></member> </simplelist> </para> <para>This option works with the Torbutton <ulink url="https://git.torproject.org/checkout/torbutton/master/src/components/crash-observer.js">crash-observer.js</ulink> to set the Tor state after a crash is detected (via the <command>extensions.torbutton.crashed</command> pref). To confirm for false positives (such as session restore failures, upgrade, normal session restore, etc), Torbutton also sets the pref extensions.torbutton.normal_exit in torbutton_uninstall_observer() during Firefox exit and checks this value as well during startup. </para> <para> Since the Tor state after a Firefox crash is unknown/indeterminate, this setting helps to satisfy the <link linkend="state">State Separation</link> requirement in the event of Firefox crashes by ensuring all cookies, settings and saved sessions are reloaded from a fixed Tor state. </para> </sect2> <sect2> <title>On normal startup, set state to: Tor, Non-Tor, Shutdown State</title> <para>Options: <simplelist> <member><command>extensions.torbutton.startup_state</command></member> <member><command>extensions.torbutton.noncrashed</command></member> <member><command>extensions.torbutton.normal_exit</command></member> </simplelist> </para> <para>This option also works with the Torbutton <ulink url="https://git.torproject.org/checkout/torbutton/master/src/components/crash-observer.js">crash-observer.js</ulink> to set the Tor state after a normal startup is detected (via the <command>extensions.torbutton.noncrashed</command> pref). To confirm for false positives (such as session restore failures, etc), Torbutton also sets the pref extensions.torbutton.normal_exit in torbutton_uninstall_observer() during Firefox exit and checks this value as well during startup. </para> </sect2> <sect2> <title>Prevent session store from saving Non-Tor/Tor-loaded tabs</title> <para>Options: <simplelist> <member><command>extensions.torbutton.nonontor_sessionstore</command></member> <member><command>extensions.torbutton.notor_sessionstore</command></member> </simplelist> </para> <para>If these options are enabled, the <ulink url="https://git.torproject.org/checkout/torbutton/master/src/components/nsSessionStore3.js">replacement nsSessionStore.js</ulink> component checks the <command>__tb_tor_fetched</command> tag of tabs before writing them out. If the tag is from a blocked Tor state, the tab is not written to disk. </para> <para> This setting helps to satisfy the <link linkend="disk">Disk Avoidance</link> requirement, and also helps to satisfy the <link linkend="state">State Separation</link> requirement in the event of Firefox crashes. </para> </sect2> <sect2> <title>Set user agent during Tor usage (crucial)</title> <para>Options: <simplelist> <member><command>extensions.torbutton.set_uagent</command></member> <member><command>extensions.torbutton.platform_override</command></member> <member><command>extensions.torbutton.oscpu_override</command></member> <member><command>extensions.torbutton.buildID_override</command></member> <member><command>extensions.torbutton.productsub_override</command></member> <member><command>extensions.torbutton.appname_override</command></member> <member><command>extensions.torbutton.appversion_override</command></member> <member><command>extensions.torbutton.useragent_override</command></member> <member><command>extensions.torbutton.useragent_vendor</command></member> <member><command>extensions.torbutton.useragent_vendorSub</command></member> </simplelist> </para> <para>On face, user agent switching appears to be straight-forward in Firefox. It provides several options for controlling the browser user agent string: <command>general.appname.override</command>, <command>general.appversion.override</command>, <command>general.platform.override</command>, <command>general.oscpu.override</command>, <command>general.productSub.override</command>, <command>general.buildID.override</command>, <command>general.useragent.override</command>, <command>general.useragent.vendor</command>, and <command>general.useragent.vendorSub</command>. If the Torbutton preference <command>extensions.torbutton.set_uagent</command> is true, Torbutton copies all of the other above prefs into their corresponding browser preferences during Tor usage.</para> <para> It also turns out that it is possible to detect the original Firefox version by <ulink url="http://ha.ckers.org/blog/20070516/read-firefox-settings-poc/">inspecting certain resource:// files</ulink>. These cases are handled by Torbutton's <link linkend="contentpolicy">content policy</link>. </para> <para> This setting helps to satisfy the <link linkend="setpreservation">Anonymity Set Preservation</link> requirement. </para> </sect2> <sect2> <title>Spoof US English Browser</title> <para>Options: <simplelist> <member><command>extensions.torbutton.spoof_english</command></member> <member><command>extensions.torbutton.spoof_charset</command></member> <member><command>extensions.torbutton.spoof_language</command></member> </simplelist> </para> <para> This option causes Torbutton to set <command>general.useragent.locale</command> <command>intl.accept_languages</command> to the value specified in <command>extensions.torbutton.spoof_locale</command>, <command>extensions.torbutton.spoof_charset</command> and <command>extensions.torbutton.spoof_language</command> during Tor usage, as well as hooking <command>navigator.language</command> via its <link linkend="jshooks">javascript hooks</link>. </para> <para> This setting helps to satisfy the <link linkend="setpreservation">Anonymity Set Preservation</link> and <link linkend="location">Location Neutrality</link> requirements. </para> </sect2> <sect2> <title>Don't send referrer during Tor Usage</title> <para>Option: <command>extensions.torbutton.disable_referer</command> </para> <para> This option causes Torbutton to set <ulink url="http://kb.mozillazine.org/Network.http.sendSecureXSiteReferrer">network.http.sendSecureXSiteReferrer</ulink> and <ulink url="http://kb.mozillazine.org/Network.http.sendRefererHeader">network.http.sendRefererHeader</ulink> during Tor usage.</para> <para> This setting also does not directly satisfy any Torbutton requirement, but some may desire to mask their referrer for general privacy concerns. </para> </sect2> <sect2> <title>Store SSL/CA Certs in separate jars for Tor/Non-Tor (recommended)</title> <para>Options: <simplelist> <member><command>extensions.torbutton.jar_certs</command></member> <member><command>extensions.torbutton.jar_ca_certs</command></member> </simplelist> </para> <para> These settings govern if Torbutton attempts to isolate the user's SSL certificates into separate jars for each Tor state. This isolation is implemented in <function>torbutton_jar_certs()</function> in <ulink url="https://git.torproject.org/checkout/torbutton/master/src/chrome/content/torbutton.js">chrome/content/torbutton.js</ulink>, which calls <function>torbutton_jar_cert_type()</function> and <function>torbutton_unjar_cert_type()</function> for each certificate type in the <ulink url="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/components/%40mozilla.org/security/nsscertcache;1">@mozilla.org/security/nsscertcache;1</ulink>. Certificates are deleted from and imported to the <ulink url="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/components/%40mozilla.org/security/x509certdb;1">@mozilla.org/security/x509certdb;1</ulink>. </para> <para> The first time this pref is used, a backup of the user's certificates is created in their profile directory under the name <filename>cert8.db.bak</filename>. This file can be copied back to <filename>cert8.db</filename> to fully restore the original state of the user's certificates in the event of any error. </para> <para> Since exit nodes and malicious sites can insert content elements sourced to specific SSL sites to query if a user has a certain certificate, this setting helps to satisfy the <link linkend="state">State Separation</link> requirement of Torbutton. Unfortunately, <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=435159">Firefox Bug 435159</ulink> prevents it from functioning correctly in the event of rapid Tor toggle, so it is currently not exposed via the preferences UI. </para> </sect2> </sect1> <sect1 id="FirefoxBugs"> <title>Relevant Firefox Bugs</title> <para> </para> <sect2 id="FirefoxSecurity"> <title>Bugs impacting security</title> <para> Torbutton has to work around a number of Firefox bugs that impact its security. Most of these are mentioned elsewhere in this document, but they have also been gathered here for reference. Several of these have fixes in Firefox3.0/trunk, but are listed because they still have not been backported to FF2.0. In order of decreasing severity, they are: </para> <orderedlist> <listitem><ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=392274">Bug 392274 - Timezone config/chrome API</ulink> <para> The lack of a config or API to configure the timezone requires Torbutton to <link linkend="jshooks">insert client content window javascript</link> to hook the Date object. Additionally, a way to <ulink url="http://pseudo-flaw.net/tor/torbutton/unmask-date.html">remove the Date hooks</ulink> was discovered by Greg Fleischer. Worse, on Firefox 3, javascript sandboxing prevents most of the javascript hooks from being installed, including the Date hooks. On Windows and Linux, you can set the TZ environment variable to "UTC" as a workaround. Firefox will obey this environment variable for your Timezone on those platforms, but on Windows this does not take effect until browser restart. A fix for this has landed in Firefox 3.5, but still has not been backported to Firefox 3.0. The lack of an easy way to reliably spoof the timezone interferes with Torbutton's ability to fulfill its <link linkend="location">Location Neutrality</link> requirement. </para> </listitem> <!-- FIXME: This one is fixed, but we need to make use of the new API in FF3.5 <listitem><ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=436250">Bug 436250 - Livemarks can't be disabled at runtime</ulink> <para> The RSS Feed based "Livemarks"/"Live Bookmarks" update frequency is controlled by the pref <command>browser.bookmarks.livemark_refresh_seconds</command>. However, changing this preference does not cancel any pending timers, which means that at least one livemarks pref fetch will happen over Tor, and once this pref is set to disable livemarks for Tor, changing it back will never cause the service to start back up again. The leakage of Livemarks interferes with Torbutton's ability to fulfill the <link linkend="isolation">Network Isolation</link> requirement. </para> </listitem> --> <listitem><ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=435159">Bug 435159 - nsNSSCertificateDB::DeleteCertificate has race conditions</ulink> <para> In Torbutton 1.2.0rc1, code was added to attempt to isolate SSL certificates the user has installed. Unfortunately, the method call to delete a certificate from the current certificate database acts lazily: it only sets a variable that marks a cert for deletion later, and it is not cleared if that certificate is re-added. This means that if the Tor state is toggled quickly, that certificate could remain present until it is re-inserted (causing an error dialog), and worse, it would still be deleted after that. The lack of this functionality is considered a Torbutton security bug because cert isolation is considered a <link linkend="state">State Separation</link> feature. </para> </listitem> <listitem><ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=409737">Bug 409737 - javascript.enabled and docShell.allowJavascript do not disable all event handlers</ulink> <para> This bug allows pages to execute javascript via addEventListener and perhaps other callbacks. In order to prevent this bug from enabling an attacker to break the <link linkend="isolation">Network Isolation</link> requirement, Torbutton 1.1.13 began blocking popups and history manipulation from different Tor states. So long as there are no ways to open popups or redirect the user to a new page, the <link linkend="contentpolicy">Torbutton content policy</link> should block Javascript network access. However, if there are ways to open popups or perform redirects such that Torbutton cannot block them, pages may still have free reign to break that requirement and reveal a user's original IP address. </para> </listitem> <listitem><ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=448743">Bug 448743 - Decouple general.useragent.locale from spoofing of navigator.language</ulink> <para> Currently, Torbutton spoofs the <command>navigator.language</command> attribute via <link linkend="jshooks">Javascript hooks</link>. Unfortunately, these do not work on Firefox 3. It would be ideal to have a pref to set this value (something like a <command>general.useragent.override.locale</command>), to avoid fragmenting the anonymity set of users of foreign locales. This issue impedes Torbutton from fully meeting its <link linkend="setpreservation">Anonymity Set Preservation</link> requirement on Firefox 3. </para> </listitem> </orderedlist> </sect2> <sect2 id="FirefoxWishlist"> <title>Bugs blocking functionality</title> <para> The following bugs impact Torbutton and similar extensions' functionality. </para> <orderedlist> <listitem><ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=445696">Bug 445696 - Extensions cannot determine if firefox is fullScreen</ulink> <para> The windowState property of <ulink url="https://developer.mozilla.org/en/XUL/window">ChromeWindows</ulink> does not accurately reflect the true state of the window in some cases on Linux. This causes Torbutton to attempt to resize maximized and minimized windows when it should not. </para> </listitem> <listitem><ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=290456">Bug 290456 - Block/clear Flash MX "cookies" as well</ulink> <para> Today, it is possible to allow plugins if you have a transparent proxy such as <ulink url="http://anonymityanywhere.com/incognito/">Incognito</ulink> to prevent proxy bypass. However, flash cookies can still be used to link your Tor and Non-Tor activity, and this reveal your IP to an adversary that does so. This can be solved by manually removing your flash cookies (like <ulink url="https://addons.mozilla.org/en-US/firefox/addon/6623">BetterPrivacy</ulink> does), but it would be nice if there was a standard way to do this from a Firefox API. </para> </listitem> <listitem><ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=417869">Bug 417869 - Browser context is difficult to obtain from many XPCOM callbacks</ulink> <para> It is difficult to determine which tabbrowser many XPCOM callbacks originate from, and in some cases absolutely no context information is provided at all. While this doesn't have much of an effect on Torbutton, it does make writing extensions that would like to do per-tab settings and content filters (such as FoxyProxy) difficult to impossible to implement securely. </para> </listitem> <listitem><ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=418321">Bug 418321 - Components do not expose disk interfaces</ulink> <para> Several components currently provide no way of reimplementing their disk access to easily satisfy Torbutton's <link linkend="disk">Disk Avoidance</link> requirements. Workarounds exist, but they are <link linkend="sessionstore">clunky</link>, and some of them involve disabling functionality during Tor usage. </para> </listitem> <!-- FIXME: Need to use new observer methods if possible <listitem><ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=448741">Bug 448741 - nsISessionStore uses private methods and is not extensible</ulink> <para> Similar to the above bug, in the specific case of the sessionstore component, the API is not amenable to Contract ID hooking, and this requires that Torbutton include modified copies of this component for Firefox 2 and 3, which has <ulink url="https://bugs.torproject.org/flyspray/index.php?do=details&id=722">raised objections</ulink> from some developers. </para> </listitem> <listitem><ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=439384">Bug 439384 - "profile-do-change" event does not cause cookie table reload</ulink> <para> In Firefox 3, the change to the new SQLlite database for cookie storage has a bug that prevents Torbutton's cookie jaring from working properly. The "profile-do-change" observer event no longer properly causes either a sync or reload of the cookie database from disk after it is copied into place. Torbutton currently works around this by issuing the SQLLite queries manually to store and rebuild the cookie database. </para> </listitem> <listitem><ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=248970">Bug 248970 (PrivateBrowsing) - Private Browsing mode (global toggle for saving/caching everything)</ulink> <para> This bug catalogs the discussion of a 'Private Mode' in Firefox that would perform many, but not all, of the activities of Torbutton. It would be useful to leverage the resulting setting to simplify Torbutton. This bug is listed so we can track this progress and ensure that it doesn't end up defining behaviors contrary to and incompatible with Torbutton's requirements (though a subset of the <link linkend="requirements">requirements</link> is of course fine). </para> </listitem> --> </orderedlist> </sect2> <sect2 id="FirefoxMiscBugs"> <title>Low Priority Bugs</title> <para> The following bugs have an effect upon Torbutton, but are superseded by more practical and more easily fixable variant bugs above; or have stable, simple workarounds. </para> <orderedlist> <listitem><ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=435151">Bug 435151 - XPCSafeJSObjectWrapper breaks evalInSandbox</ulink> <para> Under Firefox 3, the XPCSafeJSObjectWrapper breaks when you try to use constructors of classes defined from within the scope of the sandbox, among other things. This prevents Torbutton from applying the Timezone hooks under Firefox 3, but a better solution for Torbutton's specific date hooking needs would be a fix for the above mentioned Bug 392274. Of course, many more extensions may be interested in the sandbox hooking functionality working properly though. </para> </listitem> <listitem><ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=440892">Bug 440892 - network.protocol-handler.warn-external are ignored</ulink> <para> Sometime in the Firefox 3 development cycle, the preferences that governed warning a user when external apps were launched got disconnected from the code that does the launching. Torbutton depended on these prefs to prevent websites from launching specially crafted documents and application arguments that caused Proxy Bypass. We currently work around this issue by <link linkend="appblocker">wrapping the app launching components</link> to present a popup before launching external apps while Tor is enabled. While this works, it would be nice if these prefs were either fixed or removed. </para> </listitem> <listitem><ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=437014">Bug 437014 - nsIContentPolicy::shouldLoad no longer called for favicons</ulink> <para> Firefox 3.0 stopped calling the shouldLoad call of content policy for favicon loads. Torbutton had relied on this call to block favicon loads for opposite Tor states. The workaround it employs for Firefox 3 is to cancel the request when it arrives in the <command>torbutton_http_observer</command> used for blocking full page plugin loads. This seems to work just fine, but is a bit dirty. </para> </listitem> <!-- <listitem><ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=437016">Bug 437016 - nsIContentPolicy::shouldLoad not called for livemarks</ulink> <para> An alternative fix for the livemarks bug above would be to block livemarks fetches from the content policy. Unfortunately shouldLoad is not called for livemarks fetches. </para> </listitem> --> <listitem><ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=418986">Bug 418986 - window.screen provides a large amount of identifiable information</ulink> <para> As <link linkend="fingerprinting">mentioned above</link>, a large amount of information is available from <ulink url="http://developer.mozilla.org/en/docs/DOM:window.screen">window.screen</ulink>. Currently, there is no way to obscure this information without Javascript hooking. This bug is a feature request to provide some other method to change these values. </para> </listitem> <listitem><ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=309524">Bug 309524</ulink> and <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=380556">Bug 380556</ulink> - nsIContentPolicy::shouldProcess is not called. <para> This is a call that would be useful to develop a better workaround for the allowPlugins issue above. If the content policy were called before a URL was handed over to a plugin or helper app, it would make the workaround for the above allowPlugins bug a lot cleaner. Obviously this bug is not as severe as the others though, but it might be nice to have this API as a backup. </para> </listitem> <listitem><ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=401296">Bug 401296 - docShell.allowPlugins not honored for direct links</ulink> (Perhaps subset of <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=282106">Bug 282106</ulink>?) <para> Similar to the javascript plugin disabling attribute, the plugin disabling attribute is also not perfect — it is ignored for direct links to plugin handled content, as well as meta-refreshes to plugin handled content. This requires Torbutton to listen to a number of different http events to intercept plugin-related mime type URLs and cancel their requests. Again, since plugins are quite horrible about obeying proxy settings, loading a plugin pretty much ensures a way to break the <link linkend="isolation">Network Isolation</link> requirement and reveal a user's original IP address. Torbutton's code to perform this workaround has been subverted at least once already by Kyle Williams. </para> </listitem> <listitem><ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=448747">Bug 448747 - Provide Mechanism to clear TLS Session IDs</ulink> <para> As <link linkend="browseroverlay">mentioned above</link>, Torbutton currently toggles <command>security.enable_ssl2</command> to clear the SSL Session ID cache via the pref observer at <ulink url="http://mxr.mozilla.org/security/source/security/manager/ssl/src/nsNSSComponent.cpp#2134">nsNSSComponent.cpp line 2134</ulink>. This is an arcane and potentially fragile fix. It would be better if there were a more standard interface for accomplishing the same thing. </para> </listitem> <listitem><ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=419598">Bug 419598 - 'var Date' is deletable</ulink> <para> Based on Page 62 of the <ulink url="http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf">ECMA-262 Javascript spec</ulink>, it seems like it should be possible to do something like the following to prevent the Date object from being unmasked: <screen> with(window) { var Date = fakeDate; var otherVariable = 42; } delete window.Date; // Should fail. Instead succeeds, revealing original Date. delete window.otherVariable; // Fails, leaving window.otherVariable set to 42. </screen> From the ECMA-262 spec: <blockquote> If the variable statement occurs inside a FunctionDeclaration, the variables are defined with function-local scope in that function, as described in s10.1.3. Otherwise, they are defined with global scope (that is, they are created as members of the global object, as described in 10.1.3) using property attributes { DontDelete }. Variables are created when the execution scope is entered. A Block does not define a new execution scope. Only Program and FunctionDeclaration produce a new scope. Variables are initialized to undefined when created. A variable with an Initialiser is assigned the value of its AssignmentExpression when the VariableStatement is executed, not when the variable is created. </blockquote> In fact, this is exactly how the with statement with a variable declaration behaves <emphasis>for all other variables other than ones that shadow system variables</emphasis>. Some variables (such as <command>window.screen</command>, and <command>window.history</command>) can't even be shadowed in this way, and give an error about lacking a setter. If such shadowing were possible, it would greatly simplify the Javascript hooking code, which currently relies on undocumented semantics of <command>__proto__</command> to copy the original values in the event of a delete. This <command>__proto__</command> hack unfortunately does not work for the Date object though. </para> </listitem> </orderedlist> </sect2> </sect1> <sect1 id="TestPlan"> <title>Testing</title> <para> The purpose of this section is to cover all the known ways that Tor browser security can be subverted from a penetration testing perspective. The hope is that it will be useful both for creating a "Tor Safety Check" page, and for developing novel tests and actively attacking Torbutton with the goal of finding vulnerabilities in either it or the Mozilla components, interfaces and settings upon which it relies. </para> <sect2 id="SingleStateTesting"> <title>Single state testing</title> <para> Torbutton is a complicated piece of software. During development, changes to one component can affect a whole slough of unrelated features. A number of aggregated test suites exist that can be used to test for regressions in Torbutton and to help aid in the development of Torbutton-like addons and other privacy modifications of other browsers. Some of these test suites exist as a single automated page, while others are a series of pages you must visit individually. They are provided here for reference and future regression testing, and also in the hope that some brave soul will one day decide to combine them into a comprehensive automated test suite. <orderedlist> <listitem><ulink url="http://decloak.net/">Decloak.net</ulink> <para> Decloak.net is the canonical source of plugin and external-application based proxy-bypass exploits. It is a fully automated test suite maintained by <ulink url="http://digitaloffense.net/">HD Moore</ulink> as a service for people to use to test their anonymity systems. </para> </listitem> <listitem><ulink url="http://deanonymizer.com/">Deanonymizer.com</ulink> <para> Deanonymizer.com is another automated test suite that tests for proxy bypass and other information disclosure vulnerabilities. It is maintained by Kyle Williams, the author of <ulink url="http://www.janusvm.com/">JanusVM</ulink> and <ulink url="http://www.januspa.com/">JanusPA</ulink>. </para> </listitem> <listitem><ulink url="https://www.jondos.de/en/anontest">JonDos AnonTest</ulink> <para> The <ulink url="https://www.jondos.de">JonDos people</ulink> also provide an anonymity tester. It is more focused on HTTP headers than plugin bypass, and points out a couple of headers Torbutton could do a better job with obfuscating. </para> </listitem> <listitem><ulink url="http://browserspy.dk">Browserspy.dk</ulink> <para> Browserspy.dk provides a tremendous collection of browser fingerprinting and general privacy tests. Unfortunately they are only available one page at a time, and there is not really solid feedback on good vs bad behavior in the test results. </para> </listitem> <listitem><ulink url="http://analyze.privacy.net/">Privacy Analyzer</ulink> <para> The Privacy Analyzer provides a dump of all sorts of browser attributes and settings that it detects, including some information on your origin IP address. Its page layout and lack of good vs bad test result feedback makes it not as useful as a user-facing testing tool, but it does provide some interesting checks in a single page. </para> </listitem> <listitem><ulink url="http://ha.ckers.org/mr-t/">Mr. T</ulink> <para> Mr. T is a collection of browser fingerprinting and deanonymization exploits discovered by the <ulink url="http://ha.ckers.org">ha.ckers.org</ulink> crew and others. It is also not as user friendly as some of the above tests, but it is a useful collection. </para> </listitem> <listitem>Gregory Fleischer's <ulink url="http://pseudo-flaw.net/content/tor/torbutton/">Torbutton</ulink> and <ulink url="http://pseudo-flaw.net/content/defcon/dc-17-demos/d.html">Defcon 17</ulink> Test Cases <para> Gregory Fleischer has been hacking and testing Firefox and Torbutton privacy issues for the past 2 years. He has an excellent collection of all his test cases that can be used for regression testing. In his Defcon work, he demonstrates ways to infer Firefox version based on arcane browser properties. We are still trying to determine the best way to address some of those test cases. </para> </listitem> <listitem><ulink url="https://torcheck.xenobite.eu/index.php">Xenobite's TorCheck Page</ulink> <para> This page checks to ensure you are using a valid Tor exit node and checks for some basic browser properties related to privacy. It is not very fine-grained or complete, but it is automated and could be turned into something useful with a bit of work. </para> </listitem> </orderedlist> </para> </sect2> <sect2> <title>Multi-state testing</title> <para> The tests in this section are geared towards a page that would instruct the user to toggle their Tor state after the fetch and perform some operations: mouseovers, stray clicks, and potentially reloads. </para> <sect3> <title>Cookies and Cache Correlation</title> <para> The most obvious test is to set a cookie, ask the user to toggle tor, and then have them reload the page. The cookie should no longer be set if they are using the default Torbutton settings. In addition, it is possible to leverage the cache to <ulink url="http://crypto.stanford.edu/sameorigin/safecachetest.html">store unique identifiers</ulink>. The default settings of Torbutton should also protect against these from persisting across Tor Toggle. </para> </sect3> <sect3> <title>Javascript timers and event handlers</title> <para> Javascript can set timers and register event handlers in the hopes of fetching URLs after the user has toggled Torbutton. </para> </sect3> <sect3> <title>CSS Popups and non-script Dynamic Content</title> <para> Even if Javascript is disabled, CSS is still able to <ulink url="http://www.tjkdesign.com/articles/css%20pop%20ups/">create popup-like windows</ulink> via the 'onmouseover' CSS attribute, which can cause arbitrary browser activity as soon as the mouse enters into the content window. It is also possible for meta-refresh tags to set timers long enough to make it likely that the user has toggled Tor before fetching content. </para> </sect3> </sect2> <sect2 id="HackTorbutton"> <title>Active testing (aka How to Hack Torbutton)</title> <para> The idea behind active testing is to discover vulnerabilities in Torbutton to bypass proxy settings, run script in an opposite Tor state, store unique identifiers, leak location information, or otherwise violate <link linkend="requirements">its requirements</link>. Torbutton has ventured out into a strange and new security landscape. It depends on Firefox mechanisms that haven't necessarily been audited for security, certainly not for the threat model that Torbutton seeks to address. As such, it and the interfaces it depends upon still need a 'trial by fire' typical of new technologies. This section of the document was written with the intention of making that period as fast as possible. Please help us get through this period by considering these attacks, playing with them, and reporting what you find (and potentially submitting the test cases back to be run in the standard batch of Torbutton tests. </para> <sect3> <title>Some suggested vectors to investigate</title> <para> <itemizedlist> <listitem>Strange ways to register Javascript <ulink url="http://en.wikipedia.org/wiki/DOM_Events">events</ulink> and <ulink url="http://www.devshed.com/c/a/JavaScript/Using-Timers-in-JavaScript/">timeouts</ulink> should be verified to actually be ineffective after Tor has been toggled.</listitem> <listitem>Other ways to cause Javascript to be executed after <command>javascript.enabled</command> has been toggled off.</listitem> <listitem>Odd ways to attempt to load plugins. Kyle Williams has had some success with direct loads/meta-refreshes of plugin-handled URLs.</listitem> <listitem>The Date and Timezone hooks should be verified to work with crazy combinations of iframes, nested iframes, iframes in frames, frames in iframes, and popups being loaded and reloaded in rapid succession, and/or from one another. Think race conditions and deep, parallel nesting, involving iframes from both <ulink url="http://en.wikipedia.org/wiki/Same_origin_policy">same-origin and non-same-origin</ulink> domains.</listitem> <listitem>In addition, there may be alternate ways and other methods to query the timezone, or otherwise use some of the Date object's methods in combination to deduce the timezone offset. Of course, the author tried his best to cover all the methods he could foresee, but it's always good to have another set of eyes try it out.</listitem> <listitem>Similarly, is there any way to confuse the <link linkend="contentpolicy">content policy</link> mentioned above to cause it to allow certain types of page fetches? For example, it was recently discovered that favicons are not fetched by the content, but the chrome itself, hence the content policy did not look up the correct window to determine the current Tor tag for the favicon fetch. Are there other things that can do this? Popups? Bookmarklets? Active bookmarks? </listitem> <listitem>Alternate ways to store and fetch unique identifiers. For example, <ulink url="http://developer.mozilla.org/en/docs/DOM:Storage">DOM Storage</ulink> caught us off guard. It was also discovered by <ulink url="http://pseudo-flaw.net">Gregory Fleischer</ulink> that <ulink url="http://pseudo-flaw.net/content/tor/torbutton/">content window access to chrome</ulink> can be used to build <link linkend="fingerprinting">unique identifiers</link>. Are there any other arcane or experimental ways that Firefox provides to create and store unique identifiers? Or perhaps unique identifiers can be queried or derived from properties of the machine/browser that Javascript has access to? How unique can these identifiers be? </listitem> <listitem>Is it possible to get the browser to write some history to disk (aside from swap) that can be retrieved later? By default, Torbutton should write no history, cookie, or other browsing activity information to the harddisk.</listitem> <listitem>Do popup windows make it easier to break any of the above behavior? Are javascript events still canceled in popups? What about recursive popups from Javascript, data, and other funky URL types? What about CSS popups? Are they still blocked after Tor is toggled?</listitem> <listitem>Chrome-escalation attacks. The interaction between the Torbutton chrome Javascript and the client content window javascript is pretty well-defined and carefully constructed, but perhaps there is a way to smuggle javascript back in a return value, or otherwise inject network-loaded javascript into the chrome (and thus gain complete control of the browser). </listitem> </itemizedlist> </para> </sect3> </sect2> </sect1> </article>