Commit febc36f
fix(security): enforce URL validation across connectors, providers, and auth flows (SSRF + open-redirect hardening) (#4236)
* fix(workday): validate tenantUrl to prevent SSRF in SOAP client
* fix(workday): use validation.sanitized in buildWsdlUrl
* fix(security): enforce URL validation across connectors, providers, auth
- Azure OpenAI/Anthropic: validate user-supplied azureEndpoint with validateUrlWithDNS to block SSRF to private IPs, localhost (in hosted mode), and dangerous ports.
- ServiceNow connector: enforce ServiceNow domain allowlist via validateServiceNowInstanceUrl before calling the instance URL.
- Obsidian connector: validate vaultUrl with validateUrlWithDNS and reuse the resolved IP via secureFetchWithPinnedIPAndRetry to block DNS rebinding between validation and request.
- Signup + verify flows: pass redirect/callbackUrl/redirectAfter and stored inviteRedirectUrl through validateCallbackUrl; drop unsafe values and log a warning.
- lib/knowledge/documents/utils.ts: add secureFetchWithPinnedIPAndRetry wrapper around secureFetchWithPinnedIP (used by Obsidian).
* fix(obsidian): use isomorphic SSRF validation to unblock client build
The Obsidian connector is reachable from client bundles via `connectors/registry.ts` (the knowledge UI reads metadata like `.icon`/`.name`). Importing `validateUrlWithDNS` / `secureFetchWithPinnedIP` from `input-validation.server` pulled `dns/promises`, `http`, `https`, `net` into client chunks, breaking the Turbopack build:
Module not found: Can't resolve 'dns/promises'
./apps/sim/lib/core/security/input-validation.server.ts [Client Component Browser]
./apps/sim/connectors/obsidian/obsidian.ts [Client Component Browser]
./apps/sim/connectors/registry.ts [Client Component Browser]
Once that file polluted a browser context, Turbopack also failed to resolve the Node builtins in its legitimate server-route imports, cascading the error across App Routes and Server Components.
Fix: switch the Obsidian connector to the isomorphic `validateExternalUrl` + `fetchWithRetry` helpers, matching the pattern used by every other connector in the registry. This keeps the core SSRF protections:
- hosted Sim: blocks localhost, private IPs, HTTP (HTTPS enforced)
- self-hosted Sim: allows localhost + HTTP, still blocks non-loopback private IPs and dangerous ports (22, 25, 3306, 5432, 6379, 27017, 9200)
Drops the DNS-rebinding defense specifically (the IP-pinned fetch chain). The trade-off is acceptable because the vault URL is entered by the workspace admin — not arbitrary untrusted input — and hosted deployments already force the plugin to be exposed through a public URL (tunnel/port-forward), making rebinding a narrow threat.
Also reverts the `secureFetchWithPinnedIPAndRetry` wrapper in `lib/knowledge/documents/utils.ts` (no longer needed, and its `.server` import was the original source of the client-bundle pollution).
* fix(servicenow): propagate URL validation errors in getDocument
Match listDocuments behavior — invalid instance URL should surface as a
configuration error rather than being swallowed into a "document not found"
null response during sync.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(obsidian): drop allowHttp to restore HTTPS enforcement in hosted mode
allowHttp: true permitted plaintext HTTP for all hosts in all deployment
modes, contradicting the documented policy. The default validateExternalUrl
behavior already allows http://localhost in self-hosted mode (the actual
Obsidian Local REST API use case) via the built-in carve-out, while correctly
rejecting HTTP for public hosts in hosted mode — which prevents leaking the
Bearer access token over plaintext.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>1 parent 5cf7e8d commit febc36f
File tree
9 files changed
+528
-44
lines changed- apps/sim
- app/(auth)
- signup
- verify
- connectors
- obsidian
- servicenow
- lib/core/security
- providers
- azure-anthropic
- azure-openai
- tools/workday
9 files changed
+528
-44
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| 13 | + | |
13 | 14 | | |
14 | 15 | | |
15 | 16 | | |
| |||
102 | 103 | | |
103 | 104 | | |
104 | 105 | | |
105 | | - | |
106 | | - | |
107 | | - | |
108 | | - | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
109 | 114 | | |
110 | 115 | | |
111 | 116 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
55 | 56 | | |
56 | 57 | | |
57 | 58 | | |
58 | | - | |
| 59 | + | |
59 | 60 | | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
60 | 64 | | |
61 | 65 | | |
62 | 66 | | |
| |||
67 | 71 | | |
68 | 72 | | |
69 | 73 | | |
70 | | - | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
71 | 79 | | |
72 | 80 | | |
73 | 81 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
10 | 11 | | |
| 12 | + | |
11 | 13 | | |
12 | 14 | | |
13 | 15 | | |
| |||
22 | 24 | | |
23 | 25 | | |
24 | 26 | | |
25 | | - | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
26 | 39 | | |
27 | | - | |
28 | | - | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
29 | 50 | | |
30 | 51 | | |
31 | 52 | | |
| |||
61 | 82 | | |
62 | 83 | | |
63 | 84 | | |
64 | | - | |
65 | | - | |
66 | | - | |
67 | 85 | | |
68 | 86 | | |
69 | 87 | | |
| |||
183 | 201 | | |
184 | 202 | | |
185 | 203 | | |
186 | | - | |
187 | | - | |
188 | | - | |
| 204 | + | |
189 | 205 | | |
190 | 206 | | |
191 | 207 | | |
| |||
230 | 246 | | |
231 | 247 | | |
232 | 248 | | |
233 | | - | |
234 | | - | |
235 | | - | |
| 249 | + | |
236 | 250 | | |
237 | 251 | | |
238 | 252 | | |
| |||
275 | 289 | | |
276 | 290 | | |
277 | 291 | | |
278 | | - | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
279 | 298 | | |
280 | 299 | | |
281 | 300 | | |
| |||
313 | 332 | | |
314 | 333 | | |
315 | 334 | | |
316 | | - | |
317 | | - | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
318 | 339 | | |
319 | 340 | | |
320 | 341 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
| |||
45 | 46 | | |
46 | 47 | | |
47 | 48 | | |
48 | | - | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
49 | 55 | | |
50 | | - | |
51 | | - | |
52 | | - | |
53 | | - | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
54 | 59 | | |
55 | 60 | | |
56 | | - | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
57 | 66 | | |
58 | 67 | | |
59 | 68 | | |
| |||
430 | 439 | | |
431 | 440 | | |
432 | 441 | | |
433 | | - | |
| 442 | + | |
434 | 443 | | |
435 | 444 | | |
436 | 445 | | |
| |||
504 | 513 | | |
505 | 514 | | |
506 | 515 | | |
507 | | - | |
508 | 516 | | |
509 | 517 | | |
510 | 518 | | |
| |||
514 | 522 | | |
515 | 523 | | |
516 | 524 | | |
| 525 | + | |
| 526 | + | |
517 | 527 | | |
518 | 528 | | |
519 | 529 | | |
| |||
568 | 578 | | |
569 | 579 | | |
570 | 580 | | |
571 | | - | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
572 | 588 | | |
573 | 589 | | |
574 | 590 | | |
| |||
585 | 601 | | |
586 | 602 | | |
587 | 603 | | |
588 | | - | |
589 | | - | |
| 604 | + | |
590 | 605 | | |
591 | 606 | | |
592 | 607 | | |
| |||
0 commit comments