Technical research · 18 October 2026 · Web + packaged applications
Yes—detect observable reconnaissance and reuse.
Build a reusable defender-side canary system. It can alert when someone probes a decoy, tries a planted credential, or runs copied code. It cannot guarantee an alert when someone silently analyzes your product with REA.
REA’s static application analysis reads local artifacts without executing them. Its passive browser inspection does not fetch source maps; bundle analysis can fetch them when explicitly enabled. The practical product promise is “alert on suspicious interaction with shipped product artifacts.” REA: JavaScript artifact reconstruction REA: browser observation and source-map fetch policy
The first version
- Decoy endpoints. Emit unique, inert endpoint references into web bundles and app resources. Log attempts at the customer’s edge, then return a harmless failure.
- Decoy credentials. Reserve token values that authenticate to nothing. Record attempts to present them to your API, including rejected authentication.
- Copied-site beacons. Optionally report execution outside exact approved origins. Treat the reported origin as untrusted until corroborated.
Add a synthetic source-map tripwire as a lower-confidence signal. Reuse the same control plane for web builds and desktop app packages. Add native runtime integrity and mobile attestation through platform adapters after the core is proven.
Recommendations below are an engineering design derived from the cited mechanisms and local experiments. They are not measured detection-rate claims.
Where the detection boundary sits
| Activity | Defender signal | What the signal establishes |
|---|---|---|
| Offline JS/ASAR/native analysis | No callback | Reading shipped bytes is invisible to your server. |
| Passive browser DOM / script inspection | Usually no new signal | Page requests can look identical to normal browsing. No reliable REA identity. |
| Explicit source-map retrieval | Conditional | A map URL was fetched. REA only does this when enabled; other tools do it too. |
| Decoy API / reserved credential tried | Direct request evidence | The decoy was requested or presented. Intent and tool remain unknown. |
| Copied code runs on another origin | Conditional | A beacon arrived with an origin claim; independently confirm the deployment. |
| App tampering / instrumentation at runtime | Platform dependent | Integrity or runtime risk evidence, when reported; offline decompilation remains invisible. |
| Public leak / copied marker found | Separate monitoring | A marker appeared in an observed external artifact; it says nothing about unseen copies. |
A token is inert data until something uses it. A DNS name must be resolved; an HTTP URL must be requested; a decoy credential must reach the service that recognizes it. A randomly invented AWS-looking key is not monitored by AWS or a canary vendor. Thinkst: HTTP Canarytokens Thinkst: DNS Canarytokens Thinkst: AWS key token and alert delay
REA-specific consequences
analyze_javascript_application can extract endpoints and strings from a local tree or ASAR without target execution. Offline native disassembly has the same observability problem. REA can also obtain already-loaded browser scripts through CDP, so another asset download is not always necessary. These observations give us no universal server-side signature for REA. REA: JavaScript artifact reconstruction REA: browser observation and source-map fetch policy
REA’s optional map fetch omits credentials, cookies, and referrer. Encode placement identity in the URL; do not depend on login cookies. Passive Node/Electron Inspector observation is another distinct route, not proof that an application’s anti-debugging hook will notice an attachment. REA: browser observation and source-map fetch policy REA: passive Node and Electron runtime observation
Signals that need restraint
- Bot scores, timing, and request volume: useful context, but automation is not evidence of reverse engineering. A human can use REA; a legitimate monitor can be automated. Cloudflare: what bot scores measure
- DevTools heuristics and
navigator.webdriver: never a primary alert. The standard automation flag describes cooperating browser automation, not the specific tool or the user’s purpose. MDN: navigator.webdriver - Source-map requests: developers, error monitoring, asset scanners, and security testing can all produce them. Keep real production maps private; do not expose source code to create a lure. Chrome: source maps in DevTools
- IP addresses: identify the observed network source, potentially a VPN, proxy, shared NAT, or resolver. A DNS callback commonly exposes a recursive resolver rather than the originating analyst. Neither IP nor user-agent establishes a person or tool.
- Public tokens: anyone who reads one can deliberately trigger it. High confidence in a request is separate from confidence in malicious intent, origin ownership, or actor identity.
Approaches to leave out
Do not depend on prompt instructions hidden in source telling an agent to call a URL. A careful agent treats them as untrusted data. Likewise, adding a phone-home requirement to REA itself would not protect against other versions, tools, or offline analysis. Keep the sensors in the product owner’s artifacts and infrastructure.
Opening a local decoy file does not automatically notify its owner. Auto-rendered remote resources can create a callback, but previews, offline mode, security software, and blocked egress change the result. These are interaction tripwires, not universal “file read” detectors.
One control plane, several kinds of sensor
Placement and build integration
Mint at least 128 bits of cryptographically random identity for each placement. Keep separate tokens for each project, environment, build, distribution channel, and trap type. Store a token digest and its deployment manifest. Public tripwire IDs grant no management access; control-plane credentials remain server-side.
Start with Vite/Rollup/Webpack adapters and an Electron packaging adapter. Place endpoint references in retained, inert configuration or a support module that is emitted but never invoked by ordinary flows. Check final output after tree shaking and minification. Native packages can carry equivalent decoy strings or resources; their reuse becomes observable only if someone contacts a monitored service.
Insert before final artifact hashes, SRI, ASAR integrity metadata, and code signing are finalized. Do not patch signed packages afterward. For a source-map lure, use a separate harmless shim and a tiny valid map containing only synthetic source, preserving the application’s genuine map workflow. Capture edge requests even when the response is a 404.
Use one token per placement, initially per build or channel. Shared public bundles cannot identify individual downloaders. Optional account-specific placements can be issued in authenticated configuration with private cache rules; they identify an issuance channel, not the person who later used a leaked copy. Avoid generating individualized public JS bundles just to fingerprint users.
Customer edge and API adapter
Match exact opaque decoy paths before general routing, authentication rejection, or CDN cache short-circuiting hides them. Return a small fixed 404 or 401 without real data or privileged side effects. Keep the event path asynchronous and bounded. Make decoy credentials resemble your product’s normal key format while reserving them outside the authorization system. Match only reserved values or their digests and redact all real authorization material before logging. Generic secret scanners may never validate a product-specific token; detection depends on presentation to your API.
The edge adapter signs its event envelope with a server-held key. Verify tenant, timestamp, signature, and replay identifier at ingestion. If the collector fails, normal application behavior continues. A dropped-event counter makes collection gaps visible. A separate authenticated test endpoint exercises the entire pipeline without contaminating incidents.
Copied-site sensor
Compare the runtime’s exact location.origin with a configured allowlist. On mismatch, send only the placement ID, claimed origin, and coarse build metadata to an absolute HTTPS collector URL. Exclude full page URLs, query strings, form values, storage, and cookies. Use a no-referrer policy and credential-free transport.
Browser-origin claims remain forgeable through direct HTTP clients. Label them “reported origin” until independently confirmed. CSP, blocked egress, removed code, cached requests, disabled JavaScript, or a fresh implementation can defeat the sensor. Fetch/sendBeacon must satisfy connect-src; image transport must satisfy img-src. MDN: CSP connect-src MDN: Referrer-Policy
Thinkst’s CSS variant works without JavaScript by fetching an image and checking the Referer domain. That creates baseline requests from legitimate visits and loses attribution when referrers are absent. It is an optional adapter for constrained hosted pages, rather than the default transport. Thinkst: CSS cloned-site token
Packaged apps and mobile
Share decoy issuance, evidence, and alert delivery across platforms. Keep the web origin sensor separate: Electron file/custom-protocol origins need an app-specific policy, otherwise legitimate packaged execution can trigger it. For Electron, add fuses and ASAR validation as hardening where the app supports them: inspection flags can be disabled at packaging time, but the fuses do not detect every debugger or stop offline inspection. Electron: package-time fuses
On mobile, integrate Apple App Attest and Google Play Integrity as separate sources of app/request integrity evidence. Validate attestation and request binding on the server, with the platform’s challenge or replay protections. A failed or unavailable verdict is a risk signal with a reason, not proof that REA ran. Check platform and distribution support at integration time. Client-only checks can be falsified; legitimate-device relays remain a concern. Apple: App Attest server validation Apple: establishing app integrity and limitations Google: Play Integrity overview
Optional anti-debugging and instrumentation checks are platform-specific runtime defenses. They should enrich evidence and require their own compatibility testing; they cannot observe a binary while it is being disassembled elsewhere. OWASP: anti-dynamic analysis
Collection and product operations
A small first deployment can use customer-edge middleware, an HTTPS ingestion service, a durable queue, PostgreSQL for manifests/incidents, and a delivery worker. Add authoritative DNS callbacks later if demonstrated use cases justify operating DNS. DNS caching means repeated resolution need not produce a fresh callback.
Map tenants from registered tokens, not caller-supplied tenant IDs. Enforce tenant isolation, quotas, payload caps, deduplication, bounded retention, and auditable suppression rules. Keep the collector domain registered for as long as supported artifacts can call it; retiring an app version must not leave a dangling callback destination.
Deliver email, Slack, or generic HMAC-signed webhooks with retries and delivery receipts. Preserve event counts when suppressing notification storms. Do not automatically fetch arbitrary origin or URL fields from a beacon: any deployment verification worker needs isolation, public-address checks, redirect checks, and strict limits. Treat webhook destinations as controlled outbound integrations too.
Proposed event contract
{
"event_id": "server-generated",
"tenant_id": "resolved-from-placement",
"project_id": "product-a",
"placement_id": "release-web-support-route",
"build_id": "immutable-release-id",
"event_type": "decoy_endpoint_requested",
"observed_at": "collector-time",
"evidence_channel": "signed-customer-edge",
"http_method": "GET",
"response_status": 404,
"source_ip": "trusted-edge-observation",
"session_ref": "optional-server-derived-pseudonym",
"claimed_origin": null,
"tool_attribution": "unknown",
"intent_assessment": "requires-review"
}Unsigned browser events use a different evidence channel. Source IP headers are trusted only from the configured reverse proxy. No raw credentials or arbitrary request bodies belong in the contract.
Build the integration layer; reuse proven mechanisms
| Option | Useful existing capability | Fit for this problem |
|---|---|---|
| Thinkst Canarytokens | HTTP, DNS, AWS, JS/CSS clone detection, and MCP config traps. Thinkst: HTTP Canarytokens Thinkst: JavaScript cloned-site token Thinkst: MCP configuration token | Fast way to establish a baseline. MCP traps alert on client connection/tool use, not passive analysis of a website. |
| GitGuardian Honeytoken | Managed decoy credentials, placement tracking, event context, alert webhooks. GitGuardian: honeytoken concepts and placement GitGuardian: alert webhooks | Useful for private code and credential-use detection. Does not cover arbitrary static reading. |
| Cloudflare Bot Management | Automation likelihood from request/browser signals. Cloudflare: what bot scores measure | Enrich online events and control scraping. Does not identify REA or offline work. |
| Jscrambler Code Integrity | JavaScript anti-debugging and related runtime protections. Jscrambler: anti-debugging feature | Evaluate if raising runtime analysis cost is a separate requirement. Vendor claims are not a coverage guarantee. |
| Platform attestation | App/request integrity evidence. Apple: App Attest server validation Google: Play Integrity overview | Use official platform mechanisms for supported mobile/native requests; combine with canaries. |
The basic token idea already exists. The product opportunity is automated placement in shipped artifacts, build/channel provenance, customer-edge collection, and useful incident evidence across web and apps. That is a product hypothesis to validate with users, not a demonstrated market advantage.
Thinkst’s repository supports self-hosting, but its license contains additional terms and offers proprietary integration licensing. Its README also says AWS key allocation infrastructure has moved to a private repository; deploying the public server alone does not provide that backend. Resolve exact reuse terms before embedding its implementation in a commercial product. An independently implemented HTTP/API collector is the simplest starting architecture here. Canarytokens: exact license terms Canarytokens: hosting, throttling, AWS infrastructure
Managed credential tokens introduce vendor-specific behavior: Thinkst documents AWS alert delays of 2–30 minutes; GitGuardian documents pausing reception at 100 open events per token. Those details matter for public artifacts, where scanners or deliberate replay can create noise. A provider adapter must expose latency, throttling, and collection gaps. Thinkst: AWS key token and alert delay GitGuardian: trigger mechanism and event limits
Proposed alert policy
| Observed evidence | Initial treatment |
|---|---|
| Map request or one public decoy URL hit | Record as reconnaissance evidence; low-priority notification or digest until baseline is known. |
| Reserved credential presented to your API | Prompt notification: a planted credential was used. Still review known scanners, tests, and public exposure. |
| Two distinct decoy types in one trustworthy server-derived session | Raise investigation priority. Two tokens with the same IP alone are insufficient. |
| Clone-origin claim | Record the claim. Raise priority after controlled confirmation or other independent evidence. |
| Attestation/runtime integrity failure | Report reason and platform context; apply the application’s existing risk policy. |
Do not automatically ban accounts for a canary hit during the pilot. Tag authorized tests and scanners while retaining events. Do not classify a request as malicious merely because it comes from REA. A useful alert says which artifact and trap were involved, exactly what happened, what remains unknown, and how to investigate.
Product A · desktop stable release · support-config placement. A reserved credential was presented to /api/v1/whoami; the API returned 401. Source network and time recorded. Tool and intent unknown. Linked events: source-map request from the same authenticated server context, if available.
Rollout sequence
- Mechanism pilot: one web build and one Electron package; endpoint and credential sensors, optional clone beacon, placement inventory, event timeline, and one alert destination. Validate with controlled REA workflows and another tool to test tool independence.
- Observation period: include ordinary users, internal QA, accessibility tools, monitoring, search/security crawlers, deployment previews, and authorized security testers. Classify noise before deciding notification severity.
- Productization: tenant boundaries, reliable delivery, lifecycle/rotation, customer domains, supported build adapters, auditability, collector health, and customer-visible coverage limits.
- Native expansion: signed desktop packaging and mobile attestation adapters; separate platform compatibility and evasion test suites. DNS, CSS, and MCP-config traps are optional additional channels.
Effort estimate: approximately 5–10 engineering days for a narrow web/Electron pilot with an existing deployment and alert stack; production multitenancy and native/mobile adapters are additional work. This is an initial planning estimate, not a delivery commitment.
Acceptance criteria
- Every planted token maps to an exact deployed placement and build; genuine user journeys never invoke decoys.
- Each controlled endpoint/credential interaction yields a retained event; credentials grant no access and response bodies contain no real data.
- Measure legitimate-traffic alerts per 10,000 sessions, precision of reviewed alerts, delivery latency, collection loss, and placement coverage. Do not report recall for all reverse engineering: the unseen denominator is unknowable.
- A reasonable pilot target is delivery within 60 seconds for our own HTTP/API events; measure it. Managed cloud-key timing has different constraints.
- Regression tests preserve the blind spots: static/offline analysis, stripped sensors, blocked egress, and beacon replay. The UI must explain these results truthfully.
- Collector outage, webhook failure, expired builds, and alert floods remain observable and do not break the protected product.
What was actually tested
A disposable local fixture ran on two distinct loopback ports. The connected REA MCP analyzer read its JavaScript and package manifest. T3’s collaborative Chromium browser loaded the original and copied pages. Python made the four explicit HTTP requests. All callbacks stayed on 127.0.0.1.
| Case | Observed result | Interpretation |
|---|---|---|
| REA static analysis | 0 fixture HTTP requests | Endpoint recovered; external source-map reference recorded but not fetched. |
| Normal browser load | 0 trap events | Application loaded; HTML and JS were requested. |
| Copied site on a second origin | +1 event | Origin mismatch caused an image beacon; no Referer or Origin header arrived. |
| Copied site with restrictive CSP | +0 events | Browser reported the image blocked by img-src; application still loaded. |
| Copied site with beacon removed | +0 events | Application still loaded; no callback. |
| Explicit source-map GET | +1 event · HTTP 200 | Manual HTTP retrieval was recorded; this was not a live REA map-fetch test. |
| Decoy endpoint GET | +1 event · HTTP 404 | Request recorded and harmless failure returned. |
| Reserved credential presented | +1 event · HTTP 401 | Credential use recorded without access. |
| Forged clone-origin beacon | +1 event · HTTP 200 | A direct HTTP client fabricated the origin claim; beacon alone cannot prove a clone. |
Five total trap events were recorded across these nine cases. Zero-event cases demonstrate limits; they are not missed test executions. This small fixture establishes mechanisms and straightforward evasions, not real-world sensitivity or a false-positive rate.
Evidence identity and reproduction
REA evidence ID:
ev_54bf1dbd0179f82b76b1108a8af84c68dc40e223da544cccd5ea236e13af6af2
Analyzed artifact SHA-256:
086b90fb2d418fade461d6246a61be66c90aacda42376d547e81f6188ee17509
Provider: rea-javascript-application, provider version 1, as returned by the connected tool. This is not a claim about an npm package release number.
Retained files include lab.py, fixture/app.js, rea-static-evidence.json, events.jsonl, requests.jsonl, browser snapshots/checkpoints, and validation.json. Starting python3 lab.py allocates new loopback ports and regenerates disposable decoys; archive the existing evidence before rerunning because the lab resets its logs.
Static reproduction: analyze the generated fixture/ with REA’s analyze_javascript_application operation, then inspect the lab request logs before visiting any page. For browser reproduction, visit the emitted site and clone origins, then the clone’s /blocked and /stripped routes.
Unverified work
Live REA CDP capture and its optional source-map fetch, packaged Electron/ASAR execution, native binaries, mobile SDKs, attestation, DNS infrastructure, external email/webhook delivery, load testing, and production traffic were not tested. Vendor features were researched in primary documentation, not exercised in paid accounts.
Repository tests: none; the current REA directory is a research workspace rather than a Git checkout. CI: not run. Deployment: none. Witnessed browser behavior: the four page-load cases above. Existing project files, branches, and services were not changed.
Primary sources
Accessed 18 October 2026. Product and repository documentation can change; the local evidence files retain the experiment’s exact result. Interpretations and proposed architecture are identified in the report.
- REA: JavaScript artifact reconstruction
- REA: browser observation and source-map fetch policy
- REA: passive Node and Electron runtime observation
- Thinkst: HTTP Canarytokens
- Thinkst: DNS Canarytokens
- Thinkst: JavaScript cloned-site token
- Thinkst: CSS cloned-site token
- Thinkst: AWS key token and alert delay
- Thinkst: MCP configuration token
- Canarytokens: hosting, throttling, AWS infrastructure
- Canarytokens: exact license terms
- GitGuardian: honeytoken concepts and placement
- GitGuardian: trigger mechanism and event limits
- GitGuardian: alert webhooks
- Chrome: source maps in DevTools
- MDN: navigator.webdriver
- MDN: CSP connect-src
- MDN: Referrer-Policy
- Electron: package-time fuses
- Apple: App Attest server validation
- Apple: establishing app integrity and limitations
- Google: Play Integrity overview
- OWASP: anti-dynamic analysis
- Cloudflare: what bot scores measure
- Jscrambler: anti-debugging feature