Skip to content

Bind JWTs to server-issued sessions and require a production signing key - #920

Open
28Hus wants to merge 2 commits into
elunez:masterfrom
28Hus:fix/bind-jwt-to-online-session
Open

28Hus wants to merge 2 commits into
elunez:masterfrom
28Hus:fix/bind-jwt-to-online-session

Conversation

@28Hus

@28Hus 28Hus commented Oct 18, 2026

Copy link
Copy Markdown

Fixes #912.

This change addresses the identity-binding issue reported in #912 and removes the shared production JWT signing key.

Previously, the authentication filter only checked whether the Redis session identified by the JWT's sub and uid existed. A re-signed token could retain those values while changing userId, which downstream code used for authorization decisions.

Changes

  • Require the presented JWT to match the original token already stored in the Redis online-session record before renewing the session or establishing authentication.
  • Reject authentication when the stored token is missing, inconsistent, or cannot be checked.
  • Replace the fixed production signing key with ${JWT_BASE64_SECRET:}.
  • Keep the existing development default only in the dev configuration, with an environment-variable override.
  • Reject initialization when the configured key is missing, blank, invalid Base64, or decodes to fewer than 64 bytes, as required for HS512.
  • Document configuration and upgrade requirements.

The session check reuses the existing encrypted-token field. No Redis schema changes, controller changes, or authentication architecture redesign are required.

Configuration and Upgrade

Before starting with the prod profile, generate and securely retain a deployment-specific key:

export JWT_BASE64_SECRET="$(openssl rand -base64 64 | tr -d '\n')"

Pass this variable explicitly into containers and reuse the same key across restarts and replicas. Replacing the previous signing key invalidates existing tokens, so users must log in again.

Development startup remains unchanged. The development default must not be used for production deployments.

Local Validation

  • Confirmed that the original filter accepts a re-signed token with a modified userId and an otherwise valid session reference; the patched filter rejects it.
  • Passed 11 lightweight session-binding scenarios, including legitimate tokens, modified identity/session claims, missing or inconsistent stored tokens, and logged-out sessions.
  • Passed 11 configuration checks covering development defaults, environment overrides, missing/blank keys, invalid Base64, and decoded key-length boundaries.
  • Completed targeted compilation with Java 8 target bytecode and passed git diff --check.

Session checks exercised the actual filter and TokenProvider, with Redis and online-session services mocked. Configuration checks loaded the actual profile YAML files. No repository test files were added, and no database or full application environment was started.

The full offline Maven build was blocked by uncached Freemarker dependencies; it is not claimed as passing.

This contribution is part of my ongoing authentication-security research. I'm glad to help improve ELADMIN's security and welcome your feedback.

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.

[Security] JWT userId 未与 Redis 在线会话绑定,导致跨用户身份混淆与条件性垂直越权

1 participant