Compare commits

...

2 Commits

Author SHA1 Message Date
4225abe3c4 3.30.6
Some checks failed
Default (tags) / security (push) Successful in 36s
Default (tags) / test (push) Failing after 1m0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-03-11 02:18:56 +00:00
74fdb58f84 fix(PortProxy): Improve TLS renegotiation handling in PortProxy by validating the new SNI against allowed domain configurations. If the new SNI is permitted based on existing IP rules, update the locked domain to allow connection reuse; otherwise, terminate the connection to prevent misrouting. 2025-03-11 02:18:56 +00:00
4 changed files with 45 additions and 4 deletions

View File

@ -1,5 +1,11 @@
# Changelog
## 2025-03-11 - 3.30.6 - fix(PortProxy)
Improve TLS renegotiation handling in PortProxy by validating the new SNI against allowed domain configurations. If the new SNI is permitted based on existing IP rules, update the locked domain to allow connection reuse; otherwise, terminate the connection to prevent misrouting.
- Added logic to check if a new SNI during renegotiation is allowed by comparing IP rules from the matching domain configuration.
- Updated detailed logging to indicate when a valid SNI change is accepted and when it results in a mismatch termination.
## 2025-03-10 - 3.30.5 - fix(internal)
No uncommitted changes detected; project files and tests remain unchanged.

View File

@ -1,6 +1,6 @@
{
"name": "@push.rocks/smartproxy",
"version": "3.30.5",
"version": "3.30.6",
"private": false,
"description": "A powerful proxy package that effectively handles high traffic, with features such as SSL/TLS support, port proxying, WebSocket handling, and dynamic routing with authentication options.",
"main": "dist_ts/index.js",

View File

@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@push.rocks/smartproxy',
version: '3.30.5',
version: '3.30.6',
description: 'A powerful proxy package that effectively handles high traffic, with features such as SSL/TLS support, port proxying, WebSocket handling, and dynamic routing with authentication options.'
}

View File

@ -871,10 +871,45 @@ export class PortProxy {
return;
}
// Only block if we positively identify a different SNI
// Check if the SNI has changed
if (newSNI && newSNI !== record.lockedDomain) {
// Instead of immediately terminating, check if the new SNI would be allowed
// by the same ruleset that allowed the initial connection
const newDomainConfig = this.settings.domainConfigs.find((config) =>
config.domains.some((d) => plugins.minimatch(newSNI, d))
);
// If we found a matching domain config, check IP rules
if (newDomainConfig) {
const effectiveAllowedIPs = [
...newDomainConfig.allowedIPs,
...(this.settings.defaultAllowedIPs || []),
];
const effectiveBlockedIPs = [
...(newDomainConfig.blockedIPs || []),
...(this.settings.defaultBlockedIPs || []),
];
// Check if the IP is allowed for the new domain
if (isGlobIPAllowed(record.remoteIP, effectiveAllowedIPs, effectiveBlockedIPs)) {
// Allow the domain switch - Chrome is reusing the connection for a different domain
if (this.settings.enableDetailedLogging) {
console.log(
`[${connectionId}] Rehandshake with new SNI: ${newSNI} (previously ${record.lockedDomain}). ` +
`New domain is allowed by rules, permitting connection reuse.`
);
}
// Update the locked domain to the new domain
record.lockedDomain = newSNI;
return;
}
}
// If we get here, either no matching domain config was found or the IP is not allowed
console.log(
`[${connectionId}] Rehandshake detected with different SNI: ${newSNI} vs locked ${record.lockedDomain}. Terminating connection.`
`[${connectionId}] Rehandshake detected with different SNI: ${newSNI} vs locked ${record.lockedDomain}. ` +
`New domain not allowed by rules. Terminating connection.`
);
this.initiateCleanupOnce(record, 'sni_mismatch');
} else if (newSNI && this.settings.enableDetailedLogging) {