Skip to main content

logicaffeine_system/
csrf.rs

1//! The page half of CSRF: a page document carries its visitor's token in its head, where the
2//! browser host reads it and sends it back as `x-csrf-token` on the page's state-changing requests
3//! to its own server. One definition for every tier that composes or reads a page — the dev
4//! server, a compiled server, the in-process host and the browser runtime's shared name.
5
6/// The `<meta name>` a page document carries its visitor's CSRF token under.
7pub const CSRF_META_NAME: &str = "csrf-token";
8
9/// `document` carrying `token` in its head as `<meta name="csrf-token">`. The meta opens the head,
10/// so a page's own `Head:` merges over it by identity like every other head element. A document
11/// with no `<head>` is returned as it is.
12pub fn with_csrf_meta(document: &str, token: &str) -> String {
13    let Some(open) = document
14        .to_ascii_lowercase()
15        .find("<head>")
16        .map(|at| at + "<head>".len())
17    else {
18        return document.to_string();
19    };
20    let escaped = token
21        .replace('&', "&amp;")
22        .replace('<', "&lt;")
23        .replace('>', "&gt;")
24        .replace('"', "&quot;");
25    let tag = format!("\n<meta name=\"{CSRF_META_NAME}\" content=\"{escaped}\">");
26    format!("{}{tag}{}", &document[..open], &document[open..])
27}