Liking cljdoc? Tell your friends :D

dev.arkaitz.web-base.security

Web security measures that are neither authentication nor authorisation (SPEC §15): response headers added when absent, the host's Content Security Policy with a per-request nonce, opt-in trust of a reverse proxy's headers, and CSRF protection through ring-anti-forgery's synchroniser token.

Written down so it is not rediscovered: htmx's hx-on, hx-vals js: and trigger filters need unsafe-eval or the hx-csp extension; a strict policy means doing without them, which the demo does.

Web security measures that are neither authentication nor authorisation
(SPEC §15): response headers added when absent, the host's Content Security
Policy with a per-request nonce, opt-in trust of a reverse proxy's headers,
and CSRF protection through ring-anti-forgery's synchroniser token.

Written down so it is not rediscovered: htmx's `hx-on`, `hx-vals js:` and
trigger filters need `unsafe-eval` or the `hx-csp` extension; a strict
policy means doing without them, which the demo does.
raw docstring

csrf-fieldclj

(csrf-field request)

The hidden input a classic form needs; htmx requests carry the header instead. Nothing when the request carries no token — under :csrf false there is nothing to send, and an empty field would only earn a 403.

The hidden input a classic form needs; htmx requests carry the header
instead. Nothing when the request carries no token — under `:csrf false`
there is nothing to send, and an empty field would only earn a 403.
sourceraw docstring

csrf-headerclj

source

csrf-tokenclj

(csrf-token request)

The request's token, for the host's own markup — and the read that makes it stick: a token nobody read through here is not written into the session (wrap-csrf).

The request's token, for the host's own markup — and the read that makes it stick:
a token nobody read through here is not written into the session (`wrap-csrf`).
sourceraw docstring

default-headersclj

source

rotate-tokenclj

(rotate-token request)

request carrying a fresh CSRF token for a response that rotates the session, and the token recorded so the rotated session keeps exactly it. The render step calls it before turning such a response into HTML, so a login page's forms carry the token its new session holds. The request unchanged when it went through no CSRF, or carries no token. A token read before this — a handler whose own content called csrf-field — cannot follow the rotation, and is logged by name.

`request` carrying a fresh CSRF token for a response that rotates the session, and
the token recorded so the rotated session keeps exactly it. The render step calls it
before turning such a response into HTML, so a login page's forms carry the token its
new session holds. The request unchanged when it went through no CSRF, or carries no
token. A token read before this — a handler whose own content called `csrf-field` —
cannot follow the rotation, and is logged by name.
sourceraw docstring

wrap-csrfclj

(wrap-csrf handler render-error)

ring-anti-forgery inside the session: every request not GET/HEAD/OPTIONS needs the session's token, read from the __anti-forgery-token form field or the X-CSRF-Token header — which the shell makes htmx send on every request (the library also honours X-XSRF-Token; the base documents one name). A refusal is the base's own 403 datum, so an htmx swap receives a fragment and a navigation a page.

A token reaches the session only if the request used it — through csrf-token or csrf-field, which the shell calls for every page it renders, and while the handler runs. A request that renders neither writes no session, so an anonymous /health, a JSON answer or a redirect leaves no row behind. Reading :anti-forgery-token or ring-anti-forgery's dynamic var directly, or reading the token after the handler returned (a body built lazily later), mints a token that is never stored: the form built with it earns a 403.

ring-anti-forgery inside the session: every request not GET/HEAD/OPTIONS
needs the session's token, read from the `__anti-forgery-token` form field
or the `X-CSRF-Token` header — which the shell makes htmx send on every
request (the library also honours `X-XSRF-Token`; the base documents one
name). A refusal is the base's own 403 datum, so an htmx swap receives a
fragment and a navigation a page.

**A token reaches the session only if the request used it** — through
`csrf-token` or `csrf-field`, which the shell calls for every page it renders,
and while the handler runs. A request that renders neither writes no session, so
an anonymous `/health`, a JSON answer or a redirect leaves no row behind. Reading
`:anti-forgery-token` or ring-anti-forgery's dynamic var directly, or reading the
token after the handler returned (a body built lazily later), mints a token that is
never stored: the form built with it earns a 403.
sourceraw docstring

wrap-headersclj

(wrap-headers handler {:keys [csp] :as config})

Outer middleware: every response — routed, static, error — gets the security headers it lacks; a header the handler set is kept. Every request gets :wb/nonce; when the host configures :csp, {nonce} in it is replaced by that request's nonce and the policy is sent. :frame-options is DENY by default, a string to change it, false to omit it.

Outer middleware: every response — routed, static, error — gets the
security headers it lacks; a header the handler set is kept. Every request
gets `:wb/nonce`; when the host configures `:csp`, `{nonce}` in it is
replaced by that request's nonce and the policy is sent. `:frame-options`
is `DENY` by default, a string to change it, `false` to omit it.
sourceraw docstring

wrap-proxyclj

(wrap-proxy handler)

Trusts X-Forwarded-Proto and X-Forwarded-For for :scheme and :remote-addr. Only behind a proxy the host controls: anyone else can send those headers. The first X-Forwarded-For entry is taken, which is the one the client itself may have written before the proxy appended its own — a host that must trust the address should read the last hop it controls instead.

Trusts `X-Forwarded-Proto` and `X-Forwarded-For` for `:scheme` and
`:remote-addr`. Only behind a proxy the host controls: anyone else can
send those headers. The first `X-Forwarded-For` entry is taken, which is
the one the client itself may have written before the proxy appended its
own — a host that must trust the address should read the last hop it
controls instead.
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
←Move to previous article
→Move to next article
Ctrl+/Jump to the search field
× close