* feat(saml): add ALLOW_PRIVATE_SAML_METADATA_URLS SSRF bypass
Introduce the ALLOW_PRIVATE_SAML_METADATA_URLS env var and its
allow_private_saml_metadata_urls() helper, mirroring the existing
ALLOW_PRIVATE_MCP_SERVER_URLS opt-out. This lets self-hosted deployments
with internal SAML IdPs (private IPs, no public DNS) skip the metadata-URL
SSRF check that otherwise blocks server startup.
The companion EE change (saml_ee.rs) consumes the helper to gate the
validate_url_for_ssrf() call and additionally treats a cleared
(empty/whitespace-only) SAML_METADATA setting as no SAML configured.
Fixes WIN-2169
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(saml): surface opt-in hint and record SSRF control in threat model
Add saml_ssrf_error_message() so private-IdP metadata URL rejections point
to ALLOW_PRIVATE_SAML_METADATA_URLS (mirroring the MCP helper), with a unit
test. Record the new SSRF opt-in under T2 in THREAT_MODEL.md, and bump the
EE ref for the companion saml_ee.rs change.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(saml): add validate_saml_metadata_url with opt-in unit tests
Factor the SAML metadata SSRF gating into validate_saml_metadata_url()
(mirroring validate_mcp_server_url) so the private-URL opt-in branch is
unit-tested at the ssrf layer: blocks private by default, allows on
true/1, and keeps scheme/host syntax guards when the opt-in is on. Bump
the EE ref for the companion saml_ee.rs change.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* chore: update ee-repo-ref to 394ad23242de429aef4074cc1dc28867dac95870
This commit updates the EE repository reference after PR #659 was merged in windmill-ee-private.
Previous ee-repo-ref: 86da208c5aef2570568e18c7ab98f4d58adeec18
New ee-repo-ref: 394ad23242de429aef4074cc1dc28867dac95870
Automated by sync-ee-ref workflow.
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
The /ws_debug debugger WebSocket gated JWT signature verification on inline
`code` being present (`if (code && REQUIRE_SIGNED_REQUESTS)`), so a
`program`-mode launch (naming an arbitrary server-side file path that is read
and executed) skipped verification entirely — even with
REQUIRE_SIGNED_DEBUG_REQUESTS=true. The WS handshake also performed no Origin
check, allowing cross-origin (CSWSH) drive-by from a malicious page.
- Enforce signing on every launch in both handlers (Python + Bun/TS): reject
program-mode outright and require+verify a token for inline code.
- Add opt-in DEBUG_ALLOWED_ORIGINS allowlist enforced at the WS handshake.
- Default docker-compose REQUIRE_SIGNED_DEBUG_REQUESTS to true.
- Update THREAT_MODEL T8/EP15 to reflect the root cause and mitigation.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix: validate websocket trigger urls and gate trigger test route
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs: clarify validate_websocket_url_for_ssrf call sites
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>