Skip to content

Commit ff0f945

Browse files
authored
Merge pull request #35 from monteslu/fix/url-validation
fix: URL validation for dynamicHost (CVE-HSYNC-2026-004)
2 parents 5456642 + 01e376f commit ff0f945

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

connection.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,23 @@ export async function createHsync(config) {
4747
let dynamicTimeout;
4848

4949
if (dynamicHost && !hsyncSecret) {
50-
const result = await fetch.post(`${dynamicHost}/${hsyncBase}/dyn`, {});
51-
if (dynamicHost.toLowerCase().startsWith('https')) {
52-
hsyncServer = `wss://${result.url}`;
53-
} else {
54-
hsyncServer = `ws://${result.url}`;
50+
// Validate dynamicHost to prevent URL injection/SSRF (CVE-HSYNC-2026-004)
51+
let validatedHost;
52+
let isSecure;
53+
try {
54+
const parsed = new URL(dynamicHost);
55+
// Only allow http/https protocols
56+
if (!['http:', 'https:'].includes(parsed.protocol)) {
57+
throw new Error(`Invalid protocol: ${parsed.protocol}`);
58+
}
59+
isSecure = parsed.protocol === 'https:';
60+
// Reconstruct URL with only origin to strip path/query/fragment
61+
validatedHost = parsed.origin;
62+
} catch (urlErr) {
63+
throw new Error(`Invalid dynamicHost URL: ${urlErr.message}`);
5564
}
65+
const result = await fetch.post(`${validatedHost}/${hsyncBase}/dyn`, {});
66+
hsyncServer = isSecure ? `wss://${result.url}` : `ws://${result.url}`;
5667
hsyncSecret = result.secret;
5768
dynamicTimeout = result.timeout;
5869
}

0 commit comments

Comments
 (0)