Skip to content

Commit 5a386af

Browse files
committed
Update CSRF recommendation
Recommend using a form with a hidden input or an adjacent CSRF token in the header. Stop recommending a global token in the `html` or `body` tags as those may not work with `hx-boost`. Fix #3379
1 parent 7ae66f9 commit 5a386af

File tree

1 file changed

+24
-8
lines changed

1 file changed

+24
-8
lines changed

www/content/docs.md

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,22 +1695,38 @@ for exploring this topic.
16951695

16961696
### CSRF Prevention
16971697

1698-
The assignment and checking of CSRF tokens are typically backend responsibilities, but `htmx` can support returning the CSRF token automatically with every request using the `hx-headers` attribute. The attribute needs to be added to the element issuing the request or one of its ancestor elements. This makes the `html` and `body` elements effective global vehicles for adding the CSRF token to the `HTTP` request header, as illustrated below.
1698+
The assignment and checking of CSRF tokens are typically backend responsibilities.
1699+
For example, using Django, a popular Python web framework
1700+
[documentation](https://docs.djangoproject.com/en/5.2/howto/csrf/#using-csrf):
16991701

17001702
```html
1701-
<html lang="en" hx-headers='{"X-CSRF-TOKEN": "CSRF_TOKEN_INSERTED_HERE"}'>
1702-
:
1703-
</html>
1703+
<form method="post" action="/foo" hx-boost="true">{% csrf_token %}
1704+
<input name="foo-name">
1705+
<button type="submit">Add Foo</button>
1706+
</form>
17041707
```
17051708

1709+
Htmx will ensure the CSRF 'token' (a hidden input) is submitted along with the
1710+
form so that the Django backend can check it.
1711+
1712+
Or if you're not using a form, you can set the token in a header:
1713+
17061714
```html
1707-
<body hx-headers='{"X-CSRF-TOKEN": "CSRF_TOKEN_INSERTED_HERE"}'>
1708-
:
1709-
</body>
1715+
<span id="delete-foo-token">{% csrf_token %}</span>
1716+
<button
1717+
hx-delete="/orders/1234"
1718+
hx-headers="js:{'X-CSRFToken': document.querySelector('#delete-foo-token > [name=csrfmiddlewaretoken]').value}"
1719+
>
1720+
Delete Order 1234
1721+
</button>
17101722
```
17111723

1712-
The above elements are usually unique in an HTML document and should be easy to locate within templates.
1724+
It's typically not a good idea to set the CSRF token in the `html` or `body`
1725+
elements, because those are not updated by `hx-boost`. So, they could lead to
1726+
form validation errors in the backend.
17131727

1728+
Remember, these are just examples–you will need to adapt them to your backend
1729+
framework.
17141730

17151731
## Configuring htmx {#config}
17161732

0 commit comments

Comments
 (0)