I was browsing the JetBrains plugin marketplace when I was presented with a warning on a plugin page:
How did it know I had WebStorm open? I wasn't logged into the JetBrains site and I don't have any JetBrains extensions installed on Chrome either. A glance in the network tab of Chrome's Developer Tools reveals the answer:
The page was sending a network request to
Consequently, it was sending a network request to some server running on my local computer.
Here's the response in reply:
It receives the version and build number of whatever IDE is running. With this, the plugin page
is able to tell if the shown plugin is incompatible.11.
The actual process may be a little different.
The page usually issues a request to
WebStorm sometimes responds with the plugin's compatibility.
what is that port number?
The port number
63342 in the network request is the default port of WebStorm's integrated server.
When you open an HTML file from WebStorm, the page is served through this server. That's how WebStorm is able to
reload the page when the file is saved.
You can see and configure the port by going to
Build, Execution, Deployment >
However, this configuration option is misleading. It doesn't matter what port the integrated
server is set to, WebStorm and other JetBrains IDEs will listen on
On Unix-based systems,
you can check what processes are using a port with
lsof -i :$PORT.
The only way to prevent WebStorm from advertising itself is to bind another server on the same port.33.
If you have
Python installed, you can easily start a server with
python3 -m http.server $PORT.
Note that on macOS, if you also bind to
python3 -m http.server --bind localhost 63342,
WebStorm's server will take priority.
Just don't change the port to
63343 (one higher than
63342) because the plugin page
also issues a request to that port if
aren't network requests to localhost a security risk?
Imagine you had some web service running locally. Any webpage could send requests to
extract data from those local services or even craft malicious payloads.
So what stops a page from doing that?
The same way requests to other websites are allowed or blocked! Through the
CORS (cross-origin resource sharing) response headers.
localhost is considered a separate origin from (for example)
malicious-site.com, any responses
from the local web service must include a
Access-Control-Allow-Origin header with the same origin
for it to be accessible:
Normally requests that are considered simple
do not need an additional preflight request
(an initial request sent to ensure that the server understands CORS). However,
Chrome sends a special preflight request
localhost origins and requires the server to include the
Access-Control-Request-Private-Network header in
the response for it to be accessible. As of Chrome 108,
this does not seem to be enforced and instead a warning appears in the console if the header is invalid:
More details on this behavior can be found in Chrome's feature documentation.
trying it ourselves
What happens when we try to access an open JetBrains IDE's version information? If you have one installed and running you can see for yourself by clicking the button below. Make sure you're using either Chrome or Firefox (sorry Safari users!)44. On Safari, the request errors in the console with "The certificate for this server is invalid." .
A dialog will appear:
If you select
Yes, the IDE name and build number will be sent back in the response. If you select
an empty response body will be sent back but the name can still be found in the
Server response header.
However, since the
Server header is not considered a
safe CORS header,
it cannot be read by page scripts. Importantly, the IDE asks the user before allowing a
page from an unknown origin to access its API.
In this post we've discussed how the JetBrains plugin marketplace detects what IDE is running,
how network requests can be sent to
localhost, and what is needed to make them succeed.
Now you can try writing your own
localhost network requests!
The actual process may be a little different. The page usually issues a request to
/api/installPlugin?action=checkCompatibilityand WebStorm sometimes responds with the plugin's compatibility. ↩
On Unix-based systems, you can check what processes are using a port with
lsof -i :$PORT. ↩
If you have Python installed, you can easily start a server with
python3 -m http.server $PORT. Note that on macOS, if you also bind to
python3 -m http.server --bind localhost 63342, WebStorm's server will take priority. ↩
On Safari, the request errors in the console with "The certificate for this server is invalid." ↩