Skip to content

[bug] Dashboard session cookie is issued without Secure #29

@d180

Description

@d180

What went wrong

POST /api/auth/login issues the adrian_token session cookie without the
Secure attribute.

Observed Set-Cookie header:

adrian_token=b7f877086debfca8627509e4efa7779df8eafe89181c69e16d5297fbfb28ca8d;
Path=/; Max-Age=86400; HttpOnly; SameSite=Lax

Because Secure is missing, the browser may send the authenticated session
cookie over plain HTTP if the application is reachable over HTTP or passes
through an insecure redirect path. This weakens transport protection for every
dashboard session and can enable session hijacking.

Code reference:
backend/internal/api/handlers_auth.go:160


Reproduction steps

  1. Start the backend locally.
  2. Send a login request:
curl -i -X POST http://localhost:8080/api/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"email":"admin@localhost","password":"<password>"}'
  1. Inspect the Set-Cookie response header.
  2. Observe that the adrian_token cookie is returned without the Secure
    attribute.

Expected behaviour

The session cookie should be issued with the Secure attribute so browsers only
send it over HTTPS.

Example:

Set-Cookie: adrian_token=...; Path=/; Max-Age=86400; HttpOnly; Secure; SameSite=Lax

Actual behaviour

The session cookie is issued without Secure:

Set-Cookie: adrian_token=...; Path=/; Max-Age=86400; HttpOnly; SameSite=Lax

Environment

  • Adrian version / commit:
  • OS: macOS arm64
  • Docker version: Docker version 29.4.3
  • GPU model (if relevant): N/A

Logs

Click to expand
HTTP/1.1 200 OK
Set-Cookie:
adrian_token=b7f877086debfca8627509e4efa7779df8eafe89181c69e16d5297fbfb28ca8d;
Path=/; Max-Age=86400; HttpOnly; SameSite=Lax
Content-Type: application/json
...

{"data":{"user_id":"032e9c0b-fee1-4aef-b3a0-8ed9486cd68e","email":"admin@localhost","name":"Administrator","role":"admin","must_change_password":false}}

Relevant code paths

  • backend/internal/api/handlers_auth.go:160
    setSessionCookie() creates the adrian_token cookie without Secure: true.

  • backend/internal/api/handlers_auth.go:171
    clearSessionCookie() also omits Secure: true. Clearing should usually mirror
    the same cookie attributes used when setting it.

  • backend/internal/api/routes.go:88
    POST /api/auth/login is the route that triggers session cookie issuance.

  • backend/internal/api/handlers_test.go:117
    Existing login test checks that the cookie exists, but not that it includes
    the Secure attribute.

  • backend/internal/api/middleware_session.go:16
    Confirms the affected session cookie name is adrian_token.


Likely fix

Set Secure: true when issuing and clearing the session cookie.

Example:

func setSessionCookie(w http.ResponseWriter, token string, ttl time.Duration) {
	http.SetCookie(w, &http.Cookie{
		Name:     sessionCookieName,
		Value:    token,
		Path:     "/",
		MaxAge:   int(ttl.Seconds()),
		HttpOnly: true,
		Secure:   true,
		SameSite: http.SameSiteLaxMode,
	})
}

func clearSessionCookie(w http.ResponseWriter) {
	http.SetCookie(w, &http.Cookie{
		Name:     sessionCookieName,
		Value:    "",
		Path:     "/",
		MaxAge:   -1,
		HttpOnly: true,
		Secure:   true,
		SameSite: http.SameSiteLaxMode,
	})
}

Offer to contribute

I’d be happy to work on a fix for this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions