diff --git a/netbox_rack_concept/static/netbox_rack_concept/elevation.js b/netbox_rack_concept/static/netbox_rack_concept/elevation.js index a44bf8d..58671db 100644 --- a/netbox_rack_concept/static/netbox_rack_concept/elevation.js +++ b/netbox_rack_concept/static/netbox_rack_concept/elevation.js @@ -76,8 +76,10 @@ const statusEl = document.getElementById('concept-elevation-status'); function csrfToken() { - const match = document.cookie.match(/(^|;)\s*csrftoken\s*=\s*([^;]+)/); - return match ? decodeURIComponent(match[2]) : ''; + // NetBox sets CSRF_COOKIE_HTTPONLY, so the cookie itself is invisible to + // JavaScript - read the value from the hidden {% csrf_token %} input instead. + const input = document.querySelector('input[name="csrfmiddlewaretoken"]'); + return input ? input.value : ''; } function setStatus(message, isError) { diff --git a/netbox_rack_concept/templates/netbox_rack_concept/rackconcept.html b/netbox_rack_concept/templates/netbox_rack_concept/rackconcept.html index 5baf80f..08f6436 100644 --- a/netbox_rack_concept/templates/netbox_rack_concept/rackconcept.html +++ b/netbox_rack_concept/templates/netbox_rack_concept/rackconcept.html @@ -143,6 +143,10 @@
+ {# CSRF_COOKIE_HTTPONLY is on in NetBox, so the elevation.js reorder POST can't + read the csrftoken cookie via document.cookie - it reads this hidden input's + value instead, the standard Django way to CSRF-protect a plain fetch(). #} + {% csrf_token %}