Afina

Download app

AppleWindows
EN

WebSocket and local ports: how antifraud detects environment signals

WebSocket timing attack and local antifraud ports

WebSocket local ports mean a channel through which a site can indirectly assess services on localhost by response timing. It is used to notice open debugging ports, local agents, proxy clients, or traces of automation.

For teams that work with several profiles, this topic sits next to checking WebRTC leaks and UDP behavior. The external IP and proxy may look tidy, but the browser still remains a process on the local machine. If a page sees indirect signs of that environment, the digital fingerprint becomes wider than Canvas, WebGL, and User-Agent.

That is why a WebSocket timing attack should be treated as part of browser fingerprinting. It does not read files, get a process list, or show the program name. But it can provide a signal: the port refused quickly, responded with a delay, or hung until timeout. Together with Canvas, WebGL, and video fingerprinting and behavioral metrics, this signal helps antifraud systems evaluate the session environment.

Port 9222 deserves separate attention because it is often associated with Chrome DevTools Protocol. If remote control through CDP is enabled in the browser and a site records an unusual timing difference on this port, it can become an additional environment signal. To understand related leaks, it is useful to keep the article on Puppeteer CDP leaks nearby, because both topics are about not the external IP, but how automation appears inside the browser environment.

Why a web page can contact a local address

A web page can create a WebSocket connection not only to a remote server, but also to an address such as 127.0.0.1 or localhost. This does not mean the site automatically reads local data. The point is the attempt to establish a connection and measure the time until a browser error event, which may indirectly depend on the network state of a local port.

WebSocket was created for persistent two-way communication: chats, exchange charts, live statuses, and browser games. At the start, the browser makes a TCP connection, sends an HTTP Upgrade, and waits to see whether the server agrees to switch to the WebSocket protocol. If the address is localhost, the traffic does not leave for the external network. It goes through the loopback interface of the same operating system.

The problem is that even a failed attempt gives side information. A page should not see the response from MySQL, SSH, or a local proxy. Under the normal security model, it does not see it. But JavaScript can record the time difference before the error event. This can be affected by a fast OS refusal, a TCP connection followed by a failed WebSocket Upgrade, or a longer timeout.

This is not classic port scanning in the style of nmap. A browser script has no raw access to TCP packets, does not see SYN/ACK directly, and does not receive a service banner. It works more roughly: it tries several ports, records the time until the onerror event, and compares the result with a baseline value.

For an antifraud system, local timing matters together with other signs. If a session simultaneously shows a suspicious User-Agent, unusual WebGL renderer, unstable IP, and timing similar to an open CDP port, the combined signals can affect the risk score.

How response time helps estimate port state

A WebSocket timing attack relies on statistical differences in error timing, which under certain conditions can correspond to a closed, open, or firewall-filtered port. The site does not read the local service, and timing does not provide guaranteed port-state classification.

A typical scenario is simple. A script takes a high-precision timer, launches new WebSocket("ws://127.0.0.1:9222"), waits for an error, and calculates the difference. Then it repeats the attempt for several ports and compares them with a control port that is almost certainly closed.

A conditional check algorithm looks like this:

  1. choose a high control port that is not used by local services
  2. measure the average error time for this control port
  3. try WebSocket connections to ports that make sense for the risk model
  4. compare each port's delay with the baseline
  5. discard single outliers that may appear because of CPU load or garbage collection
  6. send not a raw conclusion, but a scoring signal with a confidence level

The numbers should not be read as a universal law. On localhost, a closed port often gives a very fast refusal, an open port may respond noticeably longer because of the TCP handshake and failed WebSocket Upgrade, and a filtered port may wait until a system timeout. But exact milliseconds depend on the OS, browser, CPU load, timer policies, and what exactly listens on the port.

Port stateWhat happens at TCP levelWhat the script seesWhy antifraud can use it
closedOS quickly returns RSTshort delay before onerrorbaseline for normal refusal
openhandshake succeeds, but WebSocket Upgrade failslonger delay before errorpossible local service or agent
filteredfirewall may drop the packet without a fast responsepossible longer delay or timeoutpossible filtering or unusual rule signal
unstableresult varies between attemptsnoisy measurementslow-confidence signal

After this table, it is easy to make the wrong conclusion: if the port is open, the user is guilty. In reality, no. Local ports are opened by legitimate programs: IDEs, Docker, VPN clients, password managers, crypto wallets, and corporate security agents. A technical signal becomes an antifraud risk only in the context of the whole session.

WebSocket timing routes for local port states

Antifraud models may not rely on one trigger threshold. They calibrate time on the current machine, repeat attempts, look at value spread, and compare local signs with the browser fingerprint. This is where assessment begins, not direct proof.

What browsers and operating systems restrict

Browsers restrict a web page's access to local resources through several different mechanisms. Same-Origin Policy and CORS primarily regulate access to responses from ordinary web requests, Secure Context defines availability of some capabilities, and Private Network Access adds checks for requests to private networks. These mechanisms should not be treated as the same protection from WebSocket timing: under certain conditions, the time before a browser error event may remain a side channel.

This boundary matters. If a site tries to read the response from a local HTTP server through fetch, the browser should block access to the response body without the required CORS headers. WebSocket works differently: the server may check Origin. But the fact of a successful or failed path to an error still appears.

The operating system also does not always remove this side channel. Loopback traffic does not leave the device, and firewall behavior toward it depends on the OS and configuration. DROP and REJECT rules can also create different timing characteristics.

When you configure protection, the difference between these actions is practical:

  • REJECT usually returns a refusal quickly, but the exact timing depends on the OS, firewall, and network configuration
  • DROP can discard a packet without a fast response and cause a longer timeout
  • completely blocking localhost can break legitimate local agents
  • an allowlist of services reduces noise, but needs maintenance
  • a separate profile environment better isolates local services from the browser session

If you have several work roles on one machine, do not open everything in one regular browser and hope that a proxy solves local leaks. A proxy changes the external route, but it does not remove the local Docker daemon, CDP endpoint, or corporate agent that listens on a loopback port.

Private Network Access partly closes classic scenarios where public sites access private network resources. But PNA is not a universal answer to a timing side channel. If the browser has to try a connection and then reject it by policy, the time difference itself may remain useful for scoring.

Browser and system WebSocket protection layers

For practical security, this means one thing: do not rely on one layer. Browser policy reduces access to data, the firewall controls the OS reaction, and environment isolation removes unnecessary local services from the field of view of a work session.

How these signals can enter antifraud

Antifraud can use local WebSocket timings as one of the environment signals. Specific use depends on the platform, its risk model, and rules.

A local port signal can potentially be useful in three situations:

  1. the system checks for automation signs through CDP, Playwright, Puppeteer, or Selenium
  2. it evaluates an unusual server environment where databases, SSH, control panels, or local proxies are open on localhost
  3. it compares supposedly independent profiles by a repeated set of local signs

Here, WebSocket timing attack intersects with headless browser detection. Headless mode may have visible signs in WebDriver, canvas parameters, or API behavior. A local port adds another layer: not how the browser draws a page, but what runs next to the browser on the machine.

A conditional example of how this signal could theoretically look in a scoring system:

SignalLow riskHigher riskComment
9222 or another CDP portport is closed or unavailabletheoretical model shows a delay similar to an open endpointneeds comparison with other automation signals
local proxy portsmay be expected in a corporate scenariotheoretical model repeats them across many accountscan potentially be one clustering signal
SSH or database portsmay be unusual for a normal consumer environmenttheoretical model repeats them between sessionscan indicate a server or work environment
filtered timingsisolated and unstablesystematic across many portsmay reveal an aggressive firewall rule
identical local port setrandom coincidencerepeats across dozens of profilespossible signal for cluster analysis

If several profiles with different IPs, cookies, and fingerprints have the same set of local ports, a risk scoring system may potentially treat the repeating pattern as a sign of shared infrastructure.

It is important to consider not only the browser, but also the network route. If profiles work through different proxies, but all of them run on one machine with the same local services, the proxy does not separate this layer. For QUIC, UDP, and SOCKS5, this is a separate topic that should be compared with the article on UDP through SOCKS5 and QUIC routing.

WebSocket timing signal in antifraud scoring

We are not claiming that every platform performs local port scanning. This mechanism is technically possible and can be tested in a controlled environment, so it is worth including in the security checklist for teams that work with sensitive accounts.

How to check the local environment and reduce data leakage

Checking the local environment starts with port inventory, not with randomly installing extensions. First you need to understand what exactly listens on localhost, which services are needed for work, and which ones can create an unusual pattern for a browser session.

On macOS and Linux, lsof -iTCP -sTCP:LISTEN -n -P or ss -ltnp gives a basic picture. On Windows, you can start with netstat -ano and match the PID with processes in Task Manager or PowerShell. Then the list should not just be saved, but divided into normal, service, and risky ports.

The practical audit order is:

  1. check the list of listening ports before starting the work browser
  2. close IDEs, local servers, Docker containers, and debug sessions if they are not needed for the task
  3. make sure the CDP port is not exposed without a real need
  4. limit access to unnecessary local services with a firewall and leave only connections required for work available
  5. test the same profile in a regular browser and in an isolated environment
  6. repeat measurements several times to separate a stable signal from noise
  7. document which local agents are allowed in the team SOP

In workflows with many accounts, the same logic turns into cluster risk. One profile with an open local port may be a coincidence. Fifty profiles with the same set of local ports may indicate shared infrastructure. This is where it is relevant to mention Sybil detection and cluster analysis, because risk scoring systems may consider not one isolated signal, but a repeating structure of signs.

What to do in practice if you manage team infrastructure:

  • separate work roles by different profiles and environments
  • do not run automation debugging in the same environment where you log in to important accounts
  • use an allowlist of local agents that are truly needed
  • distinguish blocking from fast refusal, because these are different signals for timing
  • record changes in the SOP so the team does not open random ports before a work shift
  • check not only IP and fingerprint, but also the local network contour

Afina is useful in this process as infrastructure for isolated browser profiles, fingerprint parameter management, proxies, and team access. Profile isolation lets teams separate cookies, sessions, proxy settings, and work roles, but it does not replace an audit of the local OS, firewall, and services on localhost. This material is provided for informational and educational purposes only.

For a team SOP, it is convenient to keep a separate checklist: which local services are allowed, which ports must not be open before launching a profile, who is responsible for updating firewall rules, and where test results are stored. This documentation helps track environment changes and analyze the reasons for additional risk checks on individual profiles.

Download

FAQ — Frequently Asked Questions

What is a WebSocket timing attack?

A WebSocket timing attack allows estimating the state of a local port by the error time during a connection attempt. The script does not read local data, but compares delays between closed, open, and filtered ports.

Can a site scan localhost through a browser?

A site can try to contact localhost through browser APIs, including WebSocket. The browser restricts access to the response, but the error timing itself may remain a side signal.

Why is port 9222 considered risky?

Port 9222 is often associated with Chrome DevTools Protocol and browser automation control. An open port alone does not prove abuse, but in antifraud scoring it can strengthen other automation signals.

Does CORS protect against WebSocket port scanning?

CORS restricts reading responses in regular web requests, but it does not remove all timing side channels. For WebSocket, the TCP handshake, Upgrade error, and time until onerror also matter.

Does Private Network Access solve the local port problem?

Private Network Access adds restrictions for some requests from public sites to private network resources. Its behavior depends on the browser, request type, and current implementation, so PNA should not be treated as universal protection from all timing side channels.

How do you check open local ports?

On macOS and Linux, use lsof or ss; on Windows, start with netstat -ano. Then match ports with processes and close services that are not needed for the work session.

Is a proxy enough to protect from localhost signals?

No, a proxy changes the external network route, but it does not remove local services on the machine. For localhost signals, environment isolation, firewall rules, and debug-port control matter.

Can you fully block browser access to localhost?

The ability to fully restrict access depends on the browser, operating system, and network policy. Strict blocking can break legitimate local agents, so in a managed environment it is better to define allowed services and rules for unwanted connections separately.

Related terms

Continue reading onAnti-detect browser — profile isolation | Afina Browser
Kirill Kucheniev Polodiyenko

Hi! I’m Kirill Kucheniiev-Polodiienko — Technical Product Manager (Automation) on the Afina team.