A web privacy measurement framework
Перейти к файлу
vringar 0cfc12f609 Merge branch 'master' into stealth_extension 2024-02-07 11:21:12 +01:00
.github/workflows Release (#1078) 2023-12-24 16:15:08 +01:00
Extension fix(Extension): fix eslint issues 2024-02-06 23:17:14 +01:00
docs Add stealth extension 2024-01-25 19:56:10 +01:00
hide_commands fix(pre-commit): address pre-commit issues 2024-01-25 19:58:39 +01:00
openwpm Merge branch 'master' into stealth_extension 2024-02-07 11:21:12 +01:00
schemas fix(schema): allow unexpanded form in schema 2024-02-06 21:17:02 +01:00
scripts Release (#1078) 2023-12-24 16:15:08 +01:00
test Release (#1078) 2023-12-24 16:15:08 +01:00
.codecov.yml v0.11.0 / Firefox 78.0.1 release (#706) 2020-07-08 18:33:27 -05:00
.dockerignore Add stealth extension 2024-01-25 19:56:10 +01:00
.gitignore Add optional tranco list to demo script (#1016) 2022-12-07 17:55:43 +01:00
.pre-commit-config.yaml Release (#1078) 2023-12-24 16:15:08 +01:00
.readthedocs.yaml Update Read the Docs configuration (automatic) (#969) 2022-01-21 21:29:29 +01:00
CHANGELOG.md Release (#1078) 2023-12-24 16:15:08 +01:00
CODE_OF_CONDUCT.md Add Mozilla Code of Conduct file 2019-03-28 21:58:46 -07:00
CONTRIBUTING.md Refactor/single extension (#1008) 2022-09-23 22:08:18 +02:00
Dockerfile fix(Dockerfile): add required dependencies 2023-10-04 18:31:10 +02:00
LICENSE Add stealth extension 2024-01-25 19:56:10 +01:00
README.md Add screen size and window position 2024-01-25 19:58:39 +01:00
VERSION Release (#1078) 2023-12-24 16:15:08 +01:00
commitlint.config.js feat: update Firefox version and all OpenWPM dependencies 2021-12-07 15:35:20 +01:00
crawler.py Add stealth extension 2024-01-25 19:56:10 +01:00
custom_command.py Command refactoring (#750) 2021-01-09 11:15:01 +01:00
demo.py Storage watchdog (#1056) 2023-10-12 19:44:01 +00:00
environment.yaml update env yaml to comply with 0.20.0 2024-01-25 19:58:34 +01:00
install.sh Mamba switch (#1026) 2023-01-19 07:23:11 +01:00
package-lock.json Release (#1078) 2023-12-24 16:15:08 +01:00
package.json Release (#1057) 2023-10-21 17:59:01 +00:00
pyproject.toml Update deps (#1038) 2023-06-25 23:52:31 +02:00

README.md

OpenWPMhide

Full details are described in our paper, which can be found on our website.

Deployment

  1. Follow the instructions from the original description to install OpenWPM (see below).
  2. Adjuste the settings.js to determine which properties shall be instrumented.
  3. Recompile the extension if you do any changes to make them effective
  4. Add the new features to your OpenWPM clients, as described in the next section
  5. Run your OpenWPM client as

To recompile the extension run the following commands:

cd Extension/firefox && npm install && run build && cp dist/*.zip ./openwpm.xpi && cd ../..

Main features

  1. Adjusting the window position
  2. Adjusting screen resolution
  3. Hardened JavaScript instrument
  4. Overwriting the webdriver attribute

Window position & screen resolution

OpenWPMhide introduces two new parameters to the BrowserParams object. Using both parameters works as follows:

from hide_commands import (SetResolution, SetPosition)
...
command_sequence = CommandSequence(...)

command_sequence.append_command(SetResolution(width=1600, height=800), timeout=10)
command_sequence.append_command(SetPosition(x=50, y=200), timeout=10)

Hardened JavaScript instrument

Set stealth_js_instrument to True to activate the hardened version (similar as above):

NUM_BROWSERS = 2
browser_params = [BrowserParams(display_mode="native") for _ in range(NUM_BROWSERS)]
for browser_param in browser_params:
  browser_param.stealth_js_instrument = True

Use the settings.js file to define which properties will be recorded. While there is a number of properties already listed in the sample settings.js, you may want to add others. Adding new properties requires to determine a property's position in the property chain. The position can be retrieved in a Firefox browser via JavaScript reflect.

In your browser, add this function via the console:

Object.getPropertyNamesPerDepth = function (subject, maxDepth=10) {
  if (subject === undefined) {
    throw new Error("Can't get property names for undefined");
  }
  let res = [];
  let depth = 0;
  let properties = Object.getOwnPropertyNames(subject);
  res.push({"depth": depth, "propertyNames":properties, "object":subject});
  let proto = Object.getPrototypeOf(subject);

  while (proto !== null, depth < maxDepth) {
    depth++;
    properties = Object.getOwnPropertyNames(proto);
    res.push({"depth": depth, "propertyNames":properties, "object":proto});
    proto = Object.getPrototypeOf(proto);
    if (proto==null){
      return res;
    }
  }
  return res;
}

Then check for property levels (this example checks the navigator object):

Object.getPropertyNamesPerDepth(Object.getPrototypeOf(navigator))

Overwriting webdriver attribute

Overwriting is done by default when activating stealth_js_instrument. However, you may not want to use the JS recording, but overwrite the property anyway. In this case, remove all entries settings.js, except the default entry for the Navigator object.

Cite

You can refer to our work as follows:

How gullible are web measurement tools? A case study analysing and strengthening OpenWPMs reliability. Benjamin Krumnow, Hugo Jonker, and Stefan Karsch. In Proc. 18th International Conference on emerging Networking EXperiments and Technologies (CoNEXT22). ACM, 16 pages, doi: 10.1145/3555050.3569131, 2022.

or

@inproceedings{KJK22,
  author      = {Krumnow, Benjamin and Jonker, Hugo and
  Karsch, Stefan},
  title       = {How gullible are web measurement tools? {A} case study
  analysing and strengthening {OpenWPM}s reliability},
  booktitle   = {Proc.\ 18th International Conference on emerging Networking
  EXperiments and Technologies {(CoNEXT 22)}},
  publisher   = { {ACM} },
  year        = {2022},
  address     = {New York, NY, USA},
  pages       = {16},
  doi         = {10.1145/3555050.3569131}
}

OpenWPM Documentation Status Build Status OpenWPM Matrix Channel

OpenWPM is a web privacy measurement framework which makes it easy to collect data for privacy studies on a scale of thousands to millions of websites. OpenWPM is built on top of Firefox, with automation provided by Selenium. It includes several hooks for data collection. Check out the instrumentation section below for more details.

Table of Contents

Installation

OpenWPM is tested on Ubuntu 18.04 via GitHub actions and is commonly used via the docker container that this repo builds, which is also based on Ubuntu. Although we don't officially support other platforms, mamba is a cross platform utility and the install script can be expected to work on OSX and other linux distributions.

OpenWPM does not support windows: https://github.com/openwpm/OpenWPM/issues/503

Pre-requisites

The main pre-requisite for OpenWPM is mamba, a fast cross-platform package management tool.

Mamba is open-source, and can be installed from https://mamba.readthedocs.io/en/latest/installation.html.

Mamba is a reimplmentation of conda and so sometimes a conda command has to be invoked instead of the mamba one.

Install

An installation script, install.sh is included to: install the conda environment, install unbranded firefox, and build the instrumentation extension.

All installation is confined to your conda environment and should not affect your machine. The installation script will, however, override any existing conda environment named openwpm.

To run the install script, run

./install.sh

After running the install script, activate your conda environment by running:

conda activate openwpm

Mac OSX

You may need to install make / gcc in order to build the extension. The necessary packages are part of xcode: xcode-select --install

We do not run CI tests for Mac, so new issues may arise. We welcome PRs to fix these issues and add full CI testing for Mac.

Running Firefox with xvfb on OSX is untested and will require the user to install an X11 server. We suggest XQuartz. This setup has not been tested, we welcome feedback as to whether this is working.

Quick Start

Once installed, it is very easy to run a quick test of OpenWPM. Check out demo.py for an example. This will use the default setting specified in openwpm/config.py::ManagerParams and openwpm/config.py::BrowserParams, with the exception of the changes specified in demo.py.

The demo script also includes a sample of how to use the Tranco top sites list via the optional command line flag demo.py --tranco. Note that since this is a real top sites list it will include NSFW websites, some of which will be highly ranked.

More information on the instrumentation and configuration parameters is given below.

The docs provide a more in-depth tutorial, and a description of the methods of data collection available.

Troubleshooting

  1. WebDriverException: Message: The browser appears to have exited before we could connect...

    This error indicates that Firefox exited during startup (or was prevented from starting). There are many possible causes of this error:

    • If you are seeing this error for all browser spawn attempts check that:

      • Both selenium and Firefox are the appropriate versions. Run the following commands and check that the versions output match the required versions in install.sh and environment.yaml. If not, re-run the install script.
      cd firefox-bin/
      firefox --version
      

      and

        conda list selenium
      
      • If you are running in a headless environment (e.g. a remote server), ensure that all browsers have the headless browser parameter set to True before launching.
    • If you are seeing this error randomly during crawls it can be caused by an overtaxed system, either memory or CPU usage. Try lowering the number of concurrent browsers.

  2. In older versions of firefox (pre 74) the setting to enable extensions was called extensions.legacy.enabled. If you need to work with earlier firefox, update the setting name extensions.experiments.enabled in openwpm/deploy_browsers/configure_firefox.py.

  3. Make sure you're conda environment is activated (conda activate openwpm). You can see you environments and the activate one by running conda env list the active environment will have a * by it.

  4. make / gcc may need to be installed in order to build the web extension. On Ubuntu, this is achieved with apt-get install make. On OSX the necessary packages are part of xcode: xcode-select --install.

  5. On a very sparse operating system additional dependencies may need to be installed. See the Dockerfile for more inspiration, or open an issue if you are still having problems.

  6. If you see errors related to incompatible or non-existing python packages, try re-running the file with the environment variable PYTHONNOUSERSITE set. E.g., PYTHONNOUSERSITE=True python demo.py. If that fixes your issues, you are experiencing issue 689, which can be fixed by clearing your python user site packages directory, by prepending PYTHONNOUSERSITE=True to a specific command, or by setting the environment variable for the session (e.g., export PYTHONNOUSERSITE=True in bash). Please also add a comment to that issue to let us know you ran into this problem.

Documentation

Further information is available at OPENWPM's Documentation Page.

Advice for Measurement Researchers

OpenWPM is often used for web measurement research. We recommend the following for researchers using the tool:

Use a versioned release. We aim to follow Firefox's release cadence, which is roughly once every four weeks. If we happen to fall behind on checking in new releases, please file an issue. Versions more than a few months out of date will use unsupported versions of Firefox, which are likely to have known security vulnerabilities. Versions less than v0.10.0 are from a previous architecture and should not be used.

Include the OpenWPM version number in your publication. As of v0.10.0 OpenWPM pins all python, npm, and system dependencies. Including this information alongside your work will allow other researchers to contextualize the results, and can be helpful if future versions of OpenWPM have instrumentation bugs that impact results.

Developer instructions

If you want to contribute to OpenWPM have a look at our CONTRIBUTING.md

Instrumentation and Configuration

OpenWPM provides a breadth of configuration options which can be found in Configuration.md More detail on the output is available below.

Storage

OpenWPM distinguishes between two types of data, structured and unstructured. Structured data is all data captured by the instrumentation or emitted by the platform. Generally speaking all data you download is unstructured data.

For each of the data classes we offer a variety of storage providers, and you are encouraged to implement your own, should the provided backends not be enough for you.

We have an outstanding issue to enable saving content generated by commands, such as screenshots and page dumps to unstructured storage (see #232). For now, they get saved to manager_params.data_directory.

Local Storage

For storing structured data locally we offer two StorageProviders:

  • The SQLiteStorageProvider which writes all data into a SQLite database
    • This is the recommended approach for getting started as the data is easily explorable
  • The LocalArrowProvider which stores the data into Parquet files.
    • This method integrates well with NumPy/Pandas
    • It might be harder to ad-hoc process

For storing unstructured data locally we also offer two solutions:

  • The LevelDBProvider which stores all data into a LevelDB
    • This is the recommended approach
  • The LocalGzipProvider that gzips and stores the files individually on disk
    • Please note that file systems usually don't like thousands of files in one folder
    • Use with care or for single site visits

Remote storage

When running in the cloud, saving records to disk is not a reasonable thing to do. So we offer a remote StorageProviders for S3 (See #823) and GCP. Currently, all remote StorageProviders write to the respective object storage service (S3/GCS). The structured providers use the Parquet format.

NOTE: The Parquet and SQL schemas should be kept in sync except output-specific columns (e.g., instance_id in the Parquet output). You can compare the two schemas by running diff -y openwpm/DataAggregator/schema.sql openwpm/DataAggregator/parquet_schema.py.

Docker Deployment for OpenWPM

OpenWPM can be run in a Docker container. This is similar to running OpenWPM in a virtual machine, only with less overhead.

Building the Docker Container

Step 1: install Docker on your system. Most Linux distributions have Docker in their repositories. It can also be installed from docker.com. For Ubuntu you can use: sudo apt-get install docker.io

You can test the installation with: sudo docker run hello-world

Note, in order to run Docker without root privileges, add your user to the docker group (sudo usermod -a -G docker $USER). You will have to logout-login for the change to take effect, and possibly also restart the Docker service.

Step 2: to build the image, run the following command from a terminal within the root OpenWPM directory:

    docker build -f Dockerfile -t openwpm .

After a few minutes, the container is ready to use.

Running Measurements from inside the Container

You can run the demo measurement from inside the container, as follows:

First of all, you need to give the container permissions on your local X-server. You can do this by running: xhost +local:docker

Then you can run the demo script using:

    mkdir -p docker-volume && docker run -v $PWD/docker-volume:/opt/OpenWPM/datadir \
    -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix --shm-size=2g \
    -it --init openwpm

Note: the --shm-size=2g parameter is required, as it increases the amount of shared memory available to Firefox. Without this parameter you can expect Firefox to crash on 20-30% of sites.

This command uses bind-mounts to share scripts and output between the container and host, as explained below (note the paths in the command assume it's being run from the root OpenWPM directory):

  • run starts the openwpm container and executes the python /opt/OpenWPM/demo.py command.

  • -v binds a directory on the host ($PWD/docker-volume) to a directory in the container (/opt/OpenWPM/datadir). Binding allows the script's output to be saved on the host (./docker-volume), and also allows you to pass inputs to the docker container (if necessary). We first create the docker-volume direction (if it doesn't exist), as docker will otherwise create it with root permissions.

  • The -it option states the command is to be run interactively (use -d for detached mode).

  • The demo scripts runs instances of Firefox that are not headless. As such, this command requires a connection to the host display server. If you are running headless crawls you can remove the following options: -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix.

Alternatively, it is possible to run jobs as the user openwpm in the container too, but this might cause problems with none headless browers. It is therefore only recommended for headless crawls.

MacOS GUI applications in Docker

Requirements: Install XQuartz by following these instructions.

Given properly installed prerequisites (including a reboot), the helper script run-on-osx-via-docker.sh in the project root folder can be used to facilitate working with Docker in Mac OSX.

To open a bash session within the environment:

./run-on-osx-via-docker.sh /bin/bash

Or, run commands directly:

./run-on-osx-via-docker.sh python demo.py
./run-on-osx-via-docker.sh python -m test.manual_test
./run-on-osx-via-docker.sh python -m pytest
./run-on-osx-via-docker.sh python -m pytest -vv -s

Citation

If you use OpenWPM in your research, please cite our CCS 2016 publication on the infrastructure. You can use the following BibTeX.

@inproceedings{englehardt2016census,
    author    = "Steven Englehardt and Arvind Narayanan",
    title     = "{Online tracking: A 1-million-site measurement and analysis}",
    booktitle = {Proceedings of ACM CCS 2016},
    year      = "2016",
}

OpenWPM has been used in over 75 studies.

License

OpenWPM is licensed under GNU GPLv3. Additional code has been included from FourthParty and Privacy Badger, both of which are licensed GPLv3+.