Is CSFloat Market Checker safe?
CSFloat is high risk. CSFloat Market Checker sends every visited Steam profile's SteamID64 to reverse.watch, a third party apart from CSFloat, no consent or disclosure. It reads the ID from page globals or the URL and fires a GET, e.g. /v1/users/{steamid64}.…
Who publishes itCSFloat Inc. - no other listings under this identity, 7 shared hostnames
CSFloat Inc. - no other listings under this identity, 7 shared hostnames
What this publisher told the store about itself, and the other listings that told it the same thing.
Shared hosts - 7 hostnames
Hostnames hardcoded in this extension that few other listings call. That can mean one operator behind both, and it can equally mean a small shared vendor, so it is context rather than a conclusion. Hosts that many listings call are left out: they are services, not connections.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Steam Profile IDs Sent to reverse.watch on Every Profile Visit
CSFloat Market Checker sends every visited Steam profile's SteamID64 to reverse.watch, a third party apart from CSFloat, no consent or disclosure.
It reads the ID from page globals or the URL and fires a GET, e.g. /v1/users/{steamid64}.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-359
- Source
- Dynamic sandbox
You open any Steam user profile page while CSFloat Market Checker is active.
The extension reads the SteamID64 from the page and sends it to reverse.watch without prompting you.
The request fires on every profile load, for every Steam account you view, whether or not that account has any reversal history.
- Viewed account's Steam ID76561197968052866
A numeric ID that uniquely identifies the Steam account viewed. Sent to reverse.watch in the URL, letting it log lookups by session.
No response body captured, the reverse.watch host was unreachable from the sandboxed analysis network. The disclosure itself does not depend on server reachability: the outbound URL was already fully formed and dispatched from the extension with the viewed profile's SteamID64 embedded in the path, so the identifier had already left the browser before any response could arrive.
ReversalStatus component fires on every Steam profile page load
Readable equivalent — getSteamId() and connectedCallback()
src/lib/page_scripts/profile.js (deobfuscated)getSteamId() { if (defined(typeof g_rgProfileData) && g_rgProfileData) { return g_rgProfileData.steamid; } const match = window.location.pathname.match(/^\/profiles\/(\d+)/); if (match) { return match[1]; }}async connectedCallback() { super.connectedCallback(); try { const steamId = this.getSteamId(); if (!steamId) { console.error('failed to get steam id'); return; } this.reversalStatus = await gReversalFetcher.fetch({ steam_id64: steamId }); } catch (e) { console.error('failed to fetch reversal status', e); }}Readable equivalent — background bridge handler
src/lib/page_scripts/profile.js (deobfuscated)const FetchReversalStatus = new SimpleHandler( RequestType.FETCH_REVERSAL_STATUS, async (req) => { const resp = await fetch(`${environment.reverse_watch_base_api_url}/v1/users/${req.steam_id64}`); const data = await resp.json(); if (!resp.ok) { throw Error(data.message ?? 'unknown error'); } return data; });- reverse.watch
Receives the SteamID64 of every profile visited. Operated separately from CSFloat; a 'powered by reverse.watch' attribution appears on a reversal. Not disclosed in the listing.
Steam Trade Offer Data Sent to csfloat.com Every 3 Minutes
The same 3-min alarm reading your Steam trade history also calls Valve's Trade Offers API for sent offers (IDs, asset IDs, state, counterparty ID64), forwarding matches to pending CSFloat trades, needing the steampowered.com permission.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-200
- Source
- Dynamic sandbox
You grant the extension's optional steampowered.com permission, offered during CSFloat trade-tracking setup, and have a Steam trade offer pending against a CSFloat listing.
No further action is needed after that; the alarm runs on its own schedule from then on.
Every 3 min, the same alarm pinging your trade history also reads sent Steam trade offers, forwarding matches' IDs, asset IDs, and the counterparty's Steam ID64 to csfloat.com.
This happens automatically in the background with no further prompt once the permission is granted.
Background alarm reads sent Steam trade offers via Valve's API, POSTs matches to CSFloat every 3min.
What a lower-footprint version would send
// Send an opaque, hashed reference to the pending CSFloat trade and// its settlement state, instead of the raw counterparty Steam ID64 and// asset IDs taken directly from Valve's Trade Offers API response.await TradeOfferStatus.handleRequest({ sent_offers: offersForCSFloat.map(minimalOfferReference), type,}, {});CSFloat's backend returned 200 OK, acknowledging receipt of the trade-offer payload.
- Content-Type
- application/json
{ "sent_offers": [ { "offer_id": "5127349018", "state": 2, "given_asset_ids": [ "20938471002" ], "received_asset_ids": [], "time_created": 1751998000, "time_updated": 1752000000, "other_steam_id64": "76561198083722517" } ], "type": 1}- Steam trade offer IDoffer_id: 5127349018
Valve's internal identifier for this specific trade offer.
- Item asset IDs given and receivedgiven_asset_ids: ["20938471002"]
Unique identifiers for the specific in-game items (skins) the offer moves.
- The counterparty's Steam ID64other_steam_id64: 76561198083722517
Identifies exactly who the other side of the trade offer is, tied to their Steam account.
- Offer statestate: 2 (active)
Whether the offer is active, accepted, declined, or expired.
Steam Web API Token Extracted From steamcommunity.com Page HTML
Each time the alarm runs, it fetches your steamcommunity.com homepage with your login cookies, then regexes your Steam Web API token and ID from the HTML, storing both locally.
Confirmed via a marker reused in a live steampowered.com call.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-200
- Source
- Dynamic sandbox
The extension's background alarm runs on its normal schedule, no page visit or click from you is required.
The same alarm that drives the trade-history and trade-offer pings also drives this token refresh.
It fetches your own steamcommunity.com homepage using your session cookies, regexes your Steam Web API token and Steam ID out of the HTML, and stores both locally.
The stored token is then reused directly in later calls to Valve's official Steam Web API.
Scrapes your Steam Web API token and Steam ID from steamcommunity.com HTML, then caches them.
What a documented alternative would look like
// Use Valve's officially supported Web API key issuance flow// (a user-generated key from steamcommunity.com/dev/apikey, entered// once by the user) instead of scraping an internal, undocumented// HTML attribute that Valve can change or remove without notice.The extension's cached Steam Web API credential, read back and reused for 30 minutes before it re-fetches steamcommunity.com to refresh it.
- Location
- chrome.storage.local key 'access_token'
{ "token": "<redacted>", "steam_id": "76561198012345678", "updated_at": 1752000000000}Valve's API accepted the request shape; with a real Steam session's token this returns the caller's live CS2/CS:GO inventory.
+2 more findings not shown