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.
This commit is contained in:
parent
bffdaffe39
commit
74fdb58f84
@ -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.
|
||||
|
||||
|
@ -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.'
|
||||
}
|
||||
|
@ -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 detected with different SNI: ${newSNI} vs locked ${record.lockedDomain}. Terminating connection.`
|
||||
`[${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}. ` +
|
||||
`New domain not allowed by rules. Terminating connection.`
|
||||
);
|
||||
this.initiateCleanupOnce(record, 'sni_mismatch');
|
||||
} else if (newSNI && this.settings.enableDetailedLogging) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user