Facebook Countermeasures

The recent spate of revelations surrounding data breaches, subversion of the democratic process, and general disregard for user privacy were the last straw. It’s time to say goodbye to Facebook. However, not everyone feels so strongly and cutting off a channel of communication as ubiquitous as Facebook can be challenging. So what can you do to protect yourself?

Note: The web browser sections below are Firefox-specific.

Behavioural Changes

Don’t use Facebook Mobile appLications

Installing Facebook or any Facebook afiliated app on your phone is probably the worst thing you can do. For example, it was recently revealed that Messenger was sending all kinds of data back to the mothership. Specifically, contact lists and phone call / SMS metadata. It’s very hard to know exactly what closed-source apps are doing behind the scenes so as a general rule don’t install them.

Disable FACEBOOK PLATFORM

Facebook Platform provides a set of application programming interfaces (APIs) that give third-party developers access to your data. This is exactly how Cambridge Analytica got access to the user data of over 50 million people. If you have “Apps, websites and games” turned on, you’re putting yourself at serious risk.

The Electronic Frontier Foundation have provided a straightforward overview of how to opt out of Platform API sharing.

Don’t ‘like’ stuff

Your personal information is valuable – don’t give it away for free! If someone offered you a service but in exchange you had to tell them your sexual orientation, ethnicity, religious and political views, personality traits, intelligence, happiness, use of addictive substances, parental separation, age, and gender would you accept? Chances are you wouldn’t. A 2013 study of 58,000 volunteers showed how your Likes reveal all of the above with frightening accuracy.

Don’t upload media with embedded EXIF metadata

Exif (Exchangeable image file format) defines a standard for embedding metadata in image and sound files. This metadata can include your device’s serial number and GPS coordinates. The serial number can be used to identify every other photo taken by that device. I’m sure you can imagine scenarios in which that might not be ideal. The power of metadata is best exemplified by the story of Higinio O. Ochoa III, an alleged Anonymous hacker from Texas (see also A Picture is Worth a Thousand Words, Including Your Location, by the Electronic Frontier Foundation).

If you have an Android phone OscuraCam is a good option for stripping Exif metadata before uploading to Facebook.

Isolate your usage of Facebook.com

Facebook recently confirmed what most people already knew; namely that it tracks and profiles users and non-users alike. You can minimise your exposure to tracking in one of two ways.

Option 1: Install the ‘Facebook Container’ add-on

Firefox Containers facilitate the segregation of site data by giving each container its own cache, cookie storage, indexeddb, and localStorage. Containers were initially only available in Firefox Nightly. In September 2017 they became widely available via the Firefox Multi-Account Containers add-on. In March 2018 Mozilla released Facebook Container – a container-based add-on designed to isolate your web activity from Facebook.

See this Mozilla blog post for more information.

Option 2: Use a dedicated browser profile

If you use Firefox, you already have a default profile. It’s where Firefox stores your history, bookmarks, installed add-ons, saved passwords, etc. Profiles also have their own cache, cookie storage, indexeddb, and localStorage. For all intents and purposes, a profile is a completely separate browser. You can see information about your current profile(s) by type ‘about:profiles‘ in the Firefox address bar.

The best way to fully isolate Facebook from your general day-to-day browsing is to create a new profile whose sole purpose is accessing Facebook. Information on adding and removing profiles can be found here.

From here on in I’ll assume you have two profiles; “default” (for all your day-to-day, non-Facebook, browsing) and “facebook” (used purely for accessing Facebook). Now that you’re no longer using your default profile for accessing Facebook, you should block all Facebook domains and cookies in that profile.

When it comes to domain blocking in the browser my go-to tool is uMatrix. From a privacy perspective uMatrix is ideal because it actually blocks requests to blacklisted domains. On the flip side it’s not the most user-friendly for non-technical users. At the time of writing, the following rules should suffice:

* facebook.com * block
* facebook.com.edgekey.net * block
* facebook.com.edgesuite.net * block
* facebook.net * block
* facebook.net.edgekey.net * block
* facebook-web-clients.appspot.com * block
* fb.com * block
* fb.me * block
* fbcdn.com * block
* fbcdn.net * block
* fbsbx.com * block
* fbsbx.com.online-metrix.net * block
* m.me * block
* messenger.com * block
* tfbnw.net * block

Information on adding uMatrix rules can be found on the uMatrix Wiki.

Non-Facebook users

If you don’t have a Facebook account, or you’ve deleted it, and are technically inclined, you can attempt to block Facebook at the network level:

  • Block all known Facebook domains at the router or in your computer’s host file.
  • Get hold of a Raspberry Pi and install Pi-hole, preferably in conjunction with DNSCrypt.
  • Use a filtering proxy such as Privoxy (P.S. never download anything from SourceForge as there have been numerous instances of malware being bundled with SourceForge downloads).

It should be noted that blocking Facebook at the network level isn’t foolproof. New domains create a constantly moving target and applications can always bypass DNS based blockers by using IP addresses.

Advertisements

Setting up a Local p2 Repository

I’m currently working on an Eclipse RCP application that uses PAX Logging. The easiest way to use the required bundles is to put them in a folder referenced by your Target Platform Definition. However, there are a couple of major drawbacks to this approach:

  1. Tycho requires p2 metadata in order to resolve dependencies, so the local folder approach won’t work if you’re using Tycho for a headless build
  2. Log4j Import-Package failures. Every time I started Eclipse I had to reset my target platform because Import-Package: org.apache.log4j;version="1.2.15";provider=paxlogging was failing

Based on the Equinox documentation I created the following ant build file to publish a local p2 repository. The only prerequisite is that all the required PAX Logging bundles are placed in a folder, relative to the build file, called lib/plugins (see p2-build.xml in-line comments). Once you’ve created your repository you can use your favourite web server to make it available to Tycho.

p2-build.xml

<?xml version="1.0" encoding="UTF-8"?>
<project name="local-p2" default="create-p2" basedir=".">

    <!-- 3rd party bundles should be placed in
         a subdirectory called 'plugins' -->
    <property name="source.dir" location="${basedir}/lib" />
    <!-- the directory the repository will be
         created in -->
    <property name="repo.dir" value="${basedir}/repository" />

    <target name="clean">
        <delete dir="${repo.dir}" />
        <mkdir dir="${repo.dir}" />
    </target>

    <target name="create-p2" depends="clean">
        
        <makeurl file="${repo.dir}" property="repo.url" />
        <echo message="Repository URL: ${repo.url}"/>
        <makeurl file="${basedir}/category.xml" property="category.file.url" />

        <!-- Use a fileset include to avoid hard-coding
             the equinox launcher jar filename -->
        <pathconvert property="launcher.jar">
            <fileset dir="${eclipse.home}/plugins/">
                <include name="org.eclipse.equinox.launcher_*.jar" />
            </fileset>
        </pathconvert>
        <echo message="Using Equinox launcher: ${launcher.jar}"/>

        <!-- Assumes 3rd party bundles are located in
             ${source.dir}/plugins -->
        <p2.publish.featuresAndBundles
            repository="${repo.url}"
            publishArtifacts="true"
            compress="false"
            source="${source.dir}" />

        <!-- See category.xml -->
        <exec executable="java">
            <arg value="-jar" />
            <arg value="${launcher.jar}" />
            <arg value="-console" />
            <arg value="-consolelog" />
            <arg value="-application" />
            <arg value="org.eclipse.equinox.p2.publisher.CategoryPublisher" />
            <arg value="-metadataRepository" />
            <arg value="${repo.url}" />
            <arg value="-categoryDefinition" />
            <arg value="${category.file.url}" />
            <arg value="-categoryQualifier" />
        </exec>
    </target>

</project>

category.xml

<?xml version="1.0" encoding="UTF-8"?>
<site>
    <bundle id="org.ops4j.pax.configmanager" version="0.2.2">
        <category name="ops4j" />
    </bundle>
   <bundle id="org.ops4j.pax.logging.pax-logging-api" version="1.7.3">
      <category name="ops4j"/>
   </bundle>
   <bundle id="org.ops4j.pax.logging.pax-logging-service" version="1.7.3">
      <category name="ops4j"/>
   </bundle>
   <category-def name="ops4j" label="ops4j"/>
</site>

Ubuntu Virtual Machine Setup

To successfully build an e4 RCP application for Mac OX S you need a Linux environment. The following instructions are a record of how I set up Ubuntu 14.04 on VirtualBox 4.3.12

Prerequisites

  • Windows 7 Professional 64-bit
  • VirtualBox 4.3.12
  • ubuntu-14.04.1-desktop-amd64.iso

Creating an Ubuntu VM on VirtualBox

  1. Open ‘Oracle VM VirtualBox Manager’ and create a new virtual machine with the following attributes:
    • Type: Linux
    • Version: Ubuntu (64bit)
    • RAM: 2048 MB
    • Hard drive: VDI, Dynamically Allocated, 10 GB
  2. Start the new VM and select ubuntu-14.04.1-desktop-amd64.iso as the installation image
  3. Follow the onscreen instructions to install Ubuntu
  4. Shutdown the VM and set the following display properties in the video tab:
    • Video Memory: 128 MB
    • Enable 3D Acceleration: selected
  5. Start Ubuntu and run the following command:
    sudo apt-get install virtualbox-guest-dkms virtualbox-guest-utils virtualbox-guest-x11

    (see Screen Resolution Problem with Ubuntu 14.04 and VirtualBox for more information on why this is required)

  6. Restart the VM

Dev Environment Setup

JDK 1.8

  1. To install JDK 1.8 run the following commands:
    sudo add-apt-repository ppa:webupd8team/java
    sudo apt-get update
    sudo apt-get install oracle-java8-installer

Eclipse for RCP and RAP Developers

  1. Download the latest Linux 64-bit version of ‘Eclipse for RCP and RAP Developers’ (currently Luna RC3) and extract it to a suitable location
  2. Create an eclipse.desktop file by running the following command:
    sudo -H gedit /usr/share/applications/eclipse.desktop

    Add the following content, replacing ‘path-to-eclipse-executable’ with the appropriate value:

    [Desktop Entry] 
    Type=Application 
    Name=Eclipse 
    Icon=eclipse 
    Exec=env UBUNTU_MENUPROXY= path-to-eclipse-executable 
    Terminal=false 
    Categories=Development;IDE;Java;
  3. Install e4 Tools
    1. Go to the eclipse e4 project downloads page
    2. Select the latest release (currently 1.6)
    3. Copy the ‘online p2 repo link’ URL
    4. Start eclipse and create a new ‘software update site’ using the URL from the previous step
    5. Install the ‘Eclipse 4 – Core Tools’ feature
  4. Install EGit via the ‘Help – Eclipse Marketplace’ menu item

Git

  1. Run the following command to install Git:
    sudo apt-get install git

    (see Getting Started – Installing Git for more information)

  2. For a graphical front end, download and install SmartGit

Additional Ubuntu Configuration

Shared Folder(s)

  1. Create a new folder on the Windows host
  2. Open ‘Oracle VM VirtualBox Manager’, select ‘Settings – Shared Folders’ and click the ‘Add’ button
  3. Select the newly created folder by selecting ‘Other’ from the ‘Folder Path’ dropdown list
  4. Check the ‘Auto-mount’ and ‘Make Permanent’ options and click ‘OK’
  5. Run the following command in Ubuntu, replacing ‘your-user-name’ with the appropriate value:
    sudo adduser your-user-name vboxsf
  6. Restart Ubuntu and confirm the folder is accessible by running:
    ls /media/

Auto-hide the Launcher

  1. Select ‘System Settings – Appearance – Behaviour’ to auto-hide the launcher
  2. If the launcher doesn’t reappear when you move the mouse to the designated area simply press ALT+F1 or the Windows key to toggle launcher visibility

Changing the Default Search Categories and Sources

  1. Select ‘System Settings – Security & Privacy – Search’ to exclude online search results
  2. Install dconf Editor by running the following command:
    sudo apt-get install dconf-tool
  3. Open dconf Editor and select ‘com – canonical – unity – lenses’
  4. Add/remove any required/unwanted scopes (see How to get the list of Dash search plugins (scopes) in command line? for more information).

Generating HTML tables with XSLT

The following code snippet is a relatively simple and reusable implementation for generating HTML table content.

    <!-- The number of columns in the generated table -->
    <xsl:variable name="nColumns" select="3" />

    <!--
        XPath indexes start at 1, not 0. 'row' and 'column' template
        parameters therefore default to 1
    -->
    
    <xsl:template name="tableRows">
        <!-- The table content node list -->
        <xsl:param name="items" />
        <!-- The current row index -->
        <xsl:param name="row" select="1" />
        <!--
            Calculate the total number of rows based on the number of
            items and the number of columns
        -->
        <xsl:variable name="nRows" select="ceiling(count($items) div $nColumns)"></xsl:variable>
        <xsl:element name="tr">
            <xsl:call-template name="tableColumns">
                <xsl:with-param name="items" select="$items" />
                <xsl:with-param name="row" select="$row" />
            </xsl:call-template>
        </xsl:element>
         <!--
              There's no loop construct in XSLT so we simply increment
              the row index and call the template again if the current
              row index is less than the total number of rows
         -->
        <xsl:if test="$nRows > $row">
            <xsl:call-template name="tableRows">
                <xsl:with-param name="items" select="$items" />
                <xsl:with-param name="row" select="$row + 1" />
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

    <xsl:template name="tableColumns">
        <!-- The table content node list -->
        <xsl:param name="items" />
        <!-- The current row index -->
        <xsl:param name="row" />
        <!-- The current column index -->
        <xsl:param name="column" select="1" />
        <!--
            Calculate the item index based on the current row and
            column index
        -->
        <xsl:variable name="itemIndex" select="(($row - 1) * $nColumns) + $column" />
        <xsl:element name="td">
            <!-- Check the item index is 'in bounds' -->
            <xsl:if test="count($items) >= $itemIndex">
                <xsl:call-template name="tableCellContent">
                    <xsl:with-param name="item" select="$items[$itemIndex]" />
                </xsl:call-template>
            </xsl:if>
        </xsl:element>
         <!--
              There's no loop construct in XSLT so we simply increment
              the column index and call the template again if the current
              column index is less than the specified number of columns
         -->
        <xsl:if test="$nColumns > $column">
            <xsl:call-template name="tableColumns">
                <xsl:with-param name="items" select="$items" />
                <xsl:with-param name="row" select="$row" />
                <xsl:with-param name="column" select="$column + 1" />
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

    <xsl:template name="tableCellContent">
        <xsl:param name="item" />
        <!-- Generate content for the current item -->
        ...
    </xsl:template>

Eclipse 4.4.0 – Tool bar item visibility based on the currently active perspective

Displaying trimmed window tool bar items based on the currently active perspective in an Eclipse 4.4.0 RCP application would seem like a straightforward task but it actually involves a fair bit of tinkering and there are a few not so obvious pitfalls along the way.

After reading section 31.2 of Lars Vogel’s Eclipse 4 RCP tutorial the obvious approach was to associate a ‘visible-when’ expression with each of my perspective-specific tool bar items. The first problem I encountered was the fact that expressions are not evaluated for items added directly to the main tool bar (see Bug 400217). By ‘added directly’ I mean added as children of the tool bar element in the e4xmi application model. Luckily, when added as ToolBar Contributions visible-when expressions are evaluated as expected.

The next problem I encountered was how to determine the currently active perspective from within a visible-when expression. I couldn’t find any up to date documentation regarding the names of predefined context variables and none of the variables listed in Command Core Expressions were available in my Eclipse Luna 4.4.0 RCP application. To determine which context variables were available I added the following @CanExecute method to one of my tool bar item command handlers:

@CanExecute
public boolean canExecute(final IEclipseContext ictx) {
    final EclipseContext ctx = (EclipseContext) ictx.getParent();
    System.out.println("### START ###");
    for (final Entry<String, Object> entry : ctx.localData().entrySet()) {
        System.out.println(String.format("Key: '%s', value: '%s'", entry.getKey(), entry.getValue()));
    }
    System.out.println("### END ###");
    return true;
}

The following entry was included in the output from this method:

 Key: 'org.eclipse.e4.ui.model.application.ui.advanced.MPerspective', value: 'org.eclipse.e4.ui.model.application.ui.advanced.impl.PerspectiveImpl@2d778add (elementId: my.example.perspective.Edit, tags: [], contributorURI: platform:/plugin/my.example.application) (widget: Composite {}, renderer: org.eclipse.e4.ui.workbench.renderers.swt.PerspectiveRenderer@7fc44dec, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: Edit, iconURI: null, tooltip: , context: PerspectiveImpl (my.example.perspective.Edit) Context, variables: [])'

Based on this output I wrote the following following Property Tester to query the elementId of the active perspective:

/**
 * Property tester that checks the <code>elementId</code> of the currently active perspective
 */
public class PerspectivePropertyTester extends PropertyTester {

    /**
     * @param receiver the currently active {@link MPerspective}
     * @param property the property to test, in this case 'elementId'
     * @param args additional arguments, in this case an empty array
     * @param expectedValue the expected value of {@link MPerspective#getElementId()}
     */
    @Override
    public boolean test(final Object receiver, final String property, final Object[] args, final Object expectedValue) {
        final MPerspective perspective = (MPerspective) receiver;
        return perspective.getElementId().equals(expectedValue);
    }
}

This was then configured in plugin.xml as follows:

<?xml version="1.0" encoding="UTF-8"?>
<plugin>
   ...
   <extension point="org.eclipse.core.expressions.propertyTesters">
      <propertyTester class="my.example.application.propertytester.PerspectivePropertyTester"
            id="my.example.application.propertytester.PerspectivePropertyTester"
            namespace="my.example.property"
            properties="perspectiveId"
            type="org.eclipse.e4.ui.model.application.ui.advanced.MPerspective">
      </propertyTester>
   </extension>
   <extension point="org.eclipse.core.expressions.definitions">
      <definition id="my.example.expression.isEditPerspective">
         <with variable="org.eclipse.e4.ui.model.application.ui.advanced.MPerspective">
            <test forcePluginActivation="true"
                  property="my.example.property.perspectiveId"
                  value="my.example.perspective.Edit">
            </test>
         </with>
      </definition>
      <definition id="my.example.expression.isPreviewPerspective">
         <with variable="org.eclipse.e4.ui.model.application.ui.advanced.MPerspective">
            <test forcePluginActivation="true"
                  property="my.example.property.perspectiveId"
                  value="my.example.perspective.Preview">
            </test>
         </with>
      </definition>
   </extension>
   ...
</plugin>

As a footnote I should also note that subscribing to UIEvents.UILifeCycle.PERSPECTIVE_OPENED events does not work as expected (see Bug 408681) so the above approach is probably the best option. You could, of course, set the visibility of tool bar items programmatically when switching perspective but this is far from ideal.

Installing Squid 3.0 on Fredora 11

  1. Install Squid in the normal fashion using yum or System -> Administration -> Add/Remove Software.
  2. Open the Squid configuration file by executing the following command:
    sudo gedit /etc/squid/squid.conf
  3. Change the value of the error_directory property so that it points to an actual directory. For example:
    error_directory /usr/share/squid/errors/English

    As opposed to

    error_directory /usr/share/squid/errors/en

    which didn’t exist on my system after the install had completed.

  4. If your current SELinux enforcing mode is set to "Enforcing" you’ll also need to perform the following steps.
  5. Create the following Type Enforcement file (the remaining steps assume the file name local.te):
    module local 1.0;
    
    require {
    	type var_run_t;
    	type unconfined_t;
    	type squid_t;
    	class file {open read getattr};
    	class process signal;
    }
    
    #============= squid_t ==============
    allow squid_t var_run_t:file {open read getattr};
    allow squid_t unconfined_t:process signal;

    N.B. The following steps will overwrite any existing module with the same name. To check if you already have a policy module called local go to System -> Administration -> SELinux Management, select "Policy Module" from the left-hand menu and enter "local" into the filter field. If you’ve already got a module called local simply edit the Type Enforcement file accordingly. For example:

    module mysquid 1.0;
  6. Edit accordingly, then execute the following script:
    dir=<your-dir-path>;
    sudo checkmodule -M -m -o $dir/local.mod $dir/local.te;
    sudo semodule_package -o $dir/local.pp -m $dir/local.mod;
    sudo semodule -i $dir/local.pp;

    N.B. The checkmodule command takes the Type Enforcement file, local.te, created in step 5 as its input.

  7. Got to System -> Administration -> Services. Start Squid.
  8. Cleanup any unwanted files created in steps 5 and 6.

Unit Testing HTTPS Clients with a Self-signed Certificate

Overview

A quick and easy way to eliminate javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target without making dangerous changes to your default trust store.

Steps

  1. Create a new keystore and associated key entry by executing the following command (N.B. The password values for the -keypass and -storepass options must be identical for Tomcat to work):
    keytool -genkey -alias tomcat -keyalg RSA -keypass <password> -keystore <user-home>/tomcat.jks -storepass <password>
    
  2. Enter and confirm your details.
  3. Uncomment the “SSL HTTP/1.1 Connector” entry in $CATALINA_BASE/conf/server.xml.
  4. Add keystoreFile and keystorePass attributes with the appropriate values. The result should now resemble the following:
    <!-- Define a SSL HTTP/1.1 Connector on port 8443
    	This connector uses the JSSE configuration, when using APR, the
    	connector should be using the OpenSSL style configuration
    	described in the APR documentation -->
    
    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
    	maxThreads="150" scheme="https" secure="true"
    	keystoreFile="${user.home}/tomcat.jks" keystorePass="<password>"
    	clientAuth="false" sslProtocol="TLS" />
    
  5. Restart Tomcat and deploy your HTTPS constrained resources.
  6. Add a @BeforeClass method to any tests generating HTTPS requests. Use this method to set the javax.net.ssl.trustStore and javax.net.ssl.trustStorePassword system properties. For example:
    @BeforeClass
    public static void setUp() {
    	System.setProperty("javax.net.ssl.trustStore", "<user-home>/tomcat.jks");
    	System.setProperty("javax.net.ssl.trustStorePassword", "<password>");
    }
    
  7. JSSE now uses the new keystore created in steps 1 and 2 as opposed to the default, <java-home>/jre/lib/security/cacerts, trust store.