Skip to content

Fix/3.0.4#672

Merged
afadil merged 15 commits intomainfrom
fix/3.0.4
Mar 5, 2026
Merged

Fix/3.0.4#672
afadil merged 15 commits intomainfrom
fix/3.0.4

Conversation

@afadil
Copy link
Owner

@afadil afadil commented Mar 5, 2026

Description

This pull request implements major security hardening for the web server’s authentication and session management, introduces cookie-based authentication, and updates both backend and frontend to support these changes. It also includes breaking changes to CORS and server startup behavior, several frontend bug fixes, and dependency updates. The most important changes are grouped below.

Security and Authentication Hardening:

  • CORS wildcard (*) is no longer allowed when authentication is enabled; WF_CORS_ALLOW_ORIGINS must be set to an explicit origin. The server will refuse to start on non-loopback addresses without authentication, unless WF_AUTH_REQUIRED=false is set. These changes are documented in RELEASE_NOTES.md and README.md. [1] [2] [3]
  • Introduces cookie-based authentication: after login, an HttpOnly; SameSite=Strict session cookie is set, enabling secure session persistence and removing the need for localStorage token storage. New endpoints /api/v1/auth/logout and /api/v1/auth/me are added.
  • Login endpoint is now rate-limited to 5 requests per 60 seconds per client IP using tower-governor.
  • Secrets encryption key derivation is changed: WF_SECRET_KEY is now split into two derived keys via HKDF-SHA256, with automatic migration for existing secrets.
  • OpenAPI schema is now served behind authentication at /api/v1/openapi.json.

Frontend Adaptation for Cookie-based Auth:

  • All frontend API requests now use credentials: "same-origin" to ensure cookies are sent with requests. [1] [2] [3] [4] [5] [6] [7]
  • SSE (EventSource) now authenticates using cookies (withCredentials: true), and query-param token passing is removed. [1] [2]
  • The frontend authentication context (AuthProvider) is updated to detect and manage cookie-based sessions, including proper logout and session expiration handling. [1] [2] [3]

Deprecations and Breaking Changes:

  • Removal of localStorage-based token persistence; tokens are now only kept in memory.
  • Docker and environment variable documentation updated to reflect new authentication and CORS requirements. [1] [2] [3]

Frontend Bug Fixes and Improvements:

  • AI chat model selection logic is improved to ensure the selected model is always among the provider’s favorites, preventing UI/backend mismatches. [1] [2]
  • Minor UI tweaks: chart axis width increased and line animation disabled for mobile performance chart. [1] [2]

Dependency and Integration Updates:

  • New dependencies: tower-governor for rate limiting, hkdf and sha2 for key derivation.
  • Wealthfolio Connect provider now checks authentication state to avoid unnecessary Supabase activity when not authenticated. [1] [2] [3]

These changes significantly improve the security posture of the application, modernize authentication flows, and ensure the frontend and backend remain in sync regarding authentication state and session management.

afadil and others added 10 commits March 5, 2026 09:30
- Enforce explicit CORS origins when authentication is enabled; wildcard '*' is rejected.
- Require authentication for non-loopback address binding unless explicitly opted out.
- Move OpenAPI schema behind authentication.
- Change secrets encryption key derivation to use HKDF-SHA256.
- Introduce cookie-based authentication with HttpOnly and SameSite attributes.
- Implement login rate limiting to 5 requests per 60 seconds per client IP.
- Update request logging to exclude query strings for security.
- Add new environment variable `WF_AUTH_REQUIRED` to control authentication requirements.
- Migrate existing secrets to the new encryption scheme automatically.
- Update frontend to support cookie-based authentication and adjust API calls accordingly.
- Add tests to verify new authentication and session management features.
…670)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a "Portfolio" filter to the securities list with "Current" and "Past"
options, defaulting to "Current" so only actively held assets are shown.
Ensure useChatModel resolves to a model visible in ModelPicker by
falling back to the first favorite when the default isn't in favorites.

Strip trailing /v1 from Ollama provider URL before passing to rig client
to prevent 405 errors from double-pathed requests.
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5636b70119

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


// Rate limit login: 5 requests per 60 seconds per peer IP
let login_governor = GovernorConfigBuilder::default()
.per_second(12) // replenish 1 token every 12s → 5 per 60s

Choose a reason for hiding this comment

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

P1 Badge Configure login rate limit to true 5-per-minute quota

The current governor config does not enforce the intended 5 requests / 60s limit: per_second(12) allows roughly 12 requests per second (plus the burst), so password attempts are effectively almost unthrottled. This materially weakens the new brute-force protection on /auth/login, especially on internet-facing deployments where this change is meant to harden authentication.

Useful? React with 👍 / 👎.

WF_AUTH_TOKEN_TTL_MINUTES: "${WF_AUTH_TOKEN_TTL_MINUTES:-60}"
WF_CORS_ALLOW_ORIGINS: "${WF_CORS_ALLOW_ORIGINS:-*}"
# Required when auth is enabled — set to your app's origin, e.g. https://wealthfolio.example.com
WF_CORS_ALLOW_ORIGINS: "${WF_CORS_ALLOW_ORIGINS}"

Choose a reason for hiding this comment

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

P2 Badge Add a safe default for WF_CORS_ALLOW_ORIGINS in Compose

Using ${WF_CORS_ALLOW_ORIGINS} without a default causes Docker Compose to pass an empty string when the variable is unset; in that case the server builds a CORS origin list containing "", and app_router later calls .parse().unwrap() on it, which panics at startup. This breaks the documented default behavior (*) and can crash even non-auth deployments unless operators manually set the variable every time.

Useful? React with 👍 / 👎.

@afadil afadil merged commit 551a5cb into main Mar 5, 2026
2 checks passed
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