requests to localhost and finding open JetBrains IDEs
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 localhost
! Specifically, http://localhost:63342/api/installPlugin
.
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 /api/installPlugin?action=checkCompatibility
and
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 Preferences
> Build, Execution, Deployment
> Debugger
:
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 63342
anyway.22.
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 localhost
with 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 63342
fails.
aren't network requests to localhost a security risk?
Imagine you had some web service running locally. Any webpage could send requests to localhost
and
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.
Since 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
for 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 No
,
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.
conclusion
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!
footnotes
-
The actual process may be a little different. The page usually issues a request to
/api/installPlugin?action=checkCompatibility
and 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 tolocalhost
withpython3 -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." ↩