Back to Knowledge Hub
Fingerprint

Rebrowser Patches: What Changes After a Proxy Works?

Compare Rebrowser patches, original Playwright and a declared browser profile on one owned page. Separate library behavior, rendering observations and proxy routing.

BotBrowser Team

Documentation

Want the structured docs for Fingerprint?

This article lives in the editorial library. For step-by-step setup, reference material, and ongoing updates, jump into the docs section.

A working Rebrowser proxy connection does not specify the browser's canvas output, fonts or audio processing. First identify whether the application uses the open-source Rebrowser library patches, a hosted browser service, or both. Those are different configurations. BotBrowser provides declared profile controls for browser-exposed graphics, fonts and audio, but it cannot guarantee a destination's decision or make a changed proxy define a complete browser environment.

TL;DR

  • The pinned Rebrowser patches modify automation-library code, including execution-context handling and launch arguments. They do not replace the Chrome executable.
  • CDP can execute scripts and install scripts before a document runs. An API being outside a particular patch's scope does not make it unreachable through CDP.
  • On one owned Ubuntu fixture, original Playwright and the patched library returned the same four rendering observations across three independent launches each. The declared-profile configuration changed three observations; the audio result stayed the same.
  • The profile configuration used a different browser patch version and a Windows target on Ubuntu. Its differences are observations of that configuration, not an isolated measurement of an implementation layer.

Three configurations feed four page observations: original and patched libraries share one stock Chrome, while the profile configuration uses a different executable and declared target.

Contents

Separate a Rebrowser package from a proxy and a cloud browser

The phrase rebrowser proxy can hide three independent questions: which automation package runs, where its browser runs, and which route carries the request. Record each explicitly. Installing a package does not prove a proxy was used. Connecting to a remote browser does not prove that its filesystem, profile or executable matches a local installation. A changed public exit does not establish that a rendering input changed.

ConfigurationWhat it identifiesWhat still needs separate evidence
Original Playwright packageThe automation library and its versionBrowser executable, launch arguments and network route
Rebrowser drop-in packageA library with the project's patches appliedActual loaded package, underlying Chrome and chosen patch settings
Proxy connectionA route for the traffic assigned to itBrowser settings, stored state and the destination's interpretation
Hosted browser sessionA remotely operated browser serviceService-specific configuration, persistence and network behavior
Declared browser profileInputs applied to a supported browser environmentSuccessful loading, actual output and application compatibility

The official pinned README describes the drop-ins as the original libraries with patches applied and separately describes the vendor's cloud offering. A local package experiment therefore cannot support a claim about that cloud product's browser identities, proxy supply, prices or success rates. No cloud Rebrowser session was part of the comparison below.

If the request takes the wrong route, start with network evidence. An owned observer should establish the outgoing address, while an origin marker establishes which request arrived. Browser graphics values cannot tell whether a tunnel authenticated. The retained-context route diagnosis addresses changes in traffic routing; the launcher workflow addresses starting and managing configured browser sessions. Neither route evidence nor launcher success replaces checking the actual package loaded by an application.

Keep a proxy's credentials out of the comparison record. Package names, versions, browser hashes, a route label and the response from an owned observer are usually enough to separate these questions. If no authorized observer is available, mark the route unverified. A successfully rendered page does not identify the route that supplied it, and a rejected request does not identify which browser property the destination considered.

Read the actual patch before drawing a boundary

The inspected source is Rebrowser patches commit 31b51356499600f71126aae532f3d57abdc92272, including its Playwright 1.64.1 patch. The running packages were [email protected] and [email protected]. A package version and an upstream patch target are different identifiers; preserve both rather than assuming their final numeric components must match.

The pinned source patch changes execution-context setup, utility-world naming and other library behavior. Its launch-argument changes include the automation-controlled Blink setting and changes to several default switches. That is more specific than calling the project a collection of page-property replacements. Some changes affect how the library talks to Chrome, and some affect the options passed when Chrome starts.

Those details also explain why an unchanged canvas result does not establish that the patch failed. A change to context management has a different purpose from changing canvas pixels. The renderer can produce identical bytes while the automation library follows a different setup path. Conversely, obtaining a different string from one API does not prove that the rest of a browser environment is consistent.

The general protocol boundary needs equal care. CDP documents Runtime.evaluate and Page.addScriptToEvaluateOnNewDocument. A protocol client can run page scripts, including scripts that affect JavaScript-visible behavior. Therefore, “these pinned patches do not configure this rendering output” is a claim about an implementation. “CDP cannot affect rendering API values” would be a much broader claim, and the documented script-execution facilities do not support it.

Execution world is another experimental input. A script evaluated in an isolated world does not share every JavaScript binding with the document's main world. A comparison that changes both the library and the world used to read a value can attribute the difference to the wrong input. In this fixture, the document's own script performs the observations and posts them to its own origin. The driver navigates and waits for delivery; it does not collect the values by evaluating the observation function in a library-selected world.

Do not infer a destination outcome from this source inspection. The source establishes what a particular revision changes. It does not establish every consequence on every Chrome version, the behavior of another package installed under a similar name, or a website's decision process. Rebrowser's own claims about third-party sites were not independently tested here and are not used as a result.

Compare three configurations on one owned page

The controlled run used Ubuntu, headed browsers on the same display, a requested 1280 × 900 viewport and fresh independent browser-data directories. Each configuration ran three times, giving nine tasks in one global pool. The requested pool limit was 20, capped by the nine available tasks. Process sampling observed nine browser lanes active together, and the supervisor verified no residual processes belonging to the run. The original and patched pages reported 1280 × 900; the declared configuration reported 1288 × 944, so observed viewport size was not held constant across all three configurations.

LaneAutomation packageActual executable versionProfile
Original[email protected]Stock Chrome 157.0.8103.50No declared product profile
Patched[email protected]The same stock Chrome 157.0.8103.50No declared product profile
Declared[email protected]BotBrowser 157.0.8103.38Chromium 157 Windows x64 target on Ubuntu

The original-versus-patched comparison holds the stock executable constant. The third lane changes the executable and target configuration together. All three share a browser major, but their full versions are not identical. A difference in that third column cannot uniquely identify the effect of a profile, the executable's patch version or an implementation layer. It is a useful configuration record with explicit limits, not a controlled claim that one layer is superior.

The following table uses prefixes of the full SHA-256 values solely to keep the page readable. Full values, algorithms, repeated observations and environment records are retained in the executable fixture's output. A prefix is a label for this run, not an identity score.

The recorded observations, local comparison script and owned-page source are available for inspection. Save the script with a .mjs extension and the page beside it as render-fixture.html. The public script reproduces page observations; it does not perform the separate profile-loading audit used to accept the controlled run.

ObservationOriginalPatchedDeclared profile
Canvas RGBA SHA-256 prefix26cd080f5b9626cd080f5b960119c1c2e040
WebGL renderer, abbreviatedANGLE, Vulkan, SwiftShaderANGLE, Vulkan, SwiftShaderANGLE, NVIDIA Quadro P1000, Direct3D11
Candidate-font hitsArial; Times New Roman; Courier New; DejaVu Sans; Liberation SansSame five candidatesArial; Times New Roman; Courier New
Offline-audio sample SHA-256 prefix0d6f33df90bb0d6f33df90bb0d6f33df90bb
Last 500 absolute audio samples, sum124.04347776696522124.04347776696522124.04347776696522

These observations repeated within each lane across all three fresh launches. In particular, the audio samples did not change in the declared-profile lane for this input. A comparison must retain that equality rather than rounding it into a claim that profile configuration changes every fingerprint surface.

The accepted run's supervisor reported:

"comparisonPermitted": true,
"peakActive": 9,

That permission means the experiment's local prerequisites passed. Initial attempts lacked the required profile-loading log evidence and were not accepted as three-lane results. The final run retained successful decryption and loading evidence for the exact encrypted file, plus the declared Windows identity from the same page context. A filename, a launched process or a connected CDP session alone was not treated as proof of loading.

No external website was contacted for a detector verdict. The fixture did not use proxies, so it cannot measure Rebrowser proxy performance or compare proxy providers. Its result answers the narrower question of whether these four page observations changed under the recorded local configurations.

Interpret canvas, WebGL, fonts and audio separately

Canvas comparison used a fixed 300 × 80 canvas with fixed shapes, colors and text. SHA-256 was calculated over all 96000 bytes returned by getImageData, before image encoding. Comparing a PNG file or a data URL instead would introduce a different serialization input. Preserve the text, requested font, dimensions and drawing order when repeating the measurement. A changed hash locates a changed output; it does not explain whether fonts, rasterization, browser options or another input caused it.

WebGL comparison recorded the renderer exposed through WEBGL_debug_renderer_info when available. The reported renderer describes an exposed value, not a verified inventory of physical hardware. The Windows-target configuration reported a Direct3D renderer while running on Ubuntu, so presenting that string as the host's installed GPU would be misleading. If the extension or context is unavailable, the correct record is unavailable, not an empty renderer string silently compared as a match.

Fonts were deliberately a small candidate experiment. The candidates were Arial, Times New Roman, Courier New, DejaVu Sans, Liberation Sans and Noto Sans. For each, the fixture compared a fixed text width against serif, sans-serif and monospace fallbacks. A hit means the candidate altered the measured width under that method. It does not prove the exact font file exists, enumerate all installed fonts or distinguish every alias and substitute. The complete output preserves widths as well as the hit list so a coarse label cannot conceal the underlying observation.

Offline audio used one channel, 5000 frames at 44100 Hz, a triangle oscillator and a fixed compressor configuration. The output records a digest of the Float32 sample bytes and the absolute-value sum of the final 500 samples. This is an offline computation, not a recording from a microphone, sound card or speaker. Equal samples establish equality for that graph and input. They do not establish that every audio API, device or processing graph behaves identically.

Group agreement is also narrower than long-term stability. Three fresh launches on one host do not establish a value across operating-system upgrades, font changes, GPU-driver changes or another browser build. Equally, a single differing observation cannot reveal how a remote system combines signals. The documented browser-surface controls identify configurable product areas; the table establishes only the behavior actually observed for this selected configuration.

Reproduce the observation without testing a third party

Use a page under your control and keep its collection script identical across lanes. Pin both automation packages and supply explicit executable paths. Playwright documents that an alternate executable path carries compatibility risk, so successful operation with the tested Chrome versions must not be generalized into a promise for arbitrary future versions. Record a launch failure as a setup failure before making any comparison.

A small local reproduction can serve a page and save a posted result without asking a third-party checker to interpret it. With Node.js, the delivery portion can be:

import http from 'node:http';
import { readFile, writeFile } from 'node:fs/promises';

const page = await readFile('./render-fixture.html');
const server = http.createServer(async (request, response) => {
  if (request.method === 'GET' && request.url === '/') {
    response.writeHead(200, { 'Content-Type': 'text/html' });
    response.end(page);
    return;
  }
  if (request.method === 'POST' && request.url === '/results') {
    const chunks = [];
    let size = 0;
    for await (const chunk of request) {
      size += chunk.length;
      if (size > 131072) {
        response.writeHead(413).end();
        return;
      }
      chunks.push(chunk);
    }
    const record = JSON.parse(Buffer.concat(chunks).toString('utf8'));
    await writeFile('./observation.json', JSON.stringify(record, null, 2));
    response.writeHead(200).end('recorded');
    return;
  }
  response.writeHead(404).end();
});
server.listen(0, '127.0.0.1');

This delivery example is not a complete browser supervisor: run one result file per task, set a total deadline and close your own server and browser contexts after delivery. The full comparison fixture separates those tasks and records process cleanup. A fixed sleep is not its completion condition. It waits for the owned page's result POST, and a missing or invalid observation remains a failed task.

Use fresh independent data directories for a rendering-only comparison. Sharing one writable browser directory between concurrent processes introduces locking and state interference. If the intended question is session continuity, use a separate test contract that starts from controlled closed snapshots; do not silently add stored-state changes to a rendering comparison. Similarly, keep launch mode and viewport constant rather than changing headed versus headless at the same time as the library.

Retain unsupported outputs. A font candidate absent in both stock lanes, an unavailable graphics extension or an unchanged audio result can be more useful than a neat all-different table. These records explain which part of an assumption failed. They do not need to be converted into a product recommendation. For a broader explanation of library and browser responsibilities, the general patch-surface comparison supplies the surrounding distinction; this version-bound experiment supplies the specific observation.

Choose the next check from the failed operation

When an application still behaves unexpectedly after installing Rebrowser, preserve the first failed operation. The useful next action depends on whether failure occurred while importing the package, launching Chrome, navigating through a proxy, executing application code or receiving the destination's response. Changing browser settings before identifying that layer makes it harder to tell which change mattered.

SymptomFirst evidenceNext controlled action
The patch appears to have no effectLoaded package name, version and resolved locationConfirm that the application imports the patched core, not another installed copy
A browser will not launchExecutable version, launch error and selected libraryCheck compatibility using a known controlled page
Requests take an unexpected routeOwned observer result and route configurationCorrect routing separately from graphics settings
A rendering value stays unchangedSame page input, executable and observation methodRead whether that pinned patch actually changes that input
Application code differs between worldsContext choice and access to document bindingsCheck execution-world requirements before changing values
A destination rejects an actionActual response and the operator's documented policyStop at the authorized diagnostic boundary; do not infer a hidden scoring rule

For imports, checking package.json alone is insufficient when a workspace contains multiple dependency trees or aliases. Log the version resolved from the running application's location. The pinned Rebrowser README documents a historical drop-in/core dependency issue; that is a reason to verify the actual package, not a claim that every installation suffers it. Reinstalling an unrelated top-level package does not establish which core the application loaded.

For rendering requirements, define the required output before selecting a control. A workload that only needs a page to render successfully has a different acceptance check from a workload that must preserve declared graphics settings across sessions. BotBrowser's automation-consistency reference documents product behavior at that boundary, but neither a configured profile nor a library patch can certify a destination's identity classification.

FAQ

Does Rebrowser replace Chrome?

The open-source drop-in libraries inspected here patch automation-library code and use a separately supplied or installed browser. A hosted service is a separate product scope.

Can a CDP client affect canvas values?

CDP can execute page scripts. The supported claim is about what a particular implementation actually modifies, not an absolute inability of the protocol to influence a JavaScript-visible result.

Do matching values mean the patch did nothing?

No. This fixture measures four rendering observations. Library changes to context setup or launch arguments can be relevant without changing those four outputs.

Does a proxy give the browser a different profile?

A proxy configuration selects routing for traffic within its scope. It does not, by itself, define fonts, a canvas input or an offline audio graph.

Sources

Practical conclusion

Start with the exact package, executable and operation that failed. In this fixed experiment, the Rebrowser library patch left four rendering observations equal to original Playwright, while the declared-profile configuration changed canvas, renderer and candidate-font observations but left audio equal. Those results answer a local configuration question. They do not rank products, characterize a cloud service or predict a destination's decision. Keep routing, automation-library behavior and declared browser settings as separately verifiable inputs.

#Rebrowser#Playwright#Browser Profiles#Proxy Troubleshooting

This article is part of the guide: What Is a Browser Fingerprint?

Run the same check in BotBrowser

Load a profile, keep the signals you just read about consistent inside the browser, and confirm the result on your own machine before a rollout.