This tool monitors canvas fingerprinting techniques on the Ozon website by intercepting and logging canvas-related operations.
IMPORTANT: This project is not intended for production use. It is just a proof of concept.
This project started as a small research project but was later inspired by CanvasInspector from BAS, https://wiki.bablosoft.com/doku.php?id=perfectcanvas.
- Monitors canvas creation and manipulation
- Supports both 2D and WebGL canvas contexts (including WebGL2)
- Captures context attributes like preserveDrawingBuffer for WebGL
- Track canvas dimension changes
- Captures canvas data URL conversions
- Logs all canvas events with timestamps and stack traces
- Intercepts and records all canvas drawing operations (fillRect, fillText, arc, etc.)
- Generates JavaScript code that can recreate each canvas with all its operations
- Saves collected data to JSON files in the output directory
- Saves full canvas images with size and hash information in the filename
- Saves JavaScript code files that can recreate each canvas
- Generates an interactive HTML report with all canvas images and code
- Well-documented and maintainable code with modular design
To work on this project, you'll need the following tools installed on your system:
- Python: Version 3.10 or newer
- Install from python.org
- Ensure you add Python to your PATH during installation
- Poetry: For dependency management and packaging
- Install using the official installer:
(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | python -
- Or via pip:
pip install poetry
- Install using the official installer:
- Make: For running development commands
- Install using GnuWin32
- Or via Chocolatey:
choco install make
- Git: For version control, install from git-scm.com or
via Chocolatey
- Or via Chocolatey:
choco install git
- Or via Chocolatey:
- Windows OS: This project is designed to work only on Windows systems
- Clone this repository
- Install Python dependencies:
poetry install
For JavaScript development, see the monitor/README.md file.
Important: Before running any Python code, you must first build the JavaScript code in the monitor directory. Navigate to the monitor directory, install dependencies, and build the JavaScript bundle:
cd monitor npm install npm run build
Or you can use the Makefile in the root directory:
make js_build
This step is required because the Python code depends on the bundled JavaScript file.
Run the monitoring script:
python main.py
The script will:
- Launch a Chrome browser
- Navigate to ozon.ru
- Monitor canvas operations
- Save collected data to the
output
directory with timestamp in filename format:canvas_logs_YYYYMMDD_HHMMSS.json
- Extract and save all canvas images to the
output/images
directory with enumerated filenames that include the canvas dimensions and image hash (1_canvas_width_height_hash.png, 2_canvas_width_height_hash.png, etc.) - Save JavaScript code files that can recreate each canvas to the
output/code
directory - Generate an interactive HTML report (
canvas_report_YYYYMMDD_HHMMSS.html
) with all canvas images and code
Note: The Ozon website requests 5 canvas images and 1 for audio for non-logged-in users. The monitoring script waits until it detects 5 unique canvas images before saving the data.
The project includes a Makefile with useful commands:
# Show available commands
make help
# Clean the output directory (preserves .gitkeep files)
make clean
The clean
command removes all files from the output directory except for .gitkeep files, which is useful before
running the monitor again or when you want to start with a clean slate.
The collected data is saved in JSON format in the output
directory. Each file contains an array of canvas events with
the following information:
- Event type (canvas-created, canvas-snapshot, dimension-change, context-created)
- Timestamp
- Message
- URL
- Line number
- Additional data specific to the event type
Additionally, canvas images are saved in the output/images
directory with enumerated filenames that include the canvas
dimensions and image hash:
- Format:
N_canvas_width_height_hash.png
where:- N is a sequential number (1, 2, 3, etc.)
- width and height are the canvas dimensions in pixels
- hash is a unique identifier of the image content
- Example:
1_canvas_350_200_1a2b3c4d.png
,2_canvas_800_600_5e6f7g8h.png
, etc.
The JavaScript code that can recreate each canvas is saved in the output/code
directory with similar enumerated
filenames:
- Format:
N_canvas_width_height_hash.js
where:- N is a sequential number (1, 2, 3, etc.)
- width and height are the canvas dimensions in pixels
- hash is a unique identifier of the image content
- Example:
1_canvas_350_200_1a2b3c4d.js
,2_canvas_800_600_5e6f7g8h.js
, etc.
These JavaScript files contain self-contained code that can be executed in a browser console to recreate the exact canvas with all its drawing operations. The code is well-formatted with comments and supports both 2D and WebGL contexts.
For 2D contexts, the code follows this format:
;(async function () {
// Create canvas element
var canvas = document.createElement("canvas");
canvas.width = 300;
canvas.height = 150;
// Create rendering context
var context = canvas.getContext('2d');
// Canvas operations
context.fillStyle = "#f60";
context.fillRect(125.0000000000, 1.0000000000, 62.0000000000, 20.0000000000);
// ... more canvas operations ...
// Convert canvas to data URL and return as hex string
var str = canvas.toDataURL("image/png");
// ... conversion to hex ...
return Promise.resolve(hex);
})();
For WebGL contexts, the code includes the context attributes (like preserveDrawingBuffer):
;(async function () {
// Create canvas element
var canvas = document.createElement("canvas");
canvas.width = 300;
canvas.height = 150;
// Create rendering context
var context = canvas.getContext('webgl', {
"preserveDrawingBuffer": true,
"antialias": true
});
// WebGL operations are not recorded due to complexity
// This is a placeholder for WebGL code
// Convert canvas to data URL and return as hex string
var str = canvas.toDataURL("image/png");
// ... conversion to hex ...
return Promise.resolve(hex);
})();
The original filenames (which include canvas dimensions and hash) are preserved in the logs.
The HTML report provides a user-friendly way to view all the canvas fingerprinting data in a single file. The report includes:
- A summary section with the report generation time, total canvas events, and unique canvas images
- A section for each canvas with its dimensions, context type, and hash
- Interactive tabs to switch between viewing the canvas image and the JavaScript code
- Syntax-highlighted JavaScript code for better readability
- Responsive design that works well on different screen sizes
The HTML report is saved to the output directory with the filename format canvas_report_YYYYMMDD_HHMMSS.html
. You can
open this file in any web browser to view the report.
The report is designed to be self-contained and doesn't require any external resources, making it easy to share with others. It provides a comprehensive view of all canvas fingerprinting activities detected during the monitoring session.
The report allows you to:
- Quickly identify all canvas operations used for fingerprinting
- View the exact images generated by each canvas
- Examine the JavaScript code used to create each canvas
- Compare different canvases side by side
- Save or print the report for documentation purposes
See the LICENSE file for details.