Persistent p_session_token Cookie Ignores cookie_max_age directive, Allowing Browser URL auto fill to Bypass login page #1114

Closed
opened 2026-04-05 18:19:18 +02:00 by MrUnknownDE · 0 comments
Owner

Originally created by @ZethKruel on 8/5/2025

Persistent p_session_token Cookie Ignores cookie_max_age, Allowing Auto-Fill Bypass login page

Describe the Bug:

The p_session_token cookie has a month-long Expires/Max-Age (e.g., ), ignoring the auth.cookie_max_age: 1800 setting in config.yml. This allows browsers (Firefox v141.1.0, Chrome latest) to auto-fill the dashboard URL (https://.) and access it without prompting for a login, even after hours of inactivity, posing a significant security risk.

To Reproduce

Configure config.yml with:

auth:
session_timeout: 30 # Minutes until session expires
cookie_secure: true # Cookies only sent over HTTPS
cookie_http_only: true # Prevents JavaScript access to cookies
cookie_max_age: 1800 # Seconds for cookie expiration (30 minutes)
cookie_samesite: "Strict" # Added to test stricter cookie policy

Log in to the dashboard at https://. with a valid user (e.g., @).
Check the p_session_token cookie in browser developer tools (F12 > Storage > Cookies):
Observed: Expires/Max-Age set to ~1 month (e.g., ), not 1800 seconds.
Other attributes: HttpOnly: true, SameSite: Lax, Secure: true.

Close and reopen the browser, use URL auto-fill to visit the dashboard.
Result: Dashboard loads without a login prompt, using the persistent cookie.

Expected Behavior

The p_session_token cookie should have Max-Age: 1800 (30 minutes) as per cookie_max_age.
Browser auto-fill should trigger a login prompt if the session has expired (after 30 minutes of inactivity, per session_timeout: 30).
cookie_samesite: "Strict" should enforce stricter cookie usage, preventing cross-site access.

Environment

Pangolin Version: 1.8.0
Badger Version: 1.2.0 (Traefik middleware, github.com/fosrl/badger@v1.2.0)
OS: Debian (VPS, IP: )
Browsers: Firefox v141.1.0 (Windows 10), Chrome latest (Windows 11)
Docker Compose: services:
pangolin:
image: docker.io/fosrl/pangolin:1.8.0
container_name: pangolin
restart: unless-stopped
volumes:
- ./config:/app/config
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3001/api/v1/"]
interval: "10s"
timeout: "10s"
retries: 15
traefik:
image: docker.io/traefik:v3.4.1
container_name: traefik
restart: unless-stopped
network_mode: service:gerbil
depends_on:
pangolin:
condition: service_healthy
command:
- --configFile=/etc/traefik/traefik_config.yml
volumes:
- ./config/traefik:/etc/traefik:ro
- ./config/letsencrypt:/letsencrypt
- ./config/traefik/logs:/var/log/traefik

Traefik Config (traefik_config.yml):log:
level: "DEBUG"
format: "common"
maxSize: 100
maxBackups: 3
maxAge: 3
compress: true
filePath: "/var/log/traefik/traefik.log"

Logs

Traefik Logs (/root/config/traefik/logs/traefik.log, 2025-08-05T16:15:02Z to 16:17:39Z):
Shows routing to pangolin:3000 (API) and pangolin:3002 (dashboard) with WRR.
No HTTP request details (e.g., Set-Cookie or Cookie: p_session_token=...) due to missing accessLog.
Single 499 Client Closed Request error at 2025-08-05T16:17:37Z, likely unrelated.

Pangolin Logs (docker logs pangolin, up to 2025-08-05T16:15:02Z):
Only Newt/WebSocket activity (e.g., Establishing websocket connection, NEWT ID: ).
No authentication, session, or p_session_token details, despite log_level: "debug".

Additional Context

Adding cookie_samesite: "Strict" to auth in config.yml had no effect on Expires/Max-Age (still ~1 month).
I have searched and no GitHub issues or discussions (up to #1200, August 2025) report this specific problem.
There may be a possible bug or misconfiguation in Pangolin’s Node.js backend (e.g., express-session) or Badger middleware ignoring the cookie_max_age directive I added to config.ym.
Browser auto-fill (Firefox/Chrome) reuses the persistent cookie, bypassing the login prompt.
Workaround attempted: Clearing browser cookies/history forces a login, but auto-fill persists the issue.

Suggested Fix

Ensure cookie_max_age: 1800 is applied to p_session_token in the backend session handler.
Add SameSite: Strict to the cookie by default or respect cookie_samesite in config.yml.
Enhance debug logging to include session creation and cookie-setting events.

Conclusion:
I tried to be as clear as possible. Please let me know if someone put mushrooms in my coffee or if this is a
legitimate issue.

*Originally created by @ZethKruel on 8/5/2025* Persistent p_session_token Cookie Ignores cookie_max_age, Allowing Auto-Fill Bypass login page Describe the Bug: The p_session_token cookie has a month-long Expires/Max-Age (e.g., <future-date>), ignoring the auth.cookie_max_age: 1800 setting in config.yml. This allows browsers (Firefox v141.1.0, Chrome latest) to auto-fill the dashboard URL (https://<dashboard-subdomain>.<domain>) and access it without prompting for a login, even after hours of inactivity, posing a significant security risk. To Reproduce Configure config.yml with: auth: session_timeout: 30 # Minutes until session expires cookie_secure: true # Cookies only sent over HTTPS cookie_http_only: true # Prevents JavaScript access to cookies cookie_max_age: 1800 # Seconds for cookie expiration (30 minutes) cookie_samesite: "Strict" # Added to test stricter cookie policy Log in to the dashboard at https://<dashboard-subdomain>.<domain> with a valid user (e.g., <username>@<email-provider>). Check the p_session_token cookie in browser developer tools (F12 > Storage > Cookies): Observed: Expires/Max-Age set to ~1 month (e.g., <future-date>), not 1800 seconds. Other attributes: HttpOnly: true, SameSite: Lax, Secure: true. Close and reopen the browser, use URL auto-fill to visit the dashboard. Result: Dashboard loads without a login prompt, using the persistent cookie. Expected Behavior The p_session_token cookie should have Max-Age: 1800 (30 minutes) as per cookie_max_age. Browser auto-fill should trigger a login prompt if the session has expired (after 30 minutes of inactivity, per session_timeout: 30). cookie_samesite: "Strict" should enforce stricter cookie usage, preventing cross-site access. Environment Pangolin Version: 1.8.0 Badger Version: 1.2.0 (Traefik middleware, github.com/fosrl/badger@v1.2.0) OS: Debian (VPS, IP: <server-ip>) Browsers: Firefox v141.1.0 (Windows 10), Chrome latest (Windows 11) Docker Compose: services: pangolin: image: docker.io/fosrl/pangolin:1.8.0 container_name: pangolin restart: unless-stopped volumes: - ./config:/app/config healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3001/api/v1/"] interval: "10s" timeout: "10s" retries: 15 traefik: image: docker.io/traefik:v3.4.1 container_name: traefik restart: unless-stopped network_mode: service:gerbil depends_on: pangolin: condition: service_healthy command: - --configFile=/etc/traefik/traefik_config.yml volumes: - ./config/traefik:/etc/traefik:ro - ./config/letsencrypt:/letsencrypt - ./config/traefik/logs:/var/log/traefik Traefik Config (traefik_config.yml):log: level: "DEBUG" format: "common" maxSize: 100 maxBackups: 3 maxAge: 3 compress: true filePath: "/var/log/traefik/traefik.log" Logs Traefik Logs (/root/config/traefik/logs/traefik.log, 2025-08-05T16:15:02Z to 16:17:39Z): Shows routing to pangolin:3000 (API) and pangolin:3002 (dashboard) with WRR. No HTTP request details (e.g., Set-Cookie or Cookie: p_session_token=...) due to missing accessLog. Single 499 Client Closed Request error at 2025-08-05T16:17:37Z, likely unrelated. Pangolin Logs (docker logs pangolin, up to 2025-08-05T16:15:02Z): Only Newt/WebSocket activity (e.g., Establishing websocket connection, NEWT ID: <newt-id>). No authentication, session, or p_session_token details, despite log_level: "debug". Additional Context Adding cookie_samesite: "Strict" to auth in config.yml had no effect on Expires/Max-Age (still ~1 month). I have searched and no GitHub issues or discussions (up to #1200, August 2025) report this specific problem. There may be a possible bug or misconfiguation in Pangolin’s Node.js backend (e.g., express-session) or Badger middleware ignoring the cookie_max_age directive I added to config.ym. Browser auto-fill (Firefox/Chrome) reuses the persistent cookie, bypassing the login prompt. Workaround attempted: Clearing browser cookies/history forces a login, but auto-fill persists the issue. Suggested Fix Ensure cookie_max_age: 1800 is applied to p_session_token in the backend session handler. Add SameSite: Strict to the cookie by default or respect cookie_samesite in config.yml. Enhance debug logging to include session creation and cookie-setting events. Conclusion: I tried to be as clear as possible. Please let me know if someone put mushrooms in my coffee or if this is a legitimate issue.
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github/pangolin#1114