
Research
/Security News
Toptal’s GitHub Organization Hijacked: 10 Malicious Packages Published
Threat actors hijacked Toptal’s GitHub org, publishing npm packages with malicious payloads that steal tokens and attempt to wipe victim systems.
@hackolade/fetch
Advanced tools
This is the HTTP client for Hackolade Studio and its plugins. It takes into account the proxies and the custom certificate authorities that are configured at the level of the operating system, which removes the need for the end user to deal with complex network settings in Hackolade Studio. It also supports configuring custom network settings in the desktop application if needed.
Web browsers provide natively the Fetch API.
In Electron, that API was originally only available in the renderer
process (which is basically a browser).
It is now also available in the main
process and in utility
processes via net.fetch. Since that function uses the Chrome's network stack, it also benefits from the integration with the OS trust store (for validating self-signed-certificates) and network settings (for detecting proxies).
This library returns the proper implementation of fetch() depending on the runtime context:
renderer
processmain
and utility
processesThis library also provides extensions to modular SDK's that allow setting a custom HTTP client:
HttpHandler
for the aws-sdk (see example here)This library aims at being a drop-in replacement for node-fetch. node-fetch can be replaced by @hackolade/fetch using NPM overrides.
"overrides": {
"node-fetch": {
".": "npm:@hackolade/fetch@1.2.2"
}
}
version
in package.json.Release v<major>.<minor>.<patch>
.develop
typically).We need to test that this library behaves as expected in various situations, whatever the OS of the user:
main
process, a renderer
process and a utility
processIn order to perform those tests, we have prepared multiple components:
Component | URL | Description |
---|---|---|
server | On your host (direct access): http://127.0.0.1:8080 https://127.0.0.1:4443 In Docker network (access through proxy): http://server:8080 https://server:4443 | This server exposes the following REST endpoint: PUT /initiators/:connectionType/:initiator It allows clients to register themselves using arbitrary routes: /initiators/direct/main , initiators/proxy/renderer , etc. This server also exposes the following REST endpoint: GET /initiators/:connectionType/:initiator It can be used to check if a given client managed to reach the server to register itself. |
app | NA | This is an Electron application. It contacts the server from both the main process, a renderer process and a utility process. Each process registers itself as a distinct :initiator : main , renderer and utility respectively. The base URL of the endpoint - including the :connectionType - is passed to the application through an environment variable, making it possible to start different instances of the application to cover different cases (e.g. direct connection, connection through a proxy). |
proxy | http://127.0.0.1:3128 | This is a proxy that does not require authentication. |
proxy-basic-auth | http://127.0.0.1:3129 | This is a proxy that requires basic authentication. You can use user1 as both username and password. |
proxy-https-inspection | http://127.0.0.1:3130 | This is a proxy that performs HTTPS inspection using a self-signed certificate. |
PAC file | http://127.0.0.1:8081/proxy.pac | This is a PAC file that leads to using the proxy that does not require authentication. |
tests | NA | This is a set of tests that query the REST API of the server to verify that all clients could successfully register themselves, whatever the context of the connection. |
Follow the instructions below prior to executing the tests:
node
: see instructions here.docker
engine for your operating system: see instructions here.npm install
in this repository in order to install the dependencies.You can run the command below to execute the automated tests.
npm run docker:test
:warning: Those tests validate the behavior of the library in Docker/Linux. Validating the behavior of the library in MacOS and Windows involve manual steps that are documented below.
See next sections for more details...
Linux | MacOS | Windows | Notes | |
---|---|---|---|---|
Direct connection | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
OS SETTINGS | Test cases for proxy settings and certificate authorities from the OS | |||
Self-signed certificate | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
Proxy | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
Proxy with basic auth | :white_check_mark: | :warning: | :warning: | 'login' event not emitted for main process (see issue #44249) |
PAC file | :warning: | :white_check_mark: | :white_check_mark: | Not natively supported by the Linux OS |
Proxy with HTTPS inspection | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
APP SETTINGS | Test cases for proxy settings and certificate authorities configured in the app | |||
Self-signed certificate | :white_check_mark: | :warning: | :warning: | setCertificateVerifyProc() ignored by utility process (see issue #44264) |
Proxy | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
Proxy with basic auth | :white_check_mark: | :warning: | :warning: | 'login' event not emitted for main process (see issue #44249) |
PAC file | :white_check_mark: | :white_check_mark: | :white_check_mark: |
In this case, the app connects directly to the server. There is no intermediate proxy involved.
:white_check_mark: Linux: this case is covered by the automated tests.
:white_check_mark: MacOS, :white_check_mark: Windows: follow the instructions below.
npm run docker:server
.npm run test:app:direct
. It should render all connections with a green background.The test cases that are described in this section cover the integration with the OS trust store (for validating self-signed-certificates) and network settings (for detecting proxies).
For a certificate to be considered valid, it must be signed by a trusted certificate authority (CA), such as GlobalSign or DigiCert. Obtaining such a certificate used to cost some money (this is not true anymore thanks to Let's Encrypt, a nonprofit certificate authority). That's why some organizations generated their own self-signed certificates, typically for internal use. Those certificates are free. However, they are unsafe and prevent HTTPS connections from being established. To be able to use self-signed certificates, an organization must add itself to the list of trusted certificate authorities in the OS of all its users.
:white_check_mark: Linux: this case is covered by the automated tests. Note that the custom certificate authority must be added to the NSS Shared DB (see instructions here).
:white_check_mark: MacOS: follow the instructions below.
npm run docker:server
.npm run test:app:cert
. It should render all connections with a green background.:white_check_mark: Windows: follow the instructions below.
npm run docker:server
.npm run test:app:cert
. It should render all connections with a green background.certmgr.msc
in the Start menu).In this case, the app connects to the server through a proxy that has been configured in the OS.
:white_check_mark: Linux: this case is covered by the automated tests. Note that the proxy is configured through the environment variables HTTP_PROXY
and HTTPS_PROXY
, which is the standard way of configuring proxies in Linux.
:white_check_mark: MacOS: follow the instructions below.
npm run docker:server
.npm run test:app:proxy
. It should render all connections with a green background.:white_check_mark: Windows: follow the instructions below.
npm run docker:server
.npm run test:app:proxy
. It should render all connections with a green background.In this case, the app connects to the server through a proxy that has been configured in the OS. That proxy requires a username and a password. Even though the username and the password might have been set at the level of the operating system, the user needs to provide them interactively to the Electron application. It is also the case for other apps such as Slack or Docker Desktop.
The main
process must handle the login event and prompt the user for the proxy credentials.
const { app } = require('electron');
app.on('login', (event, webContents, details, authInfo, callback) => {
// Prevent the default behavior since it cancels all authentications.
event.preventDefault();
// Prompt the user for credentials
// ...
callback(username, password);
});
The login
handler will be called automatically for both the main
process and a renderer
process.
For a utility
process, the option respondToAuthRequestsFromMainProcess must be set to true
when creating it.
const { utilityProcess } = require('electron');
utilityProcess.fork(..., { respondToAuthRequestsFromMainProcess: true });
:white_check_mark: Linux: this case is covered by the automated tests. Note that the proxy is configured through the environment variables HTTP_PROXY
and HTTPS_PROXY
, which is the standard way of configuring proxies in Linux.
:warning: MacOS: follow the instructions below. Note that the server cannot be contacted from the main
process because the 'login' event (see code snippet above) is not emitted for that process, which ultimately leads to a HTTP #407 Proxy Authentication Required
.
npm run docker:server
.npm run test:app:proxy-basic-auth
. It should render all connections with a green background. Note that you won't be prompted for credentials because we hardcoded them.:white_check_mark: Windows: follow the instructions below.
npm run docker:server
.npm run test:app:proxy-basic-auth
. It should render all connections with a green background. Note that you won't be prompted for credentials because we hardcoded them.In this case, the app connects to the server through the proxy that is returned by a PAC file that has been configured in the OS.
:warning: Linux: PAC files are not natively supported by Linux, aka you cannot set HTTP_PROXY
or HTTPS_PROXY
to the URL of a PAC file. Linux requires the application itself to provide support for PAC files. That's because PAC files were originally meant to be used by browsers (see here). That's why they are JavaScript files.
:white_check_mark: MacOS: follow the instructions below.
npm run docker:server
.npm run test:app:proxy-pac-file
. It should render all connections with a green background.:white_check_mark: Windows: follow the instructions below.
npm run docker:server
.npm run test:app:proxy-pac-file
. It should render all connections with a green background.HTTPS inspection is the process of checking encrypted web traffic. It relies on a proxy that sets up two separate encrypted connections:
Note that the proxy can use a self-signed certificate. This means that establishing the connection with a server can require a custom certificate authority even though the server uses a valid certificate.
:white_check_mark: Linux: this case is covered by the automated tests.
:white_check_mark: MacOS: follow the instructions below.
npm run docker:server
.npm run test:app:proxy-https-inspection
. It should render all connections with a green background.:white_check_mark: Windows: follow the instructions below.
npm run docker:server
.npm run test:app:proxy-https-inspection
. It should render all connections with a green background.certmgr.msc
in the Start menu).The test cases that are described in this section cover the configuration of custom network settings in the application itself.
In this case, the app connects to a server that uses a self-signed certificate. The corresponding certificate authority has not been installed in the trust store of the operating system: it is configured directly in the application. You can find here the code that installs that certificate authority in the application.
:white_check_mark: Linux: this case is covered by the automated tests.
:warning: MacOS, :warning: Windows: follow the instructions below. Note that the server cannot be contacted from the utility
process because it ignores the custom procedure that we set for verifying the certificate (see session.setCertificateVerifyProc()).
npm run docker:server
.npm run test:app:custom-cert
. It should render all connections with a green background, except for the utility
process.In this case, the app connects to the server through a proxy that has been configured in the app itself. You can find here the code that applies the given proxy settings.
:white_check_mark: Linux: this case is covered by the automated tests.
:white_check_mark: MacOS, :white_check_mark: Windows: follow the instructions below.
npm run docker:server
.npm run test:app:custom-proxy
. It should render all connections with a green background.In this case, the app connects to the server through a proxy that has been configured in the app itself. That proxy requires a username and a password.
:white_check_mark: Linux: this case is covered by the automated tests.
:warning: MacOS, :warning: Windows: follow the instructions below. Note that the server cannot be contacted from the main
process because the 'login' event is not emitted for that process, which ultimately leads to a HTTP #407 Proxy Authentication Required
.
npm run docker:server
.npm run test:app:custom-proxy-basic-auth
. It should render all connections with a green background, except for the main
process.In this case, the app connects to the server through the proxy that is returned by a PAC file that has been configured in the app itself.
:white_check_mark: Linux: this case is covered by the automated tests.
:white_check_mark: MacOS, :white_check_mark: Windows: follow the instructions below.
npm run docker:server
.npm run test:app:custom-proxy-pac-file
. It should render all connections with a green background.TypeScript does not require you to specify the file extensions in imports and exports.
However, the TypeScript code of this library is ultimately transpiled to both CommonJS and ESM.
ESM requires imports and exports to be fully specified, aka to include the file extensions (see here).
The problem is that TypeScript transpilers do not modify imported and exported paths (see here).
So the only workaround is to use the .js
extension in the TypeScript imports and exports in order to be compliant with the ESM requirement (see here).
This problem is related to line break differences between operating systems. To fix it, just save the Dockerfile using the LF line break (e.g. from the status bar in Visual Studio Code).
When reporting an issue in the Electron repository, you need to provide a standalone test case that reproduces the problem. You can do this easily by using Electron Fiddle. You can connect it to your GitHub account and easily upload a test case as a public gist that you can then link from the GitHub issue that you are creating.
Examples:
[1.3.0] - 2025-05-14
FAQs
A HTTP client that works in the browser and in Electron
We found that @hackolade/fetch demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
/Security News
Threat actors hijacked Toptal’s GitHub org, publishing npm packages with malicious payloads that steal tokens and attempt to wipe victim systems.
Research
/Security News
Socket researchers investigate 4 malicious npm and PyPI packages with 56,000+ downloads that install surveillance malware.
Security News
The ongoing npm phishing campaign escalates as attackers hijack the popular 'is' package, embedding malware in multiple versions.