fix(js-instrument): match native function arity and name on wrappers - #1210
Draft
vringar wants to merge 1 commit into
Draft
fix(js-instrument): match native function arity and name on wrappers#1210vringar wants to merge 1 commit into
vringar wants to merge 1 commit into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1210 +/- ##
==========================================
- Coverage 62.22% 62.20% -0.03%
==========================================
Files 40 40
Lines 3929 3929
==========================================
- Hits 2445 2444 -1
- Misses 1484 1485 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
vringar
force-pushed
the
fix/legacy-instrument-arity-name
branch
from
June 30, 2026 18:11
601eb76 to
4396c14
Compare
vringar
force-pushed
the
fix/legacy-instrument-arity-name
branch
from
July 20, 2026 22:54
4396c14 to
1d0ba91
Compare
vringar
added a commit
that referenced
this pull request
Jul 20, 2026
…-instruments mitigation (do-not-merge) Runs PR #1210's TestJSInstrumentFunctionArityAndName against un-fixed master (Extension/src/lib/js-instruments.ts is NOT patched). The wrapper closure reports length 0 / name "" so the instrumented fetch call is expected to log arity-0.example.com/name- instead of arity-1.example.com/name-fetch, making the tests shard fail. This failure is the proof that the test is a genuine guard. Do-not-merge verification branch.
The legacy JavaScript instrument replaces native methods with a closure
wrapper. The wrapper's page-observable `length` (arity) and `name` did not
match the native function: a wrapped method reported `length === 0` and
`name === ""` regardless of the native value. This is trivially detectable
from page script (e.g. native `getImageData.length === 4`,
`getImageData.name === "getImageData"` vs the wrapper's `0` / `""`).
Copy the native function's own `length` and `name` descriptors onto the
wrapper, preserving the native non-writable / non-enumerable / configurable
shape, so the wrapper is indistinguishable from native on these two axes.
Adds a browser-level regression test that instruments `window.fetch` and
asserts the wrapper reports the native arity (1) and name ("fetch").
The separate proto-chain flattening artifact is out of scope: de-polluting it
would silently drop inherited-member capture that collection_fingerprinting
relies on (tradeoff-blocked).
vringar
added a commit
that referenced
this pull request
Aug 25, 2026
…-instruments mitigation (do-not-merge) Runs PR #1210's TestJSInstrumentFunctionArityAndName against un-fixed master (Extension/src/lib/js-instruments.ts is NOT patched). The wrapper closure reports length 0 / name "" so the instrumented fetch call is expected to log arity-0.example.com/name- instead of arity-1.example.com/name-fetch, making the tests shard fail. This failure is the proof that the test is a genuine guard. Do-not-merge verification branch.
vringar
force-pushed
the
fix/legacy-instrument-arity-name
branch
from
August 25, 2026 09:18
1d0ba91 to
7bef7e2
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The legacy JavaScript instrument (
Extension/src/lib/js-instruments.ts) replacesnative methods with a closure wrapper (
instrumentFunction). The wrapper'spage-observable
length(arity) andnamedid not match the nativefunction it wraps: every wrapped method reported
length === 0andname === "",regardless of the native value. Both are trivially readable from page script and
make instrumented methods fingerprintable.
This PR copies the native function's own
lengthandnameproperty descriptorsonto the wrapper (preserving the native non-writable / non-enumerable /
configurable shape), so the wrapper matches native on these two axes.
Empirical before/after (direct-selenium, FF152, no extension)
Repro injects the real compiled
getInstrumentJS(via.toString(), exactlyas the extension's
${getInstrumentJS}template-literal does) as an inline<script>, headless, no extension. It instruments concrete native methods andreads the wrapper's
.length/.name:CanvasRenderingContext2D.prototype.getImageData.length404CanvasRenderingContext2D.prototype.getImageData.name"getImageData""""getImageData"HTMLCanvasElement.prototype.toDataURL.name"toDataURL""""toDataURL"Both artifacts reproduced before the fix and are gone after. Instrumentation
still logs the calls in both runs (no capture regression).
Regression test
test/test_js_instrument.py::TestJSInstrumentFunctionArityAndNameinstrumentswindow.fetchin a real browser, reads the wrapper's observable.length/.namein-page, and encodes them into a
fetchcall argument so they land in thejavascripttable. Nativefetchhas arity1and name"fetch"; the testasserts the logged call argument is
https://arity-1.example.com/name-fetch.Verified the negative: with the fix disabled (wrapper left unchanged) the test
fails (observed
arity-0/name-), confirming it is a genuine guard. Thefull
test/test_js_instrument.pysuite passes (8 tests).Out of scope
The separate proto-chain flattening artifact (#56 sub-item iii) is not
addressed here. For the legacy plain-JS-wrapper architecture, de-polluting the
flatten would silently drop inherited-member capture that the bundled
collection_fingerprintingrelies on (per-interface attribution of inheritedmembers is structurally tied to the per-leaf copy-down). It is tradeoff-blocked
and intentionally left untouched.
Refs crosslink #56.