Skip to content

fix(saml): validate SITE_URL before constructing SAML callback URL#5383

Closed
devin-ai-integration[bot] wants to merge 2 commits intomainfrom
devin/1770325113-fix-saml-callback-url-validation
Closed

fix(saml): validate SITE_URL before constructing SAML callback URL#5383
devin-ai-integration[bot] wants to merge 2 commits intomainfrom
devin/1770325113-fix-saml-callback-url-validation

Conversation

@devin-ai-integration
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot commented Feb 5, 2026

Context

When SITE_URL is not configured (it is optional in the env schema), the SAML AssertionConsumerServiceURL is constructed as "undefined/api/v1/sso/saml2/<id>" via a JS template literal with an undefined value. This is not a valid URI, causing Azure AD / Entra ID to reject the SAML AuthnRequest with:

AADSTS7500511: XML attribute 'AssertionConsumerServiceURL' in the SAML message must be a URI.

This is particularly likely to happen with self-hosted omnibus installations where the config key is PUBLIC_URL but the backend reads SITE_URL.

This PR adds explicit guards before constructing the SAML config:

  1. Checks that SITE_URL is defined (not empty/undefined)
  2. Validates that SITE_URL is a proper absolute http(s) URL via new URL() parsing and protocol check

The audience fallback (|| "") is also removed since it's now redundant after the guards.

Reported by a customer running v0.158.0 with an Entra ID SAML SSO + HAProxy/Nginx setup.

Updates since last revision

  • Added URL format validation (via new URL() + protocol check) in addition to the empty check, so malformed values like example.com or ftp://host are also caught with a clear error message. This addresses the Greptile review feedback.

Steps to verify the change

  1. In a local dev environment, unset the SITE_URL env var.
  2. Attempt to initiate a SAML SSO login.
  3. Confirm the error message now clearly states that SITE_URL must be configured, rather than producing a cryptic IdP error.
  4. Set SITE_URL to a non-URL value (e.g. example.com) and verify the format validation error is returned.

Type

  • Fix
  • Feature
  • Improvement
  • Breaking
  • Docs
  • Chore

Checklist

Review pointers

  • Main risk: This fix assumes the root cause is SITE_URL being undefined or malformed. If the customer's omnibus package does properly map PUBLIC_URLSITE_URL, then these guards won't trigger and the issue may lie elsewhere (e.g., URL encoding, proxy behavior). However, the guards are still correct defensive coding regardless.
  • Verify that removing || "" from audience is safe — it is, because the !appCfg.SITE_URL guard above guarantees it's defined at that point.
  • The parameterless catch block is intentional — both new URL() parse failures and the explicit protocol-check error should produce the same user-facing message.
  • Other SITE_URL usages in this file (redirect URLs at lines ~300, 304) are in the POST callback handler, which only executes after a successful SAML round-trip — if the callback URL was valid enough for the IdP to respond, SITE_URL must be set. So no additional guards are needed there.

Link to Devin run: https://app.devin.ai/sessions/02bf2a7f3b9344f08974ca4100c617f9
Requested by: @0xArshdeep

When SITE_URL is not configured, the SAML AssertionConsumerServiceURL
becomes 'undefined/api/v1/sso/saml2/<id>' which is not a valid URI.
Azure AD/Entra ID rejects this with AADSTS7500511.

Add explicit validation to throw a clear error message instead of
silently producing an invalid URL.

Co-Authored-By: arsh@infisical.com <arshsb1998@gmail.com>
@devin-ai-integration
Copy link
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@maidul98
Copy link
Collaborator

maidul98 commented Feb 5, 2026

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 5, 2026

Greptile Overview

Greptile Summary

This PR hard-fails SAML option generation when SITE_URL is missing, preventing construction of invalid AssertionConsumerServiceURL/audience values like undefined/api/v1/... that cause IdP-side rejection (notably Azure AD/Entra ID). The change is localized to the SAML router’s MultiSamlStrategy.getSamlOptions and replaces the prior audience: appCfg.SITE_URL || "" fallback with an explicit config guard and audience: appCfg.SITE_URL.

Confidence Score: 4/5

  • This PR is likely safe to merge and improves failure-mode clarity, with a small remaining risk around accepting malformed SITE_URL values.
  • Change is minimal and correctly prevents the known undefined-template-literal bug, but it still permits non-URL SITE_URL strings that will continue to generate invalid SAML URLs and user-facing IdP errors.
  • backend/src/ee/routes/v1/saml-router.ts

Important Files Changed

Filename Overview
backend/src/ee/routes/v1/saml-router.ts Adds a BadRequest guard when SITE_URL is unset before building SAML callbackUrl/audience; removes audience fallback.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 file reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines 74 to 78
if (!appCfg.SITE_URL) {
throw new BadRequestError({
message:
"SITE_URL environment variable is not configured. SAML SSO requires SITE_URL to be set to your Infisical instance URL."
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing URL format validation

The new guard only checks that SITE_URL is non-empty, but callbackUrl/audience still become invalid URIs if SITE_URL is set to a non-absolute value (e.g. example.com, localhost:8080, trailing whitespace) which will continue to trigger IdP errors. Consider validating it’s a proper absolute http(s) URL (e.g. via new URL(appCfg.SITE_URL) and protocol check) and throw the same clear error if parsing fails.

Co-Authored-By: arsh@infisical.com <arshsb1998@gmail.com>
@devin-ai-integration
Copy link
Contributor Author

Closing due to inactivity for more than 7 days. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant