Skip to content

fix: accept only Prividium sessions issued to the explorer on login and the REST API - #673

Merged
mikhail-egorov merged 7 commits into
mainfrom
me-priv-423-block-explorer-accepts-prividium-sessions-issued-to-other
Oct 9, 2026
Merged

mikhail-egorov merged 7 commits into
mainfrom
me-priv-423-block-explorer-accepts-prividium-sessions-issued-to-other

Conversation

@mikhail-egorov

@mikhail-egorov mikhail-egorov commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

What ❔

Reject Prividium user sessions issued to another application at explorer login, on the REST bearer path, and behind existing explorer cookies.

GET /api/auth/current-session must identify an account session (oauthClientId null or absent) or the explorer's own session (block-explorer). Other session types and audiences are rejected.

  • Login checks the profile before checking the audience, so junk tokens do not consume the permissions API's shared auth rate limit.
  • Successful login records audienceChecked: true in the signed cookie. Existing cookies receive this marker after their first successful audience check.
  • Cookie middleware and the separate Swagger gate honor the marker across pod restarts and cache eviction. Foreign cookies receive 401 and are cleared before reaching data routes, including /rpc.
  • /auth/me continues to reflect the cookie without calling the permissions API.
  • REST bearer requests retain their live profile lookup. M2M requests using x-api-key do not call the session verifier.

Caching and availability. One shared verifier caches accepted and confirmed foreign-audience verdicts until session expiry, within a combined 10,000-entry limit. Concurrent requests for the same token share one upstream call. Repeated foreign-token logins also reuse the rejection. Accepted logins fetch fresh expiry; upstream 401/403 responses, throttling, and network/server failures remain uncached.

New logins, uncached bearer tokens, and unmarked legacy cookies still require available upstream auth capacity. Established, marked cookies do not depend on current-session for data requests.

Authorization. This caches only immutable session type and audience. Existing cookie expiry and live authorization checks remain in place. REST bearer requests, Swagger, and routes using AddUserRolesPipe check the live profile; /rpc relies on upstream RPC authorization. Cookie routes without a live lookup, such as /blocks, /stats, and the token list, can remain readable until cookie session expiry after upstream revocation. This matches their behavior before this PR.

Failure handling. A 429 or 5xx from current-session is an upstream failure: 500 on login and 502 in the middleware or Swagger gate. The frontend logs out only on 401/403 and preserves the cookie on transient failures.

Why ❔

The explorer previously accepted application-scoped sessions without comparing their OAuth client to its own. A token obtained through another application's "Login with Prividium" flow could therefore become an explorer cookie or access the indexed chain through the REST API.

The audience check closes that path. Cookie markers, profile-first login, and bounded verdict caching keep repeated invalid attempts from adding an auth-rate-limit dependency to established cookie sessions.

Compatibility and rollout

  • The audience check only takes effect with permissions API v1.309.0 or later. Earlier versions omit oauthClientId and give applications account sessions, so every user session passes this check, including tokens obtained through other applications. Upgrade those deployments for the fix to provide audience isolation.
  • Explorer login remains compatible with older permissions APIs. Documented SIWE account-token REST clients continue to work.
  • Application-scoped tokens issued to other clients are intentionally rejected. M2M API-key behavior is unchanged.

Evidence

  • API unit suite: 821 passed, including the coverage gate (98.81% lines, 95.19% branches, 100% functions).
  • API E2E: 185 passed. The initial local run exceeded the five-second setup timeout under system load; the rerun passed with --testTimeout=30000.
  • Prividium API E2E: 22 passed, including pre-fix foreign cookies on /rpc and cookie migration during upstream failure.
  • API TypeScript check, lint on changed files, formatting, and git diff --check passed.
  • The explorer's Nest auth module called a real local permissions API built from v1.309.0 source, backed by a disposable PostgreSQL database. No upstream fetch responses were mocked. A fixture account session was created with the real session service. A third-party application was registered through POST /api/applications; its server-generated client ID was k5PIekVFOcikkxxa. Explorer and third-party sessions were issued through /api/auth/application-session.
Real permissions API session Explorer POST /auth/login Cookie result
Account, oauthClientId: null 201 Audience marker set; upstream expiry preserved
Explorer, oauthClientId: "block-explorer" 201 Audience marker set; upstream expiry preserved
Registered third-party application, oauthClientId: "k5PIekVFOcikkxxa" 403 No explorer session issued

The real contract check covers backend login and session responses; it does not exercise browser OAuth redirects. Its test sessions were revoked afterwards. Normal admin-panel login receives an account session without an application audience, which the explorer intentionally accepts.

Checklist

  • PR title corresponds to the body of PR (we generate changelog entries from PRs).
  • Tests for the changes have been added / updated.
  • Documentation comments have been added / updated.

Comment thread packages/api/src/auth/explorerSession.ts Fixed
@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

API E2E Test Results

185 tests   185 ✅  9s ⏱️
 13 suites    0 💤
  1 files      0 ❌

Results for commit 6cb225d.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

API Prividium E2E Test Results

22 tests   22 ✅  4s ⏱️
 1 suites   0 💤
 1 files     0 ❌

Results for commit 6cb225d.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Unit Test Results

    4 files    288 suites   8m 30s ⏱️
2 505 tests 2 504 ✅ 1 💤 0 ❌
2 673 runs  2 672 ✅ 1 💤 0 ❌

Results for commit 6cb225d.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown

Visit the preview URL for this PR:
https://staging-scan-v2-zksyncos--pr-673-r2ev1bkn.web.app

Comment thread packages/api/src/auth/explorerSession.ts Dismissed
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown

Visit the preview URL for this PR:
https://staging-scan-v2-zksyncos--pr-673-r2ev1bkn.web.app

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown

Visit the preview URL for this PR:
https://staging-scan-v2-zksyncos--pr-673-r2ev1bkn.web.app

@mikhail-egorov
mikhail-egorov marked this pull request as ready for review October 8, 2026 13:21
@mikhail-egorov
mikhail-egorov requested a review from a team as a code owner October 8, 2026 13:21
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown

Visit the preview URL for this PR:
https://staging-scan-v2-zksyncos--pr-673-r2ev1bkn.web.app

@jodator jodator left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No blockers from me. The main ask is the new dependency of data routes on the permissions API auth rate limit, inline on auth.middleware.ts and explorerSession.ts. The rest are PR body claims, tests and nits.

Comment thread packages/api/src/middlewares/auth.middleware.ts
Comment thread packages/api/src/auth/explorerSession.ts Outdated
Comment thread packages/api/src/auth/auth.controller.ts
Comment thread packages/api/src/auth/explorerSession.ts
Comment thread packages/api/src/auth/explorerSession.ts
Comment thread packages/api/src/middlewares/auth.middleware.spec.ts
Comment thread packages/api/test/prividium-api.e2e-spec.ts
Comment thread packages/api/src/middlewares/auth.middleware.ts Outdated
Comment thread packages/api/src/middlewares/auth.middleware.ts Outdated
Comment thread packages/api/src/auth/explorerSession.ts Outdated
Record verified audiences in signed cookies, reject junk tokens before the auth lookup, and cache confirmed foreign audiences within the shared bound. Cover retries, cookie migration, M2M isolation, and foreign-cookie RPC rejection.
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown

Visit the preview URL for this PR:
https://staging-scan-v2-zksyncos--pr-673-r2ev1bkn.web.app

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown

Visit the preview URL for this PR:
https://staging-scan-v2-zksyncos--pr-673-r2ev1bkn.web.app

Comment thread packages/api/src/middlewares/auth.middleware.ts Outdated
Comment thread packages/api/src/auth/explorerSession.ts Outdated
@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown

Visit the preview URL for this PR:
https://staging-scan-v2-zksyncos--pr-673-r2ev1bkn.web.app

@jodator jodator left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks!

@mikhail-egorov
mikhail-egorov merged commit 94d6b34 into main Oct 9, 2026
24 checks passed
@mikhail-egorov
mikhail-egorov deleted the me-priv-423-block-explorer-accepts-prividium-sessions-issued-to-other branch October 9, 2026 09:08
@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown

🎉 This PR is included in version 3.32.2 🎉

The release is available on:

Your semantic-release bot 📦🚀

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants