Skip to content

fix(gitlab): pin pagination cursor to configured host + consolidate isSameOrigin#4873

Merged
waleedlatif1 merged 2 commits into
stagingfrom
waleedlatif1/gitlab-cursor-origin-check
Jun 3, 2026
Merged

fix(gitlab): pin pagination cursor to configured host + consolidate isSameOrigin#4873
waleedlatif1 merged 2 commits into
stagingfrom
waleedlatif1/gitlab-cursor-origin-check

Conversation

@waleedlatif1
Copy link
Copy Markdown
Collaborator

Summary

  • The GitLab repository-tree keyset cursor stored GitLab's verbatim rel="next" URL and re-fetched it with an Authorization: Bearer header. A tampered or corrupted fileNextUrl could have leaked the access token to an attacker-controlled host. The connector now asserts the cursor's origin matches the configured apiBase before following it, failing closed on mismatch.
  • Generalized the shared isSameOrigin util (lib/core/utils/validation.ts) to accept an optional base origin (defaults to the app base URL, so existing callers are unchanged).
  • Replaced the GitLab connector's local origin helper and refactored the tools self-origin check to consume the shared util instead of duplicating URL-parsing.

Type of Change

  • Bug fix

Testing

Tested manually. bun run lint and the API-validation contract check both pass.

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)

waleedlatif1 and others added 2 commits June 3, 2026 14:13
…g it

The repository-tree keyset cursor stores GitLab's verbatim rel="next"
URL and re-fetches it with an Authorization: Bearer header. Assert the
cursor's origin matches the configured apiBase before following it, so a
tampered or corrupted fileNextUrl cannot exfiltrate the access token to
an attacker-controlled host. Fails closed on mismatch.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…nectors/tools

Add an optional base argument to the shared isSameOrigin (defaulting to
the app base URL) so callers can pin a URL to any trusted origin. The
GitLab connector's cursor host-check and the tools self-origin check now
consume the shared helper instead of their own URL-parsing.
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 3, 2026

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jun 3, 2026 9:22pm

Request Review

@cursor
Copy link
Copy Markdown

cursor Bot commented Jun 3, 2026

PR Summary

Low Risk
Targeted security hardening and a backward-compatible util signature; behavior for existing single-argument isSameOrigin callers is unchanged.

Overview
Hardens GitLab repo-tree pagination by verifying a stored keyset fileNextUrl matches the configured API host (apiBase) before refetching it with the PAT—fails closed if the cursor points elsewhere, closing a path where a tampered cursor could send credentials off-host.

Extends shared isSameOrigin with an optional base origin (default unchanged for redirect checks) and reuses it in the tools layer for self-origin detection instead of duplicating URL parsing.

Reviewed by Cursor Bugbot for commit 6c7e41a. Configure here.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Jun 3, 2026

Greptile Summary

This PR closes an SSRF-adjacent token-leak vector: the GitLab connector was using the verbatim rel="next" URL from the Link header as a resumption cursor, and would re-fetch it with a live Authorization: Bearer header without first asserting the cursor's origin hadn't drifted to a foreign host. The fix adds a single guard that validates the stored fileNextUrl against the configured apiBase origin before the request is issued, and re-uses the shared isSameOrigin util (now generalized with an optional base argument) rather than duplicating URL-parsing logic.

  • validation.ts: isSameOrigin gains an optional base parameter (defaults to getBaseUrl()); all existing one-argument call-sites are unchanged.
  • gitlab.ts: Origin-check guard is inserted before the cursor is consumed; throws with a descriptive error on mismatch, failing closed.
  • tools/index.ts: isSelfOriginUrl is collapsed from an 11-line try/catch to a one-liner using isSameOrigin; behavior is identical.

Confidence Score: 5/5

Safe to merge; the changes are a targeted security hardening of the GitLab connector's pagination path with no regressions introduced.

All three files contain well-scoped, correct changes. The origin guard in gitlab.ts is placed correctly — before the cursor is consumed, short-circuits on falsy values, and fails closed on mismatch. The isSameOrigin generalization is backward-compatible and the isSelfOriginUrl refactor in tools/index.ts is semantically equivalent to the original.

No files require special attention.

Important Files Changed

Filename Overview
apps/sim/lib/core/utils/validation.ts Generalized isSameOrigin to accept an optional base parameter (default: getBaseUrl()), fully backward-compatible; change is clean and correct.
apps/sim/connectors/gitlab/gitlab.ts Adds an origin validation guard on state.fileNextUrl before following it with credentials; check fires only when the cursor is present and correctly pins against apiBase derived from the configured host.
apps/sim/tools/index.ts Refactored isSelfOriginUrl to delegate to the shared isSameOrigin util; behavior is semantically equivalent to the original try/catch implementation.

Sequence Diagram

sequenceDiagram
    participant Caller
    participant GitLabConnector
    participant isSameOrigin
    participant GitLabAPI

    Caller->>GitLabConnector: listDocuments(cursor)
    GitLabConnector->>GitLabConnector: decodeCursor(cursor) → state.fileNextUrl
    alt state.fileNextUrl is set
        GitLabConnector->>isSameOrigin: isSameOrigin(fileNextUrl, apiBase)
        isSameOrigin-->>GitLabConnector: true / false
        alt origin mismatch
            GitLabConnector-->>Caller: throw Error("unexpected host")
        end
    end
    GitLabConnector->>GitLabAPI: GET fileNextUrl ?? defaultUrl (+ Authorization header)
    GitLabAPI-->>GitLabConnector: "200 OK + Link: rel="next""
    GitLabConnector->>GitLabConnector: parseNextLink() → nextLink
    GitLabConnector->>GitLabConnector: "encodeCursor({ fileNextUrl: nextLink })"
    GitLabConnector-->>Caller: "{ documents, nextCursor, hasMore }"
Loading

Reviews (1): Last reviewed commit: "improvement(validation): generalize isSa..." | Re-trigger Greptile

@waleedlatif1 waleedlatif1 merged commit 80d966d into staging Jun 3, 2026
14 checks passed
@waleedlatif1 waleedlatif1 deleted the waleedlatif1/gitlab-cursor-origin-check branch June 3, 2026 21:42
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