ovobrowser patches Chromium in C++ but ships only binaries, and only for Windows
源码级 Chromium 指纹内核,检测站按普通 Chrome 评分。Source-level Chromium fingerprint kernel that passes bot detection tests. Not JS injection — C++ patches compiled into the binary.
At a glance
- What is it?
- A fingerprint browser kernel built by editing Chromium source and recompiling, offered as three Windows portable zips under one release. The technique is the interesting part; what the repository actually contains is not.
- Who is it for?
- Read ovobrowser as a build recipe and a set of flag semantics, not as source you can audit, because no C++ appears in the repository. Anyone planning real work with it should first accept that using a fingerprint kernel to defeat a site's bot checks is a terms-of-service decision their own employer or client has to make, and second confirm that spoofing identities you do not control is out of scope.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 39 days ago.
- What is it written in?
- GitHub does not report a main language for this repository.
Answers come from the project's GitHub data, last synced on October 5, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The repository holds a README and three directories, and no Chromium source
The central claim is that the fingerprint lives in C++ and is compiled into the binary, explicitly not as JavaScript injection and not as the runtime patches used by tools like playwright-stealth. The comparison table puts the modification site at Chromium C++ source rather than at JS, CDP or assembled startup arguments, and argues that injection tools break every time Chrome updates while this rebase travels with the kernel version.
The repository itself does not let you check any of that. The top level is `.gitattributes`, `.gitignore`, `LICENSE`, `README.en.md`, `README.md`, plus `docs/`, `examples/` and `video/`. There is no `src/` directory, no build script and no patch series, and the metadata records the primary language as unknown. The table's own wording points at this repository's portable package rather than at its source, which is consistent with what is actually here.
So the C++ claim is a statement about how the binaries were produced, published as prose plus a download, and not as reviewable code. The MIT `LICENSE` covers the four documentation files and the examples; it says nothing about the C++ that would have to be present to patch it yourself.
What is present is decently organized for a consumer. Documentation is bilingual, with `README.en.md` beside `README.md`, `docs/` for detail, `video/` for capture, and `examples/` carrying a separate language binding for each of the seven languages the quick start names: Python, Node, Go, C#, PowerShell, Java and Rust. Those seven directories match the seven the prose promises.
Three Chromium versions live in one release, all Windows x64, and the oldest is 138
There is exactly one release, v1.0.0, cut on 2026-08-23, and it carries all three kernels at once: 150 at `150.0.7871.124`, 144 at `144.0.7559.132` and 138 at `138.0.7204.183`. Each ships as a separate `win64-portable.zip` under that tag. Unzip and the kernel is the `chrome.exe` in the directory.
The platform ceiling is the hard constraint. There is a Windows x64 package and nothing else: no macOS build, no Linux build, no architecture other than x64. Anyone on a Mac or on Linux gets nothing from this repository.
Choosing between the three is a fingerprint decision as much as a compatibility one. The guidance is to take 150, on the grounds that it is friendlier to the machine learning inside FingerprintJS, and that the switch sets across the three are broadly the same. The stated differences are narrow: 144 and 150 carry more complete audio noise, and the canvas values are aligned between the main thread and a Worker.
Kernel 138 is the one to watch. It is the oldest of the three and is carried for compatibility rather than recommended, and a fingerprint that reports an old Chrome will be unusual to any check that tracks version distribution.
Pass no switch and you get the real machine, including the host display scaling
The operating rule is simple and worth memorising before touching any flag: an absent switch means the real machine or the upstream default, and a passed switch means the value you supplied. Nothing is inferred and nothing is randomised on your behalf.
That rule has a sharp edge. `--fingerprint-device-scale-factor` drives `devicePixelRatio`, the CSS `resolution` media feature and the `Sec-CH-DPR` header. Left unset, it falls through to the host machine's display scaling, which the documentation calls out as a leak of the real machine. So the one value you might skip thinking about is the one that quietly reintroduces what you were trying to remove.
Screen geometry has the same pairing problem. `--fingerprint-screen=` sets `screen.width`, `screen.height` and the `avail*` values in CSS logical pixels, and 144 and 150 also accept the component form through `--fingerprint-screen-width=` and `--fingerprint-screen-height=`, which is described as equivalent to the combined switch. `--fingerprint-screen-color-depth=` sets `colorDepth` and `pixelDepth`, with 24 in the worked example.
The worked launch line pairs `1536x864` with a device scale factor of `1.25`, and the documentation makes the pairing explicit rather than leaving it to the reader. A screen size and a scaling value that belong to different machines read as inconsistent even when each value is individually plausible.
The UA wants major.0.0.0 while brand-version wants the full four-part patch number
The two version fields deliberately disagree in shape, and getting them backwards costs a score. Inside the user agent string the version must be the major version followed by three zeroes, as in `Chrome/150.0.0.0`. The full patch number belongs only in `--fingerprint-brand-version`, which sets the full version in UA-CH `brands`. Write the four-part build into the user agent instead and BrowserScan reports a different browser version penalty of five percent.
That is the kind of small internal contradiction that separates a hand-tuned profile from a generated one, and it is the reason the documentation gives both numbers for every kernel.
Two more version-adjacent behaviours are automatic. With `--fingerprint-platform=ios`, `navigator.userAgentData` is hidden, because a real Safari on that platform has no such API. The GREASE brand is generated by the kernel from the major version, so there is nothing to hand-write for it.
The product name is `ovobrowser` in the task manager, the about page and the default user data directory. The user agent and Client Hints still say Chrome on purpose: renaming those to ovobrowser gets the browser classified as unknown, which is exactly what the whole exercise avoids.
Hardware fields follow the same absent-equals-real pattern. `--fingerprint-hardware-concurrency=` takes a core count, `--fingerprint-device-memory=` takes `0.25`, `0.5`, `1`, `2`, `4` or `8` with 8 as the default, `--fingerprint-dnt=` takes `1`, `0` or `unspecified`, `--fingerprint-battery=` takes four comma-separated values, and passing `--fingerprint-disable-speech-voices` empties the speech synthesis list.
WebGPU and Bluetooth can be made to not exist, and WebRTC stops leaking the local address
Three switches remove API surface rather than rewrite values. `--fingerprint-webgpu=disable` sets `navigator.gpu` to null so no adapter is exposed. `--fingerprint-disable-bluetooth` does the same for `navigator.bluetooth`. In both cases the API is absent, not faked, and in both cases the default is the real machine's state.
The WebRTC control is different in kind. `--webrtc-ip-handling-policy=` sets the ICE candidate policy, with `disable_non_proxied_udp` given as the recommended value and also as the same default. The stated effect is that WebRTC stops exposing the local network address.
GPU identity is the remaining piece, and it is two strings rather than one. `--fingerprint-gpu-vendor=` sets `UNMASKED_VENDOR_WEBGL` and `--fingerprint-gpu-renderer=` sets `UNMASKED_RENDERER_WEBGL`. The worked value pairs `Qualcomm` with an ANGLE renderer string naming the same part, and the rule given for both is that they must be a matched set from one real GPU.
That constraint is the section's real lesson, and it is the one most often ignored. A mobile user agent paired with a desktop Direct3D 11 or RTX renderer string reads as fake on sight. Five independent noise families sit on top of this surface and can be disabled or given a fixed seed: Canvas, WebGL, Audio, ClientRects and Font.
Timezone and language have to agree with the exit IP, not with you
Three switches carry locale, and the documentation ties them to geography rather than preference. `--timezone=` sets what JavaScript sees through `Intl` and `Date`. `--lang=` sets the interface language, `navigator.language` and the Intl locale. `--accept-lang=` sets the request header value. The instruction that accompanies them is to change timezone and language to wherever the exit IP actually is.
That is the single most common way a hand-built profile fails: a profile whose declared locale contradicts the network it leaves from. It is also the one field group where the answer is not a preference decision at all, which is why the worked launch line is described as a skeleton that you still have to localise.
The proxy is a separate concern from the locale, with its own section covering proxies that carry credentials. Worth noticing is what the worked example does not contain: it sets the browser path, the profile directory and the target URL, and passes locale, screen, hardware and UA values on the command line, but it shows no proxy switch in that line. Those three environment variables are the common setup shared by every language example:
set OVO_CHROME=D:\ovobrowser-150\chrome.exe
set OVO_PROFILE=D:\ovobrowser-profiles\acc01
set OVO_URL=https://demo.fingerprint.com/playgroundThree environment variables stand in for the whole command line in the examples
The examples for all seven languages share a common setup, expressed as three environment variables rather than repeated per language: the path to the patched `chrome.exe`, the profile directory, and the URL to open. Written for a Windows shell, it is three `set` lines. That is the whole per-language contract, which is why bindings exist for Python, Node, Go, C#, PowerShell, Java and Rust without any of them needing to know what the fingerprint flags mean.
It is worth being clear about what this arrangement does and does not give you. It gives you one executable, one profile directory per account, and a repeatable way to launch them. What it does not give you is an audit surface, because the fingerprint logic lives inside the binary rather than in anything you can read in this repository.
For ordinary users there is also a separate graphical client, linked from the README under a different repository name, that manages environments, proxies, teams and window synchronisation without hand-assembling command lines, with bilingual documentation and screenshots. That client is a separate project; the portable kernel in this repository is the underlying binary.
One last number to keep in view: the README lists ten detection sites whose results are shown, from demo.fingerprint.com and browserscan.net through bot.sannysoft.com, bot-detector.rebrowser.net, CreepJS and fingerprint-scan.com. Those are presented as evidence, which is a fair thing to check yourself, but they are not a claim about any site that is not on the list.
Editorial conclusion
Read ovobrowser as a build recipe and a set of flag semantics, not as source you can audit, because no C++ appears in the repository. Anyone planning real work with it should first accept that using a fingerprint kernel to defeat a site's bot checks is a terms-of-service decision their own employer or client has to make, and second confirm that spoofing identities you do not control is out of scope. Beyond that, check the platform ceiling (Windows x64 only), the kernel age, and whether the missing source blocks your own audit before you depend on it.
Frequently asked questions
How is ovobrowser different from playwright-stealth?
ovobrowser changes the fingerprint in Chromium C++ source and compiles it into the binary, while playwright-stealth and puppeteer-extra work at the JS, CDP or startup-argument level. Detection sites are said to see ordinary Chrome APIs from the compiled-in approach.
Which operating systems does ovobrowser ship for?
Only Windows x64. Release v1.0.0 publishes three win64 portable zips for kernels 150.0.7871.124, 144.0.7559.132 and 138.0.7204.183, and there is no macOS or Linux package.
Does the ovobrowser user agent say Chrome or ovobrowser?
It says Chrome, and that is deliberate. The product name is ovobrowser in the task manager, the about page and the default user data directory, but the user agent and Client Hints still report Chrome because renaming those gets the browser classified as unknown.
Do the ovobrowser WebGL vendor and renderer strings have to match?
Yes, they have to be a matched set from one real GPU. The documentation gives Qualcomm with a matching ANGLE renderer string as the example, and warns that a mobile user agent with a desktop RTX or Direct3D 11 renderer reads as fake.
What are OVO_CHROME, OVO_PROFILE and OVO_URL used for?
They are the shared setup for all seven language examples: the path to the patched chrome.exe, the profile directory, and the URL to open. They are set the same way in the Python, Node, Go, C#, PowerShell, Java and Rust bindings.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ovobrowsersupport-ovobrowser)