Research
Security News
Malicious npm Package Targets Solana Developers and Hijacks Funds
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
@e9x/simple-socks
Advanced tools
Creates a simple SOCKS5 server and gives you control over the flow (filter, auth, protocol).
This is a clone of https://github.com/brozeph/simple-socks.
$ npm install @e9x/simple-socks
This package will not log errors caught in callbacks such as authenticate
, filter
, and connect
by default. This may lead to unexpected errors being caught and causing clients to disconnect. This may lead to confusion and unintended closing of the SOCKS client. To help debug, this package uses debug.
Set the DEBUG
environment variable to simple-socks
in your terminal to see debug messages from this package.
set DEBUG=simple-socks & node examples/createServer.mjs
$env:DEBUG = 'simple-socks'; node examples/createServer.mjs
DEBUG=simple-socks node examples/createServer.mjs
In the examples folder exists two examples, one that requires no authentication and one that requires username/password authentication. Below is an example with no authentication:
import { createProxyServer } from "@e9x/simple-socks";
const server = createProxyServer();
server.listen(1080);
For a SOCKS5 server that does not require authentication, look at examples/createServer.mjs:
$ node examples/createServer.mjs
In a separate terminal window:
$ curl http://www.google.com --socks5 127.0.0.1:1080
For a SOCKS5 server that requires username/password authentication, look at examples/createServerWithAuthentication.mjs:
$ node examples/createServerWithAuthentication.mjs
In a separate terminal window:
$ curl http://www.google.com --socks5 127.0.0.1:1080 --proxy-user foo:bar
For a SOCKS5 server that can perform either origin or destination (or both!) address filtering, look at examples/createServerFilter.mjs:
$ node examples/createServerFilter.mjs
In a separate terminal window:
$ curl http://www.github.com --socks5 127.0.0.1:1080 # allowed
$ curl http://www.google.com --socks5 127.0.0.1:1080 # denied
The underlying API to connect to the destination is exposed to allow for flexibility. As a result, you can use slightly higher level APIs to establish a connection to the destination. For a SOCKS5 server will connect to a locally hosted TOR socks proxy, look at examples/createServerConnect.mjs:
$ node examples/createServerConnect.mjs
In a separate terminal window:
$ curl https://myip.wtf/json --socks5 127.0.0.1:1080
{
"YourF***ingTorExit": true
}
Factory method that creates an instance of a SOCKS5 proxy server:
import { createProxyServer } from "@e9x/simple-socks";
const server = createProxyServer();
server.listen(1080, "0.0.0.0", () => {
console.log("SOCKS5 proxy server started on 0.0.0.0:1080");
});
This method accepts an optional options
argument:
options.authentication
- A callback for authenticationoptions.filter
- A callback for connection filteringoptions.connect
- A callback for low-level connectingUnlike simple-socks, the callbacks are based on modern promises.
The return value is equivalent to net.Server with a pre-defined listener for connection
.
To make the socks5 server require username/password authentication, supply a function callback in the options as follows:
import { createProxyServer } from "@e9x/simple-socks";
const server = createProxyServer({
authenticate: (username, password) =>
username === "foo" && password === "bar",
});
// begin listening and require user/pass authentication
server.listen(1080);
The authenticate
callback accepts three arguments:
You must return a promise. The promise resolving true indicates the credentials were accepted. The promise resolving false indicates the credentials were rejected.
Allows you to filter incoming connections, based on either origin and/or destination.
import { createProxyServer } from "@e9x/simple-socks";
const server = createProxyServer({
filter: (destinationPort, destinationAddress, socket) => {
if (socket.remoteAddress === "127.0.0.1") {
console.log(
"denying access from %s:%s",
socket.remoteAddress,
socket.remotePort,
);
return false;
}
if (destinationAddress === "10.0.0.1") {
console.log(
"denying access to %s:%s",
destinationAddress,
destinationPort,
);
return false;
}
return true;
},
});
The filter
callback accepts three arguments:
For an example, see examples/createServerFilter.mjs.
You must return a promise. The promise resolving true indicates the connection was accepted. The promise resolving false indicates the connection was rejected.
Allows you to control the flow of connecting to the remote.
import { createProxyServer } from "@e9x/simple-socks";
import { SocksClient } from "socks";
const server = createProxyServer({
connect: async (port, host) => {
// connect to TOR socks proxy
const { socket } = await SocksClient.createConnection({
proxy: {
host: "127.0.0.1",
port: 9050, // TOR daemon
type: 5,
},
command: "connect",
destination: {
port,
host,
},
});
return socket;
},
});
The connect
callback accepts three arguments:
For an example, see examples/createServerConnect.mjs.
You must return a promise. The promise resolving true indicates the connection was accepted and is CONNECTED. The promise resolving false indicates the connection was rejected and was NOT connected. You can utilize waitForConnect to wait for the socket to connect/throw before resolving to make it compatible with this callback.
Method that will wait for a socket to connect to help use unconnected sockets as the resolution for connect:
import { createProxyServer, waitForConnect } from "@e9x/simple-socks";
import { connect } from "node:net";
const server = createProxyServer({
connect: async (port, host) => {
// create unconnected socket
const socket = connect(port, host);
await waitForConnect(socket);
return socket;
},
});
(non-async)
import { createProxyServer, waitForConnect } from "@e9x/simple-socks";
import { connect } from "node:net";
const server = createProxyServer({
connect: (port, host) =>
new Promise((resolve, reject) => {
// create unconnected socket
const socket = connect(port, host);
waitForConnect(socket)
.then(() => {
resolve(socket);
})
.catch((err) => {
// only err should be passed to reject
reject(err);
});
}),
});
The waitForConnect
method accepts one argument:
The socket must not already be connected when calling this method. If it is, return the socket instead of calling this method. This method will throw an error if the socket could not connect. This error should be caught in the stack that called options.connect. You should not catch this error and return a different one because it contains an error code that is used to determine how the socket was ended.
Unlike simple-socks, events have been removed due to the unlikeliness of them being used and their nature of wasting resources. Specifically the proxyData event is the culprit of poor speeds because it causes the stream to buffer, adding overhead to streaming data from the client to the remote. It may be argued the events being fired constantly are a waste of resources too. Use the hooks provided in options instead.
FAQs
SOCKS proxy server written in TypeScript
We found that @e9x/simple-socks demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer 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
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.