2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-10-03 15:52:51 +00:00

feat(backend): releax protocol check (#10454)

* feat(backend): releax protocol check

* add changelog entry

* fix variable name

---------

Co-authored-by: Oliver <oliver.henry.walters@gmail.com>
This commit is contained in:
Matthias Mair
2025-10-02 13:36:37 +02:00
committed by GitHub
parent b8b1fabc50
commit 7638092ab8
5 changed files with 34 additions and 5 deletions

View File

@@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- Changed site URL check to allow protocol mismatches if `INVENTREE_SITE_LAX_PROTOCOL` is set to `True` (default) in [#10454](https://github.com/inventree/InvenTree/pull/10454)
### Removed ### Removed

View File

@@ -135,6 +135,7 @@ Depending on how your InvenTree installation is configured, you will need to pay
| INVENTREE_CORS_ORIGIN_WHITELIST | cors.whitelist | List of whitelisted CORS URLs. Refer to the [django-cors-headers documentation](https://github.com/adamchainz/django-cors-headers#cors_allowed_origins-sequencestr) | Uses the *INVENTREE_SITE_URL* parameter, if set. Otherwise, an empty list. | | INVENTREE_CORS_ORIGIN_WHITELIST | cors.whitelist | List of whitelisted CORS URLs. Refer to the [django-cors-headers documentation](https://github.com/adamchainz/django-cors-headers#cors_allowed_origins-sequencestr) | Uses the *INVENTREE_SITE_URL* parameter, if set. Otherwise, an empty list. |
| INVENTREE_CORS_ORIGIN_REGEX | cors.regex | List of regular expressions for CORS whitelisted URL patterns | *Empty list* | | INVENTREE_CORS_ORIGIN_REGEX | cors.regex | List of regular expressions for CORS whitelisted URL patterns | *Empty list* |
| INVENTREE_CORS_ALLOW_CREDENTIALS | cors.allow_credentials | Allow cookies in cross-site requests | `True` | | INVENTREE_CORS_ALLOW_CREDENTIALS | cors.allow_credentials | Allow cookies in cross-site requests | `True` |
| INVENTREE_SITE_LAX_PROTOCOL | site_lax_protocol | Ignore protocol mismatches on INVE-E7 site checks | `True` |
| INVENTREE_USE_X_FORWARDED_HOST | use_x_forwarded_host | Use forwarded host header | `False` | | INVENTREE_USE_X_FORWARDED_HOST | use_x_forwarded_host | Use forwarded host header | `False` |
| INVENTREE_USE_X_FORWARDED_PORT | use_x_forwarded_port | Use forwarded port header | `False` | | INVENTREE_USE_X_FORWARDED_PORT | use_x_forwarded_port | Use forwarded port header | `False` |
| INVENTREE_USE_X_FORWARDED_PROTO | use_x_forwarded_proto | Use forwarded protocol header | `False` | | INVENTREE_USE_X_FORWARDED_PROTO | use_x_forwarded_proto | Use forwarded protocol header | `False` |

View File

@@ -234,9 +234,17 @@ class InvenTreeHostSettingsMiddleware(MiddlewareMixin):
if path in urls or any(path.startswith(p) for p in paths_ignore): if path in urls or any(path.startswith(p) for p in paths_ignore):
return None return None
# Ensure that the settings are set correctly with the current request # treat the accessed scheme and host
accessed_scheme = request._current_scheme_host accessed_scheme = request._current_scheme_host
if accessed_scheme and not accessed_scheme.startswith(settings.SITE_URL): referer = urlsplit(accessed_scheme)
# Ensure that the settings are set correctly with the current request
matches = (
(accessed_scheme and not accessed_scheme.startswith(settings.SITE_URL))
if not settings.SITE_LAX_PROTOCOL_CHECK
else not is_same_domain(referer.netloc, urlsplit(settings.SITE_URL).netloc)
)
if matches:
if ( if (
isinstance(settings.CSRF_TRUSTED_ORIGINS, list) isinstance(settings.CSRF_TRUSTED_ORIGINS, list)
and len(settings.CSRF_TRUSTED_ORIGINS) > 1 and len(settings.CSRF_TRUSTED_ORIGINS) > 1
@@ -251,7 +259,6 @@ class InvenTreeHostSettingsMiddleware(MiddlewareMixin):
) )
# Check trusted origins # Check trusted origins
referer = urlsplit(accessed_scheme)
if not any( if not any(
is_same_domain(referer.netloc, host) is_same_domain(referer.netloc, host)
for host in [ for host in [

View File

@@ -1064,6 +1064,9 @@ DATE_INPUT_FORMATS = ['%Y-%m-%d']
# Site URL can be specified statically, or via a run-time setting # Site URL can be specified statically, or via a run-time setting
SITE_URL = get_setting('INVENTREE_SITE_URL', 'site_url', None) SITE_URL = get_setting('INVENTREE_SITE_URL', 'site_url', None)
SITE_LAX_PROTOCOL_CHECK = get_boolean_setting(
'INVENTREE_SITE_LAX_PROTOCOL', 'site_lax_protocol', True
)
if SITE_URL: if SITE_URL:
SITE_URL = str(SITE_URL).strip().rstrip('/') SITE_URL = str(SITE_URL).strip().rstrip('/')

View File

@@ -110,6 +110,24 @@ class MiddlewareTests(InvenTreeTestCase):
response = self.client.get(reverse('web')) response = self.client.get(reverse('web'))
self.do_positive_test(response) self.do_positive_test(response)
def test_site_lax_protocol(self):
"""Test that the site URL check is correctly working with/without lax protocol check."""
# Simple setup with proxy
with self.settings(
SITE_URL='https://testserver', CSRF_TRUSTED_ORIGINS=['https://testserver']
):
response = self.client.get(reverse('web'))
self.do_positive_test(response)
# No worky if strong security
with self.settings(
SITE_URL='https://testserver',
CSRF_TRUSTED_ORIGINS=['https://testserver'],
SITE_LAX_PROTOCOL_CHECK=False,
):
response = self.client.get(reverse('web'))
self.assertContains(response, 'INVE-E7: The used path', status_code=500)
def test_site_url_checks_multi(self): def test_site_url_checks_multi(self):
"""Test that the site URL check is correctly working in a multi-site setup.""" """Test that the site URL check is correctly working in a multi-site setup."""
# multi-site setup with trusted origins # multi-site setup with trusted origins
@@ -162,7 +180,6 @@ class MiddlewareTests(InvenTreeTestCase):
CSRF_TRUSTED_ORIGINS=['https://example.com'], CSRF_TRUSTED_ORIGINS=['https://example.com'],
): ):
response = self.client.get(reverse('web')) response = self.client.get(reverse('web'))
self.assertEqual(response.status_code, 500)
self.assertContains( self.assertContains(
response, 'is not in the TRUSTED_ORIGINS', status_code=500 response, 'is not in the TRUSTED_ORIGINS', status_code=500
) )
@@ -176,7 +193,6 @@ class MiddlewareTests(InvenTreeTestCase):
CSRF_TRUSTED_ORIGINS=['http://localhost:8000'], CSRF_TRUSTED_ORIGINS=['http://localhost:8000'],
): ):
response = self.client.get(reverse('web')) response = self.client.get(reverse('web'))
self.assertEqual(response.status_code, 500)
self.assertContains( self.assertContains(
response, 'INVE-E7: The used path `http://testserver` ', status_code=500 response, 'INVE-E7: The used path `http://testserver` ', status_code=500
) )