Skip to content

Commit

Permalink
fix: correctly validate protocols in anonymize_proxy (#545)
Browse files Browse the repository at this point in the history
This allows usage of SOCKS protocols with `anonymizeProxy`.
  • Loading branch information
jirimoravcik authored Aug 19, 2024
1 parent a1ac3f2 commit c46eafd
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 20 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "proxy-chain",
"version": "2.5.1",
"version": "2.5.2",
"description": "Node.js implementation of a proxy server (think Squid) with support for SSL, authentication, upstream proxy chaining, and protocol tunneling.",
"main": "dist/index.js",
"keywords": [
Expand Down
9 changes: 4 additions & 5 deletions src/anonymize_proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import net from 'net';
import http from 'http';
import { Buffer } from 'buffer';
import { URL } from 'url';
import { Server } from './server';
import { Server, SOCKS_PROTOCOLS } from './server';
import { nodeify } from './utils/nodeify';

// Dictionary, key is value returned from anonymizeProxy(), value is Server instance.
Expand Down Expand Up @@ -38,10 +38,9 @@ export const anonymizeProxy = (
}

const parsedProxyUrl = new URL(proxyUrl);
if (parsedProxyUrl.protocol !== 'http:') {
throw new Error(
'Invalid "proxyUrl" option: only HTTP proxies are currently supported.',
);
if (!['http:', ...SOCKS_PROTOCOLS].includes(parsedProxyUrl.protocol)) {
// eslint-disable-next-line max-len
throw new Error(`Invalid "proxyUrl" provided: URL must have one of the following protocols: "http", ${SOCKS_PROTOCOLS.map((p) => `"${p.replace(':', '')}"`).join(', ')} (was "${parsedProxyUrl}")`);
}

// If upstream proxy requires no password, return it directly
Expand Down
2 changes: 1 addition & 1 deletion src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { customConnect } from './custom_connect';
import { forwardSocks } from './forward_socks';
import { chainSocks } from './chain_socks';

const SOCKS_PROTOCOLS = ['socks:', 'socks4:', 'socks4a:', 'socks5:', 'socks5h:'];
export const SOCKS_PROTOCOLS = ['socks:', 'socks4:', 'socks4a:', 'socks5:', 'socks5h:'];

// TODO:
// - Implement this requirement from rfc7230
Expand Down
14 changes: 1 addition & 13 deletions test/anonymize_proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,19 +114,11 @@ describe('utils.anonymizeProxy', function () {
assert.throws(() => { closeAnonymizedProxy(null); }, Error);
});

it('throws for unsupported proxy protocols', () => {
assert.throws(() => { anonymizeProxy('socks://whatever.com'); }, Error);
it('throws for unsupported https: protocol', () => {
assert.throws(() => { anonymizeProxy('https://whatever.com'); }, Error);
assert.throws(() => { anonymizeProxy('socks5://whatever.com'); }, Error);
assert.throws(() => {
anonymizeProxy({ url: 'socks://whatever.com' });
}, Error);
assert.throws(() => {
anonymizeProxy({ url: 'https://whatever.com' });
}, Error);
assert.throws(() => {
anonymizeProxy({ url: 'socks5://whatever.com' });
}, Error);
});

it('throws for invalid ports', () => {
Expand All @@ -144,16 +136,12 @@ describe('utils.anonymizeProxy', function () {
it('throws for invalid URLs', () => {
assert.throws(() => { anonymizeProxy('://whatever.com'); }, Error);
assert.throws(() => { anonymizeProxy('https://whatever.com'); }, Error);
assert.throws(() => { anonymizeProxy('socks5://whatever.com'); }, Error);
assert.throws(() => {
anonymizeProxy({ url: '://whatever.com' });
}, Error);
assert.throws(() => {
anonymizeProxy({ url: 'https://whatever.com' });
}, Error);
assert.throws(() => {
anonymizeProxy({ url: 'socks5://whatever.com' });
}, Error);
});

it('keeps already anonymous proxies (both with callbacks and promises)', () => {
Expand Down
25 changes: 25 additions & 0 deletions test/socks.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ const ProxyChain = require('../src/index');
describe('SOCKS protocol', () => {
let socksServer;
let proxyServer;
let anonymizeProxyUrl;

afterEach(() => {
if (socksServer) socksServer.close();
if (proxyServer) proxyServer.close();
if (anonymizeProxyUrl) ProxyChain.closeAnonymizedProxy(anonymizeProxyUrl, true);
});

it('works without auth', (done) => {
Expand Down Expand Up @@ -70,4 +72,27 @@ describe('SOCKS protocol', () => {
.catch(done);
});
}).timeout(5 * 1000);

it('works with anonymizeProxy', (done) => {
portastic.find({ min: 50500, max: 50750 }).then((ports) => {
const [socksPort, proxyPort] = ports;
socksServer = socksv5.createServer((info, accept) => {
accept();
});
socksServer.listen(socksPort, 'localhost');
socksServer.useAuth(socksv5.auth.UserPassword((user, password, cb) => {
cb(user === 'proxy-chain' && password === 'rules!');
}));

ProxyChain.anonymizeProxy({ port: proxyPort, url: `socks://proxy-chain:rules!@localhost:${socksPort}` }).then((anonymizedProxyUrl) => {
anonymizeProxyUrl = anonymizedProxyUrl;
gotScraping.get({ url: 'https://example.com', proxyUrl: anonymizedProxyUrl })
.then((response) => {
expect(response.body).to.contain('Example Domain');
done();
})
.catch(done);
});
});
}).timeout(5 * 1000);
});

0 comments on commit c46eafd

Please sign in to comment.