Login fails when BASE_PATH set #7199

Closed
opened 2025-12-29 20:20:22 +01:00 by adam · 5 comments
Owner

Originally created by @candlerb on GitHub (Nov 4, 2022).

Originally assigned to: @candlerb on GitHub.

NetBox version

v3.3.7

Python version

3.8

Steps to Reproduce

  1. Install netbox v3.3.7 with BASE_PATH = 'netbox/'. Adjust Apache config accordingly.
  2. Try to login with the local admin login.

Expected Behavior

Should be able to login normally.

Observed Behavior

First time you click on the Log In button: you get the login page, and then you are returned to the front screen with a pop-up saying "Logged in as admin". However at this point you are still logged out, and the top-right button shows "Log In" rather than your username. Subsequent clicks of this button just refresh the screen, but you are still logged out.

Tested with Chrome and Firefox: identical behaviour.

This worked with v3.3.5 but doesn't work with v3.3.7. I haven't determined exactly where it changed, but I have reproduced this on two independent systems. This broke in v3.3.6.

Originally created by @candlerb on GitHub (Nov 4, 2022). Originally assigned to: @candlerb on GitHub. ### NetBox version v3.3.7 ### Python version 3.8 ### Steps to Reproduce 1. Install netbox v3.3.7 with `BASE_PATH = 'netbox/'`. Adjust Apache config accordingly. 2. Try to login with the local admin login. ### Expected Behavior Should be able to login normally. ### Observed Behavior First time you click on the Log In button: you get the login page, and then you are returned to the front screen with a pop-up saying "Logged in as admin". However at this point you are still logged out, and the top-right button shows "Log In" rather than your username. Subsequent clicks of this button just refresh the screen, but you are still logged out. Tested with Chrome and Firefox: identical behaviour. This worked with v3.3.5 but doesn't work with v3.3.7. ~~I haven't determined exactly where it changed, but I have reproduced this on two independent systems.~~ This broke in v3.3.6.
adam added the type: bugstatus: accepted labels 2025-12-29 20:20:22 +01:00
adam closed this issue 2025-12-29 20:20:22 +01:00
Author
Owner

@candlerb commented on GitHub (Nov 4, 2022):

Checking developer console in an incognito window, I see the following response headers from the POST to login:

Set-Cookie: messages=W1siX19qc29uX21lc3NhZ2UiLDAsMjAsIkxvZ2dlZCBpbiBhcyBhZG1pbi4iXV0:1oqtqD:9oVpEum9r9ZDaB9A_vkK3hbgV6suhYzoncjEkFpxnBs; HttpOnly; Path=/; SameSite=Lax
Set-Cookie: csrftoken=KAxIwSj0Q6pxZU5hiKoEIGQ8E28FxEnwMJfzwaI5fG6HMyUiZvFjRGIf7y7vSs5X; expires=Fri, 03 Nov 2023 10:22:25 GMT; Max-Age=31449600; Path=netbox/; SameSite=Lax
Set-Cookie: sessionid=2ia9xis4xhgacqmenrztngc2hellcpk8; expires=Fri, 18 Nov 2022 10:22:25 GMT; HttpOnly; Max-Age=1209600; Path=netbox/; SameSite=Lax

I note that the csrftoken and sessionid have path netbox/ when it should be /netbox. (messages should probably also be bound to /netbox, but that doesn't matter too much)

Logging into a VM which is running Netbox v3.2.9 (but also with BASE_PATH='netbox/'), I see:

Set-Cookie: messages=W1siX19qc29uX21lc3NhZ2UiLDAsMjAsIkxvZ2dlZCBpbiBhcyBhZG1pbi4iXV0:1oqu8F:XQFbD1uKnnuF2AwXhc-0KqMrkQEQZqT7EwuBvZKkWnM; HttpOnly; Path=/; SameSite=Lax
Set-Cookie: csrftoken=RkWeYCDonUnHTbMsx7zxTAEOCgM1yR6Xay2ogelFpIpeSipKgnsLlmkBctnYZOmz; expires=Fri, 03 Nov 2023 10:41:03 GMT; Max-Age=31449600; Path=/; SameSite=Lax
Set-Cookie: sessionid=ayx0qo9l4qtn1hsp56zvshvfglw0y2s5; expires=Fri, 18 Nov 2022 10:41:03 GMT; HttpOnly; Max-Age=1209600; Path=/; SameSite=Lax

That seems to confirm my theory.

Maybe this isn't a Netbox issue, but a Django one, since upgrading Netbox would also have rebuilt the virtualenv.

@candlerb commented on GitHub (Nov 4, 2022): Checking developer console in an incognito window, I see the following response headers from the POST to login: ``` Set-Cookie: messages=W1siX19qc29uX21lc3NhZ2UiLDAsMjAsIkxvZ2dlZCBpbiBhcyBhZG1pbi4iXV0:1oqtqD:9oVpEum9r9ZDaB9A_vkK3hbgV6suhYzoncjEkFpxnBs; HttpOnly; Path=/; SameSite=Lax Set-Cookie: csrftoken=KAxIwSj0Q6pxZU5hiKoEIGQ8E28FxEnwMJfzwaI5fG6HMyUiZvFjRGIf7y7vSs5X; expires=Fri, 03 Nov 2023 10:22:25 GMT; Max-Age=31449600; Path=netbox/; SameSite=Lax Set-Cookie: sessionid=2ia9xis4xhgacqmenrztngc2hellcpk8; expires=Fri, 18 Nov 2022 10:22:25 GMT; HttpOnly; Max-Age=1209600; Path=netbox/; SameSite=Lax ``` I note that the csrftoken and sessionid have path `netbox/` when it should be `/netbox`. (`messages` should probably also be bound to `/netbox`, but that doesn't matter too much) Logging into a VM which is running Netbox v3.2.9 (but also with `BASE_PATH='netbox/'`), I see: ``` Set-Cookie: messages=W1siX19qc29uX21lc3NhZ2UiLDAsMjAsIkxvZ2dlZCBpbiBhcyBhZG1pbi4iXV0:1oqu8F:XQFbD1uKnnuF2AwXhc-0KqMrkQEQZqT7EwuBvZKkWnM; HttpOnly; Path=/; SameSite=Lax Set-Cookie: csrftoken=RkWeYCDonUnHTbMsx7zxTAEOCgM1yR6Xay2ogelFpIpeSipKgnsLlmkBctnYZOmz; expires=Fri, 03 Nov 2023 10:41:03 GMT; Max-Age=31449600; Path=/; SameSite=Lax Set-Cookie: sessionid=ayx0qo9l4qtn1hsp56zvshvfglw0y2s5; expires=Fri, 18 Nov 2022 10:41:03 GMT; HttpOnly; Max-Age=1209600; Path=/; SameSite=Lax ``` That seems to confirm my theory. Maybe this isn't a Netbox issue, but a Django one, since upgrading Netbox would also have rebuilt the virtualenv.
Author
Owner

@candlerb commented on GitHub (Nov 4, 2022):

On my test VM, I wound it back from 3.3.7 to 3.3.5, and I find that login is successful again (and the cookies have Path=/)

I wound it forward to 3.3.6, and it stopped working (Path=netbox/). So the problem is somewhere between 3.3.5 and 3.3.6.

Aha: almost certainly it's this from the 3.3.6 release notes:

  • #10639 - Set cookie paths according to configured BASE_PATH

... which in turn came from PR #10706

@candlerb commented on GitHub (Nov 4, 2022): On my test VM, I wound it back from 3.3.7 to 3.3.5, and I find that login is successful again (and the cookies have `Path=/`) I wound it forward to 3.3.6, and it stopped working (`Path=netbox/`). So the problem is somewhere between 3.3.5 and 3.3.6. Aha: almost certainly it's this from the [3.3.6 release notes](https://github.com/netbox-community/netbox/releases/tag/v3.3.6): > * [#10639](https://github.com/netbox-community/netbox/issues/10639) - Set cookie paths according to configured `BASE_PATH` ... which in turn came from PR #10706
Author
Owner

@candlerb commented on GitHub (Nov 4, 2022):

This is a quick-and-dirty patch that fixes it for me. I'll leave you to decide whether you want to DRY this.

--- netbox/netbox/settings.py.orig	2022-11-04 11:12:43.495829728 +0000
+++ netbox/netbox/settings.py	2022-11-04 11:19:23.526013549 +0000
@@ -85,7 +85,7 @@
 CORS_ORIGIN_REGEX_WHITELIST = getattr(configuration, 'CORS_ORIGIN_REGEX_WHITELIST', [])
 CORS_ORIGIN_WHITELIST = getattr(configuration, 'CORS_ORIGIN_WHITELIST', [])
 CSRF_COOKIE_NAME = getattr(configuration, 'CSRF_COOKIE_NAME', 'csrftoken')
-CSRF_COOKIE_PATH = BASE_PATH or '/'
+CSRF_COOKIE_PATH = '/' + BASE_PATH[:-1]
 CSRF_TRUSTED_ORIGINS = getattr(configuration, 'CSRF_TRUSTED_ORIGINS', [])
 DATE_FORMAT = getattr(configuration, 'DATE_FORMAT', 'N j, Y')
 DATETIME_FORMAT = getattr(configuration, 'DATETIME_FORMAT', 'N j, Y g:i a')
@@ -130,8 +130,8 @@
 SENTRY_TAGS = getattr(configuration, 'SENTRY_TAGS', {})
 SESSION_FILE_PATH = getattr(configuration, 'SESSION_FILE_PATH', None)
 SESSION_COOKIE_NAME = getattr(configuration, 'SESSION_COOKIE_NAME', 'sessionid')
-SESSION_COOKIE_PATH = BASE_PATH or '/'
-LANGUAGE_COOKIE_PATH = BASE_PATH or '/'
+SESSION_COOKIE_PATH = '/' + BASE_PATH[:-1]
+LANGUAGE_COOKIE_PATH = '/' + BASE_PATH[:-1]
 SHORT_DATE_FORMAT = getattr(configuration, 'SHORT_DATE_FORMAT', 'Y-m-d')
 SHORT_DATETIME_FORMAT = getattr(configuration, 'SHORT_DATETIME_FORMAT', 'Y-m-d H:i')
 SHORT_TIME_FORMAT = getattr(configuration, 'SHORT_TIME_FORMAT', 'H:i:s')
@candlerb commented on GitHub (Nov 4, 2022): This is a quick-and-dirty patch that fixes it for me. I'll leave you to decide whether you want to DRY this. ``` --- netbox/netbox/settings.py.orig 2022-11-04 11:12:43.495829728 +0000 +++ netbox/netbox/settings.py 2022-11-04 11:19:23.526013549 +0000 @@ -85,7 +85,7 @@ CORS_ORIGIN_REGEX_WHITELIST = getattr(configuration, 'CORS_ORIGIN_REGEX_WHITELIST', []) CORS_ORIGIN_WHITELIST = getattr(configuration, 'CORS_ORIGIN_WHITELIST', []) CSRF_COOKIE_NAME = getattr(configuration, 'CSRF_COOKIE_NAME', 'csrftoken') -CSRF_COOKIE_PATH = BASE_PATH or '/' +CSRF_COOKIE_PATH = '/' + BASE_PATH[:-1] CSRF_TRUSTED_ORIGINS = getattr(configuration, 'CSRF_TRUSTED_ORIGINS', []) DATE_FORMAT = getattr(configuration, 'DATE_FORMAT', 'N j, Y') DATETIME_FORMAT = getattr(configuration, 'DATETIME_FORMAT', 'N j, Y g:i a') @@ -130,8 +130,8 @@ SENTRY_TAGS = getattr(configuration, 'SENTRY_TAGS', {}) SESSION_FILE_PATH = getattr(configuration, 'SESSION_FILE_PATH', None) SESSION_COOKIE_NAME = getattr(configuration, 'SESSION_COOKIE_NAME', 'sessionid') -SESSION_COOKIE_PATH = BASE_PATH or '/' -LANGUAGE_COOKIE_PATH = BASE_PATH or '/' +SESSION_COOKIE_PATH = '/' + BASE_PATH[:-1] +LANGUAGE_COOKIE_PATH = '/' + BASE_PATH[:-1] SHORT_DATE_FORMAT = getattr(configuration, 'SHORT_DATE_FORMAT', 'Y-m-d') SHORT_DATETIME_FORMAT = getattr(configuration, 'SHORT_DATETIME_FORMAT', 'Y-m-d H:i') SHORT_TIME_FORMAT = getattr(configuration, 'SHORT_TIME_FORMAT', 'H:i:s') ```
Author
Owner

@jeremystretch commented on GitHub (Nov 4, 2022):

Thanks for tracking this down @candlerb!

@jeremystretch commented on GitHub (Nov 4, 2022): Thanks for tracking this down @candlerb!
Author
Owner

@prauscher commented on GitHub (Nov 5, 2022):

Thanks for pointing this out. In https://github.com/netbox-community/netbox/blob/develop/netbox/netbox/settings.py#L81 makes sure BASE_PATH always contains a trailing /. I'd suggest to use

SESSION_COOKIE_PATH = CSRF_COOKIE_PATH = LANGUAGE_COOKIE_PATH = f'/{BASE_PATH.rstrip("/")}'

just to be super explicit (or use a comment on your line that [:-1] only removes the trailing /). Once approved I could provide a PR

@prauscher commented on GitHub (Nov 5, 2022): Thanks for pointing this out. In https://github.com/netbox-community/netbox/blob/develop/netbox/netbox/settings.py#L81 makes sure `BASE_PATH` always contains a trailing `/`. I'd suggest to use ``` SESSION_COOKIE_PATH = CSRF_COOKIE_PATH = LANGUAGE_COOKIE_PATH = f'/{BASE_PATH.rstrip("/")}' ``` just to be super explicit (or use a comment on your line that `[:-1]` only removes the trailing `/`). Once approved I could provide a PR
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#7199