mirror of
https://github.com/netbox-community/netbox.git
synced 2026-03-04 21:40:05 +01:00
Compare commits
1 Commits
main
...
21468-copy
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d026d22a22 |
@@ -38,6 +38,7 @@ FILTER_TREENODE_NEGATION_LOOKUP_MAP = dict(
|
||||
# HTTP Request META safe copy
|
||||
#
|
||||
|
||||
# Non-HTTP_ META keys to include when copying a request (whitelist)
|
||||
HTTP_REQUEST_META_SAFE_COPY = [
|
||||
'CONTENT_LENGTH',
|
||||
'CONTENT_TYPE',
|
||||
@@ -61,6 +62,13 @@ HTTP_REQUEST_META_SAFE_COPY = [
|
||||
'SERVER_PORT',
|
||||
]
|
||||
|
||||
# HTTP_ META keys known to carry sensitive data; excluded when copying a request (denylist)
|
||||
HTTP_REQUEST_META_SENSITIVE = {
|
||||
'HTTP_AUTHORIZATION',
|
||||
'HTTP_COOKIE',
|
||||
'HTTP_PROXY_AUTHORIZATION',
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# CSV-style format delimiters
|
||||
|
||||
@@ -8,7 +8,7 @@ from netaddr import AddrFormatError, IPAddress
|
||||
|
||||
from netbox.registry import registry
|
||||
|
||||
from .constants import HTTP_REQUEST_META_SAFE_COPY
|
||||
from .constants import HTTP_REQUEST_META_SAFE_COPY, HTTP_REQUEST_META_SENSITIVE
|
||||
|
||||
__all__ = (
|
||||
'NetBoxFakeRequest',
|
||||
@@ -45,11 +45,14 @@ def copy_safe_request(request, include_files=True):
|
||||
request: The original request object
|
||||
include_files: Whether to include request.FILES.
|
||||
"""
|
||||
meta = {
|
||||
k: request.META[k]
|
||||
for k in HTTP_REQUEST_META_SAFE_COPY
|
||||
if k in request.META and isinstance(request.META[k], str)
|
||||
}
|
||||
meta = {}
|
||||
for k, v in request.META.items():
|
||||
if not isinstance(v, str):
|
||||
continue
|
||||
if k in HTTP_REQUEST_META_SAFE_COPY:
|
||||
meta[k] = v
|
||||
elif k.startswith('HTTP_') and k not in HTTP_REQUEST_META_SENSITIVE:
|
||||
meta[k] = v
|
||||
data = {
|
||||
'META': meta,
|
||||
'COOKIES': request.COOKIES,
|
||||
|
||||
@@ -1,7 +1,42 @@
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
from django.test import RequestFactory, TestCase
|
||||
from netaddr import IPAddress
|
||||
|
||||
from utilities.request import get_client_ip
|
||||
from utilities.request import copy_safe_request, get_client_ip
|
||||
|
||||
|
||||
class CopySafeRequestTests(TestCase):
|
||||
def setUp(self):
|
||||
self.factory = RequestFactory()
|
||||
|
||||
def _make_request(self, **kwargs):
|
||||
request = self.factory.get('/', **kwargs)
|
||||
request.user = AnonymousUser()
|
||||
return request
|
||||
|
||||
def test_standard_meta_keys_copied(self):
|
||||
request = self._make_request(HTTP_USER_AGENT='TestAgent/1.0')
|
||||
fake = copy_safe_request(request)
|
||||
self.assertEqual(fake.META.get('HTTP_USER_AGENT'), 'TestAgent/1.0')
|
||||
|
||||
def test_arbitrary_http_headers_copied(self):
|
||||
"""Arbitrary HTTP_ headers (e.g. X-NetBox-*) should be included."""
|
||||
request = self._make_request(HTTP_X_NETBOX_BRANCH='my-branch')
|
||||
fake = copy_safe_request(request)
|
||||
self.assertEqual(fake.META.get('HTTP_X_NETBOX_BRANCH'), 'my-branch')
|
||||
|
||||
def test_sensitive_headers_excluded(self):
|
||||
"""Authorization and Cookie headers must not be copied."""
|
||||
request = self._make_request(HTTP_AUTHORIZATION='Bearer secret')
|
||||
fake = copy_safe_request(request)
|
||||
self.assertNotIn('HTTP_AUTHORIZATION', fake.META)
|
||||
|
||||
def test_non_string_meta_values_excluded(self):
|
||||
"""Non-string META values must not be copied."""
|
||||
request = self._make_request()
|
||||
request.META['HTTP_X_CUSTOM_INT'] = 42
|
||||
fake = copy_safe_request(request)
|
||||
self.assertNotIn('HTTP_X_CUSTOM_INT', fake.META)
|
||||
|
||||
|
||||
class GetClientIPTests(TestCase):
|
||||
|
||||
Reference in New Issue
Block a user