Skip to content

Commit 966aa73

Browse files
authored
Merge branch 'main' into update-deps
2 parents 5581ade + f8a61a3 commit 966aa73

File tree

4 files changed

+76
-17
lines changed

4 files changed

+76
-17
lines changed

package-lock.json

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
"dependencies": {
9090
"axios": "^1.6.8",
9191
"naive-ui": "^2.38.1",
92+
"ipaddr.js": "^2.1.0",
9293
"uuid": "^9.0.1",
9394
"vue-query": "^1.26.0",
9495
"vue-router": "^4.3.1"

src/helpers/socksProxy.test.ts

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { describe, expect, it } from '@jest/globals';
2+
import { isLocalOrReservedIP } from './socksProxy';
3+
4+
describe('isLocalOrReservedIP', () => {
5+
it('should return true for localhost', () => {
6+
expect(isLocalOrReservedIP('localhost:8080')).toBeTruthy();
7+
});
8+
9+
it('should return true for private IP', () => {
10+
expect(isLocalOrReservedIP('192.168.1.1')).toBeTruthy();
11+
});
12+
13+
it('should return true for loopback IP', () => {
14+
expect(isLocalOrReservedIP('127.0.0.1')).toBeTruthy();
15+
expect(isLocalOrReservedIP('::1')).toBeTruthy();
16+
});
17+
18+
it('should return false for public IP', () => {
19+
expect(isLocalOrReservedIP('8.8.8.8')).toBeFalsy();
20+
});
21+
22+
it('should return false for invalid IP', () => {
23+
expect(isLocalOrReservedIP('invalid.ip')).toBeFalsy();
24+
});
25+
26+
it('should return true for unique local addresses', () => {
27+
expect(isLocalOrReservedIP('fc00::')).toBeTruthy();
28+
});
29+
30+
it('should return true for multicast addresses', () => {
31+
expect(isLocalOrReservedIP('ff00::')).toBeTruthy();
32+
});
33+
34+
it('should return false when IP address is not provided', () => {
35+
expect(isLocalOrReservedIP('')).toBeFalsy();
36+
});
37+
});

src/helpers/socksProxy.ts

+29-17
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { RequestDetails, ProxyDetails } from './socksProxy.types';
2+
import ipaddr from 'ipaddr.js';
23

34
const getGlobalProxyDetails = async (): Promise<ProxyDetails> => {
45
const response = await browser.storage.local.get('globalProxyDetails');
@@ -59,13 +60,7 @@ const handleProxyRequest = async (details: browser.proxy._OnRequestDetails) => {
5960
const proxiedHosts = Object.keys(hostProxiesParsed);
6061
const currentHost = getCurrentHost(details);
6162

62-
if (excludedHostsParsed.includes(currentHost) || currentHost.includes('localhost')) {
63-
// Disable logging for localhost
64-
if (!currentHost.includes('localhost')) {
65-
console.log('excluded: ', details.url);
66-
console.log('proxy used: direct');
67-
console.log('_____________________________');
68-
}
63+
if (excludedHostsParsed.includes(currentHost) || isLocalOrReservedIP(currentHost)) {
6964
return { type: 'direct' };
7065
} else if (
7166
proxiedHosts.includes(currentHost) &&
@@ -87,21 +82,38 @@ const getCurrentHost = (details: RequestDetails) => {
8782
// the host is determined from its top parent frame (frameID === 0)
8883
const frame = details.frameAncestors.find((frame) => frame.frameId === 0);
8984
if (frame) {
90-
return new URL(frame.url).host;
85+
return new URL(frame.url).hostname;
9186
}
92-
} else if (
93-
new URL(details.url).host.includes('localhost') ||
94-
new URL(details.url).host.includes('::1') ||
95-
new URL(details.url).host.includes('127.0.0.1')
96-
) {
97-
// This is to make sure localhost traffic is not proxied
98-
return new URL(details.url).host;
87+
} else if (isLocalOrReservedIP(new URL(details.url).hostname)) {
88+
// This is to handle localhost/reserved IP ranges
89+
return new URL(details.url).hostname;
9990
} else if (details.documentUrl) {
10091
// when the request comes froms a a page(top level frame),
10192
// then the host is determined from the document URL
102-
return new URL(details.documentUrl).host;
93+
return new URL(details.documentUrl).hostname;
10394
}
10495
// When a request is initiated in the browser background,
10596
// the host is derived from the request URL itself
106-
return new URL(details.url).host;
97+
return new URL(details.url).hostname;
98+
};
99+
100+
export const isLocalOrReservedIP = (hostname: string) => {
101+
if (hostname.includes('localhost')) return true;
102+
if (!ipaddr.isValid(hostname)) return false;
103+
104+
try {
105+
const addr = ipaddr.parse(hostname);
106+
const range = addr.range();
107+
108+
return (
109+
range === 'private' ||
110+
range === 'multicast' ||
111+
range === 'linkLocal' ||
112+
range === 'loopback' ||
113+
range === 'uniqueLocal'
114+
);
115+
} catch (e: unknown) {
116+
console.error('Invalid IP address:', e);
117+
return false;
118+
}
107119
};

0 commit comments

Comments
 (0)