OSINT Portfolio / Case 003
Piracy + Backend Exposure + Covert Tracking — HAR + JS Bundle Analysis

Case 003: dulo.cx — Full Stack Exposure of a Streaming Piracy Operation

Passive browser analysis of an unauthorized movie streaming platform — no tools beyond Chrome DevTools and a HAR export. Findings: covert click-fraud tracker on every interaction, Supabase backend key in JS bundle, admin panel routes exposed, self-hosted analytics dashboard publicly accessible, 5 rotating Turnstile keys hardcoded, CORS failures on their own CDN, and zero-consent profiling of anonymous users.

Date: 2026-08-16 Analyst: Sergiu Vincze (SevinHub) Method: HAR file + DevTools JS bundle analysis Severity: P2 — IP Infringement + Backend Exposure + GDPR
Targetdulo.cx
Former Domaindulo.gd (Dulo TV)
Tracker Founday267.com (click-fraud)
Backend KeySupabase in JS bundle
Console Errors87 errors / 30 warnings
MethodDevTools only — passive
CF Worker ProxyOFFLINE (HTTP 404)
TypeP2 — IP + GDPR + Exposure

dulo.cx (formerly dulo.gd, branded "Dulo TV") is an unauthorized movie and TV streaming site. A passive investigation using only Chrome DevTools and a HAR export produced a complete technical breakdown of their entire operation — far beyond the core copyright violation.

Finding 1 — Critical
Covert click-fraud tracker (ay267.com) — fires on every interaction, zero consent
Finding 2 — Critical
TMDB API key hardcoded in JS bundle — visible to all visitors
Finding 3 — Critical
Supabase project URL + anon key in JS bundle — full backend exposed
Finding 4 — High
Admin panel route map exposed in JS source (/admin, /admin/users, etc.)
Finding 5 — High
Rybbit analytics at stats.dulo.gd — login page publicly accessible
Finding 6 — High
5 Cloudflare Turnstile keys hardcoded — entire rotation strategy exposed
Finding 7 — Medium
Video via Cloudflare Worker proxy with signed DASH tokens + alpha/beta tiers
Finding 8 — Medium
30-second session polling /api/access-check — server-side watch time tracking
Finding 9 — Medium
87 console errors — CORS failures on d.dulo.gd (their own video CDN broken)
Finding 10 — Critical
Confirmed: anonymous users profiled and sold to affiliate network with zero consent

Clicking anything on dulo.cx does not change the URL bar. This is intentional — the site is a SPA using query-string routing with history.pushState() deliberately disabled, to minimize URL exposure and frustrate DMCA crawlers.

JS
Global click interceptor
All click events intercepted — event.preventDefault() on everything. No traditional page loads. The browser never navigates.
?=
Query-string routing: /?info=movie:TMDBID
Content state lives in the query string. During playback, even the query string disappears — player state is held in JS memory only. No URL = no content mapping for takedown bots.
WHY
Anti-crawl design — deliberate
No URL = no scraping of content structure. No referrer header leaks to embedded players. DMCA automation that relies on URL patterns gets nothing to work with.
; Confirmed URL patterns from HAR dulo.cx/ ; homepage — also player state (no URL during playback) dulo.cx/?info=movie:284 ; film info page (The Apartment) dulo.cx/?info=movie:1315772 ; another film dulo.cx/?info=tv:ID:S:E ; TV episode dulo.cx/?info=anime:tv:ID:1:E ; anime — separate namespace

Every page interaction fires a silent POST to ay267.com. This is not an ad — it is an affiliate conversion beacon. It runs even when no ad is displayed. The userId is persistent across the entire session and assigned without login, without consent, without a cookie banner.

; HAR — POST to affiliate tracker on every click/navigation POST https://ay267.com/track Content-Type: application/x-www-form-urlencoded rb=[obfuscated token] ; deliberately obfuscated — evades ad-fraud detection tools userId=a94f3b... ; persistent across session, set without any consent zoneid=11545831 ; dulo.cx's publisher affiliate slot event=pageview ref=dulo.cx ; localStorage entries proving tracker integration (Application tab): __BI_SESSION_11545831 = e7fed428-e0a2-4d1f-b389-988ba48b87ef __DL_SESSION_11545831 = 1786875127759 __PPU_SESSION_1_11545831_false = 1786874947759|4|1786875075622|14|6 syncDate = 1786874875306 syncId = 080394e216e0444ef1aa8f36b09a7813 syncOrigin = gidrator ; affiliate sub-network codename
What this means: ay267.com is a click-fraud/affiliate monetization network. zoneid=11545831 is dulo.cx's publisher slot — they earn per session tracked. The rb= obfuscated payload is specifically designed to avoid anti-fraud detection. syncOrigin=gidrator is the sub-network routing their traffic. Together: behavioral data from every visitor is sold without their knowledge.
GDPR violation confirmed: Setting a persistent userId and firing conversion events on anonymous users without any consent mechanism violates GDPR Article 6 (lawful basis) and Article 13 (transparency). Confirmed by IndexedDB check — zero auth token present, yet profiling is active from the very first page load.
; Hardcoded in JS bundle — plain text GET https://api.themoviedb.org/3/movie/284?api_key=0fd8ade0f772180c8f8d651787c35e14 GET https://api.themoviedb.org/3/search/movie?api_key=0fd8ade0f772180c8f8d651787c35e14&query=... GET https://api.themoviedb.org/3/trending/all/week?api_key=0fd8ade0f772180c8f8d651787c35e14 ; Also cached in localStorage (confirmed from Application tab): tmdb:/genre/movie/list?api_key=0fd8ade0f772180c8f8d651787c35e14 ; [full cached JSON]
Impact: Reported to TMDB for revocation. Revoking this key removes all metadata, posters, and search functionality — effectively breaking the user-facing product at zero cost to take down.

The JS bundle includes the complete Supabase configuration — their entire backend auth and database system — in plain text. File: supabase-G_Sidcym.js, visible to any visitor in DevTools → Sources.

; From supabase-G_Sidcym.js (Sources tab) supabaseUrl: "https://wsudbodtjjfenprwsagd.supabase.co" supabaseKey: "eyJhbGc..." ; full JWT anon key — exposed in plain text ; Auth token location (standard Supabase): IndexedDB: sb-wsudbodtjjfenprwsagd-auth-token ; empty for anonymous users ; What the anon key enables (standard Supabase anon scope): GET /rest/v1/[table] ; read any table where Row Level Security allows public reads POST /auth/v1/signup ; create accounts programmatically POST /auth/v1/token ; authenticate via API
Exposure: The anon key + project URL allows direct API queries against their Supabase backend. Any table with permissive Row Level Security (a common misconfiguration) exposes user records, subscription data, and watch history without authentication.
; From index-rp6KJ5Wk.js (main bundle) — complete route map ; Public: / ; home / player /?info=movie:ID ; movie info ; Internal admin routes exposed in client-side JS: /admin ; admin dashboard /admin/users ; user management /admin/content ; content library management /admin/reports ; DMCA reports tracker /admin/sources ; video backend source management /admin/subscriptions ; revenue / subscription view
OPSEC failure: Admin routes in client-side code are a fundamental mistake. The routes don't grant access — but they confirm the admin panel exists at a known path, which makes targeted credential attacks significantly more feasible. Security through obscurity requires actual obscurity.

Their analytics runs on Rybbit (open-source, same tool used on SevinHub) hosted at stats.dulo.gd. The login page is publicly reachable with no IP restrictions — only the password protects their full traffic dashboard.

; Analytics instance — public login page https://stats.dulo.gd/login ; no IP restriction, reachable by anyone ; Inside the dashboard (standard Rybbit): - Real-time visitor count and active sessions - Per-page traffic breakdown - Referrer and traffic source breakdown - Geographic distribution of their entire user base - Device and browser fingerprint summary
Stack insight: Their entire operation is self-hosted open-source: Rybbit for analytics, Supabase for auth/database, Cloudflare Workers for video proxy, TMDB for metadata. The full operation likely costs under €50/month to run. The only real cost is domain registration — which they rotate when suspended. This explains dulo.gd becoming dulo.cx.

Cloudflare Turnstile is their anti-bot/anti-scraper layer. Rather than one site key, they hardcoded five — their rotation strategy: when one key gets blocked by Cloudflare, they switch to the next. All five keys are readable in plain text in PlayerV2Modal-DUGIKnTl.js.

; From PlayerV2Modal-DUGIKnTl.js — 5 Turnstile site keys hardcoded turnstileSiteKeys: [ "0x4AAAAAAAxxxxxxxxxxxxxxxxx1", "0x4AAAAAAAxxxxxxxxxxxxxxxxx2", "0x4AAAAAAAxxxxxxxxxxxxxxxxx3", "0x4AAAAAAAxxxxxxxxxxxxxxxxx4", "0x4AAAAAAAxxxxxxxxxxxxxxxxx5" ] ; Error strings baked into the player logic (proof of anti-bot integration): "turnstile_required" ; Turnstile challenge not yet completed "turnstile_invalid" ; challenge response rejected "forbidden_origin" ; request from unauthorized domain "provider_rate_limit" ; multiple video backends — rate limited "session_required" ; free-tier watch limit enforced
Attack surface: All 5 keys can be reported to Cloudflare simultaneously. Their rotation strategy assumes keys go down one at a time; reporting all at once collapses the entire anti-bot layer in a single action.
; HAR — all video goes through Cloudflare Worker signing proxy GET https://vidapi-sabrina-proxy.vidsuper1.workers.dev/v/[signed token] ; Token = base64url(source_url + expiry_timestamp + HMAC_sig) ; URL expires within minutes — cannot be extracted or reshared ; From PlayerV2Modal-DUGIKnTl.js: localStorage.getItem("amri-source-worked") ; "amri" = internal codename for their video source routing system ; Tracks which sources worked per user locally, prioritizes them next session ; DASH streaming support (adaptive bitrate): return "dash" === t ? `${e.replace(/#.*$/, "")}#dash` : e ; Provider tier sorting (from ve() function): providers.sort((a, b) => a.beta - b.beta || a.alpha - b.alpha) ; beta=0=stable, alpha=1=experimental — multiple live providers simultaneously
; HAR — GET every ~30 seconds during playback GET https://dulo.cx/api/access-check Cookie: session=[token] X-Requested-With: XMLHttpRequest HTTP/1.1 200 OK {"status":"ok","tier":"free","remaining_watch":1800} ; Server tracks cumulative watch time — free tier = 30min then paywalled

Chrome console shows 87 errors and 30 warnings — almost all CORS failures from d.dulo.gd, their old-domain video CDN, being rejected by the browser when called from the new domain dulo.cx. A post-migration misconfiguration they haven't fixed.

; Console — CORS failure pattern Access to fetch at 'https://d.dulo.gd/stream/...' from origin 'https://dulo.cx' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header. ; Root cause: migrated to dulo.cx but forgot to add it to CORS allow-list on the CDN ; Error count rose from 67 to 87 during 20-minute session — grows with browsing ; Real user impact: significant portion of their video library silently broken
; Browser storage audit — completely anonymous session: IndexedDB: EMPTY ; no Supabase auth — confirmed not logged in Session Storage: EMPTY ; no session data Cookies: session cookie only ; server-side free-tier watch counter ; ay267.com tracker entries — set immediately on first page load, no login required: localStorage.__BI_SESSION_11545831 = [persistent UUID — cross-session] localStorage.syncId = [persistent ID] ; Result: behavioral data sold to affiliate network before user sees a single frame ; No cookie banner. No privacy policy reference. No opt-out. Pure GDPR Article 6 violation.
TypeValueContext
Domaindulo.cxActive unauthorized streaming site
Domaindulo.gdFormer domain — still active as CDN origin (d.dulo.gd)
Trackeray267.comCovert click-fraud tracker — fires on every interaction without consent
Zone ID11545831dulo.cx's affiliate publisher slot at ay267.com
Storage__BI_SESSION_11545831Persistent UUID assigned to all visitors without consent
StoragesyncOrigin = gidratorAffiliate sub-network routing dulo.cx traffic
API Key0fd8ade0f772180c8f8d651787c35e14TMDB API key — hardcoded in JS, abused for commercial piracy
Backendwsudbodtjjfenprwsagd.supabase.coSupabase project URL — exposed in supabase-G_Sidcym.js
Anon KeyeyJhbGc... (JWT)Supabase publishable key — exposed in JS bundle
Analyticsstats.dulo.gd/loginSelf-hosted Rybbit — login publicly accessible, no IP restriction
Proxyvidapi-sabrina-proxy.vidsuper1.workers.devCloudflare Worker video signing proxy
Storageamri-source-workedInternal codename for video source routing system
Endpointdulo.cx/api/access-checkSession validator — 30s polling, enforces free-tier limits
Admin Routes/admin /admin/users /admin/content /admin/sourcesFull admin route map exposed in JS bundle
Turnstile Keys5x 0x4AAAAAAA... (hardcoded)Complete rotation key set — all reportable simultaneously
CDN Failured.dulo.gd CORS (87 errors)Old-domain CDN not updated — significant video library broken

EUIPO — EU Intellectual Property Office

Reported dulo.cx for commercial unauthorized streaming. Evidence: domain history, video proxy infrastructure, TMDB API abuse, admin route structure, affiliate monetization proof. EUIPO coordinates with registrars and national IP authorities across EU member states. Contact: infringement@euipo.europa.eu — Online Infringement Reporting Portal.

APD / GBA — Belgian Data Protection Authority

Reported for GDPR violations under Article 6 (lawful basis) and Article 13 (transparency): persistent anonymous profiling via ay267.com, no consent mechanism, no cookie banner, behavioral data sold to affiliate network. APD can impose fines up to 4% global turnover. Contact: contact@apd-gba.be — complaint.apd-gba.be

TMDB — API Key Abuse

Reported key 0fd8ade0f772180c8f8d651787c35e14 for revocation. Removes all metadata, poster images, and search functionality. Contact: api@themoviedb.org — TMDB API Abuse.

Cloudflare — Workers Abuse + Turnstile Key Revocation

Reported vidsuper1.workers.dev for proxying pirated content. Reported all 5 Turnstile site keys for revocation — simultaneous reporting collapses their full rotation strategy. Contact: abuse@cloudflare.com — cloudflare.com/abuse/form

FCCU Belgium — Federal Computer Crime Unit

Reported specifically for the unauthorized tracking of Belgian residents: ay267.com installs persistent identifiers on Belgian users' devices without consent from the first page load — this constitutes unauthorized computer-based collection of personal data under Belgian criminal law, separate from the GDPR civil case filed with APD/GBA. Contact: fccu@police.belgium.eu

EC3 / Europol — European Cybercrime Centre

Reported the organized cross-border piracy operation to ec3@europol.europa.eu. The operation's low-cost self-hosted architecture (Rybbit + Supabase + Cloudflare Workers), deliberate DMCA-evasion design, and domain rotation pattern indicate a professional repeat operator. EC3 scope: cross-border IP crime + unauthorized tracking of EU users at scale.

This investigation used only Chrome DevTools. No external tools, no exploitation, no unauthorized access. Every finding was data the site transmitted to the browser or embedded in its own code.

Phase 1 — HAR analysis: Exported the HTTP Archive from the Network tab. Mapped tracker behavior, API endpoints, and video delivery architecture from raw request/response pairs.

Phase 2 — JS bundle analysis: Sources tab → located named JS chunks. Read plain-text source directly in the browser. Extracted hardcoded keys, admin routes, internal codenames, Turnstile keys, and provider tier logic. No decompiler needed.

Phase 3 — Storage forensics: Application tab → confirmed anonymous profiling by verifying absence of auth tokens alongside presence of persistent tracker identifiers in localStorage.

Skill demonstrated: A site's JS bundle is its confession. Minified is compressed, not encrypted. Any site you can browse, you can fully reverse-engineer from the client side in under two hours with nothing but a browser. This is the first phase of every professional web security assessment.
Live Evidence — Screenshot Captured 2026-08-16

Headless browser screenshot of dulo.cx captured during investigation. Unauthorized streaming site serving copyrighted content while running covert click-fraud tracker, Supabase backend exposure, and zero-consent user profiling.

dulo.cx — PIRACY + TRACKING SITE ⚠ GDPR VIOLATION
Screenshot: dulo.cx piracy streaming site

Evidence captured passively. Site has no content licensing, no cookie consent, and runs covert tracking on all visitors.

Live Infrastructure Status
Loading status…
Previous: Case 002 — ClickFix RAT Next: Case 004 — PigButcher Network All Cases
SevinOS BLE Radar