Assignment 3 โ€“ Somebody's Always Watching ๐Ÿ‘๏ธ

Welcome to Assignment 3 for CS 253: Web Security. โœจ

Prepare

Check your Node.js version

You should already have Node.js installed from previous assignments. For this assignment, it's highly recommended to use Node.js 16. Open your terminal and run this command to confirm you're running some version 16.x.x:

node --version

If not, you can install Node.js from the official site.

Get the starter code

Run this command to clone the code with git:

git clone https://github.com/stanford-web-security/assign3.git

Enter the folder you just created:

cd assign3

Install the necessary local dependencies with npm:

npm install

Start the assignment

Run the local server:

npm start

Your browser should open up to http://localhost:4001/ where you can begin the assignment. The page should display the fingerprint 359d-b414-6f2d-fb8c at the bottom of the page, corresponding to a hash of the placeholder string "userid" in the starter code.

TIP: If you don't see the hash at the bottom of the page (the page may say [loading] instead), then you may have an ad-blocker running. You will likely want to turn off ad-blockers for the http://localhost:4001/ site, as they may block some of your intended behavior. We will test all of the grading criteria below with ad-blockers turned off as well.

Part 1: Coding Portion (36 points)

Instructions

The only coding file you will need to modify for this assignment is fingerprint.js. Your goal is to implement a fingerprinting technique in fingerprint.js that generates a unique identifier for a user across multiple browsing sessions (see Grading below for the exact conditions that we will be testing your fingerprinting on). The fingerprint.js script will be executed on the client side and will have full access to the DOM, including the ambient window, document, and navigator objects.

The return value of your fingerprint function should be a string, which will likely be a hash of several fingerprinting vectors. We have provided a hash function that you can feel free to use (defined in hash.js), which takes in any number of arguments (each of which can be a string, number, JSON object, etc.), and returns a hash corresponding to those arguments. You can view the return value of your fingerprint function by visiting http://localhost:4001/ in your browser. Feel free to make liberal use of console.log statements as well to help with debugging, which you can view using the browser Dev Tools console as usual.

If you choose, you may also extend the server-side code to provide information on HTTP headers (or anything else you think might be helpful for your fingerprinting) to fingerprint.js. To do so, modify your-server-code.js with any new endpoints that you wish to call, which you can then call in fingerprint.js. Note that this is not at all required, and it's definitely possible to receive full credit without modifying the server-side code.

Requirements

Grading

We will grade your fingerprinting technique under the following situations, and will award points if the corresponding criteria for the return value of fingerprint.js are met.

Part 2: Short Answer Questions (24 points, 6 per question)

Your answers should be concise. Each answer should not exceed 300 words. Include your answers in REPORT.md.

  1. What fingerprinting methods did you use? Why did you choose them?

  2. What limitations does your fingerprinting implementation currently have? In what situations would the fingerprinting fail?

  3. Suppose you are working on a privacy-preserving web browser. Describe ONE way to defend against your fingerprinting methods (or explain why your method is unable to be defended against).

    Analyze the costs of your proposed mitigation strategy, in terms of performance, user experience, and web compatibility.

  4. Choose ONE of the following browser anti-fingerprinting initiatives. Do they defend against your fingerprinting methods? If so, how could you modify your fingerprinting methods to continue to work despite those new policies?

Part 3: Survey (3 points)

Your feedback matters a lot! Please help us improve by answering the survey questions in SURVEY.md. As a reward, enjoy some easy points!

Submit

Before you submit

Ensure that the sanity tests pass:

npm test

This command just runs a basic sanity test that ensures your project passes npm run lint. If npm test doesn't report any errors that doesn't necessarily mean that you've solved every exercise perfectly!

๐ŸŒŸ PRO TIP: You can automatically fix most lint errors by running:

npm run lint-fix

Gradescope

We'll use Gradescope for submissions.

The moment of truth

When you're ready to submit your work, you'll upload three files to Gradescope: fingerprint.js, REPORT.md, and SURVEY.md. (Note: if you chose to modify the server code in your-server-code.js as well, please also submit your-server-code.js.)

You should submit early and often! There's no downside to repeatedly submitting your assignment.

Resources

In addition to the lecture slides from this class, you can use the two references below to get a better idea of common fingerprinting vectors.