Skip to content

fix(security): credential-set invite email check + shopify authorize XSS#4302

Merged
waleedlatif1 merged 1 commit intostagingfrom
waleedlatif1/hex-findings
Apr 27, 2026
Merged

fix(security): credential-set invite email check + shopify authorize XSS#4302
waleedlatif1 merged 1 commit intostagingfrom
waleedlatif1/hex-findings

Conversation

@waleedlatif1
Copy link
Copy Markdown
Collaborator

Summary

  • credential-set invite accept now verifies the session user's email matches the invitation email (uses normalizeEmail from the org-invite path); open invites with no bound email still work
  • shopify authorize page reflects returnUrl via JSON.stringify after isSameOrigin validation, replacing the unsafe '${encodeURIComponent(returnUrl)}' JS-string interpolation that left ' unescaped

Type of Change

  • Bug fix

Testing

Tested manually

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 27, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Apr 27, 2026 3:43am

Request Review

@cursor
Copy link
Copy Markdown

cursor Bot commented Apr 27, 2026

PR Summary

Medium Risk
Tightens security checks in OAuth initiation and invitation acceptance; small, localized changes but they affect auth-related flows and could block legitimate users if validation is too strict.

Overview
Hardens the Shopify OAuth authorize bootstrap page by only reflecting returnUrl when it passes isSameOrigin, and by embedding it into the inline script via JSON.stringify to avoid JavaScript string injection.

Locks down credential-set invite acceptance by requiring the authenticated user’s email (normalized via normalizeEmail) to match the invitation’s bound email when present, returning 403 on mismatch while keeping email-less/open invites working.

Reviewed by Cursor Bugbot for commit 33fac4b. Configure here.

@waleedlatif1 waleedlatif1 force-pushed the waleedlatif1/hex-findings branch from 3f3abf5 to 33fac4b Compare April 27, 2026 03:43
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 27, 2026

Greptile Summary

This PR fixes two security vulnerabilities: a reflected XSS in the Shopify authorize page (via unsafe JS string interpolation of returnUrl) and a missing email authorization check in the credential-set invite acceptance flow. Both fixes are targeted and consistent with existing patterns in the codebase.

Confidence Score: 5/5

Both security fixes are well-implemented and consistent with existing codebase patterns; no new issues introduced.

No P0 or P1 findings. Both changes are tightly scoped, use existing helpers (isSameOrigin, normalizeEmail), and the logic is straightforward to verify. The XSS fix correctly uses JSON.stringify after origin validation, and the email-match check handles the open-invite case correctly.

No files require special attention.

Important Files Changed

Filename Overview
apps/sim/app/api/auth/shopify/authorize/route.ts XSS fix: replaces unsafe template-literal string interpolation with JSON.stringify after isSameOrigin validation; consistent with the existing isSameOrigin guard on the OAuth cookie path.
apps/sim/app/api/credential-sets/invite/[token]/route.ts Authorization fix: adds email-match check before accepting an invite, reusing the existing normalizeEmail helper; open (no-email) invites are correctly left unrestricted.

Sequence Diagram

sequenceDiagram
    participant Browser
    participant ShopifyRoute as Shopify Authorize Route
    participant CredRoute as Credential Set Invite Route

    Note over ShopifyRoute: XSS fix
    Browser->>ShopifyRoute: GET with returnUrl param
    ShopifyRoute->>ShopifyRoute: isSameOrigin check
    alt same origin
        ShopifyRoute->>ShopifyRoute: JSON.stringify after encodeURIComponent
        ShopifyRoute-->>Browser: HTML with safely quoted JS literal
    else different origin or no returnUrl
        ShopifyRoute-->>Browser: HTML with empty string literal
    end

    Note over CredRoute: Email authorization fix
    Browser->>CredRoute: POST accept invite token
    CredRoute->>CredRoute: invitation has email?
    alt email bound
        CredRoute->>CredRoute: normalizeEmail comparison
        alt emails match
            CredRoute-->>Browser: 200 accepted
        else mismatch
            CredRoute-->>Browser: 403 forbidden
        end
    else open invite
        CredRoute-->>Browser: 200 accepted
    end
Loading

Reviews (2): Last reviewed commit: "fix(security): credential-set invite ema..." | Re-trigger Greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 33fac4b. Configure here.

@waleedlatif1 waleedlatif1 merged commit 60652e6 into staging Apr 27, 2026
14 checks passed
@waleedlatif1 waleedlatif1 deleted the waleedlatif1/hex-findings branch April 27, 2026 03:52
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