http.frm.csrf
CSRF 双提交令牌中间件(P6-B;HMAC 签名对 + SameSite 默认)
语义登记(v1 口径):
形 = 无状态双提交(statemless double-submit)+ HMAC 签名硬化:签发面
csrf_issue(key, nonce) → tok = nonce "." hex(HMAC-SHA256(key, nonce))
(std/crypto hmac_sha256 —— ws.ct use std.crypto 先例,纯叶无 W8052);
校验面 csrf_verify(key, cookie_tok, submit_tok):cookie token 与提交
(header/form)token 串等值(双提交)+ 签名重算恒等验证。缺任一端/
不等/形坏/签坏 → 结构化拒(why 码;composition 层映射 403)。
恒时比较:签名 hex 段比较走逐字节算术平方累计 diff(长度差一并计入;
差非零即平方 > 0,累计和恒 0 当且仅当全等)——字符串早期退出面收窄;
真·恒时(数据无关访存)登记志向(Task 3 auth 同面,hmac + 常时比较
助手归口)。【emit 缺口登记(P6-B 实证)】位或 | 表达式位 = ctron-emit
挂死(最小探针:interp 绿,emit 侧无输出即杀;语言无位运算 §4.5 在案
—— lexer 有 | token 但 emit 侧无 lowering)——草稿原形
diff = diff | (da-db)*(da-db) 即触;本文件以算术累计绕行,crypto.ct
xor32 手工位抽取同口径。
Cookie 面 = Set-Cookie 助手:SameSite=Lax 默认(题面);HttpOnly 不设 (双提交要求 JS 可读提交 —— 经典权衡,登记);Secure/Domain/自定义名 列志向。cookie/form 取值助手(csrf_cookie_get/csrf_form_get)零解码 (token 域 = [A-Za-z0-9]{16..64},percent/plus 解码登记缺席 —— 签发域 即不含,从严)。
nonce 熵源 = composition 层注入(uuid_v4/random 序号/会话指纹)—— 纯层 无熵,uuid.ct 依赖 net 垫片为 emit 专臂,故本模块收 nonce 形参(可确定性 测试;真钟/真熵装配归 composition)。
注入面:Set-Cookie 值恒出自本模块签发(nonce 域校验 + hex 签名)—— CR/LF/控制字节不可达;csrf_set_cookie 对外仍按「仅喂 csrf_issue 产物」 约定登记(不再二次校验,v1)。请求侧取值面(csrf_cookie_get/csrf_form_get) 产出只进 csrf_verify 比较面,永不回流响应头 —— 头走私面封口。
Task 3 auth 对齐登记:cookie 名 csrf、属性序 Path=/; SameSite=Lax
—— auth.ct 会话 cookie 沿用同属性序(Path 前置、SameSite=Lax 收尾),
会话版增 HttpOnly;双提交令牌 cookie 特意不带 HttpOnly(JS 需读提交,
经典权衡见上)。
use 面:std.crypto 单叶(零共享 —— 多中间件同入口组合不触严格树 E5020; middleware/router 不引,链形适配由消费方组合层完成,同 cors.ct 登记)。 消费方若自用 std.crypto 再 use 本模块 = 同叶双径 E5020,禁(fixture 以 本模块面消费 crypto,直用面归 tests/crypto_vec)。
pub struct
struct CsrfTok
| Field | Type |
|---|---|
ok |
I64 |
why |
I64 |
tok |
Str |
struct CsrfVer
| Field | Type |
|---|---|
rc |
I64 |
why |
I64 |
pub fn
| Signature | Returns | Description |
|---|---|---|
ct_rc(t: CsrfTok) |
I64 |
why:0 ok / 1 nonce 形坏(域 [A-Za-z0-9]{16..64}) |
ct_why(t: CsrfTok) |
I64 |
— |
ct_tok(t: CsrfTok) |
Str |
— |
csrf_issue(key: Str, nonce: Str) |
CsrfTok |
签发:tok = nonce "." hex(HMAC-SHA256(key, nonce)) |
cv_rc(v: CsrfVer) |
I64 |
why:0 ok / 1 cookie 端缺 / 2 提交端缺 / 3 双提交不等 / 4 形坏(无点分/ nonce 域坏/sig 非 64 hex)/ 5 签名不合 |
cv_why(v: CsrfVer) |
I64 |
— |
csrf_verify(key: Str, cookie_tok: Str, submit_tok: Str) |
CsrfVer |
双提交校验:cookie_tok/submit_tok(header 或 form 提交值) |
csrf_cookie_get(cookie_hdr: Str, name: Str) |
Str |
Cookie 头值 "a=b; c=d" → 名精确匹配值(无 → "";首匹配胜出) |
csrf_form_get(body: Str, name: Str) |
Str |
form-urlencoded 体 "a=b&c=d" → 名精确匹配值(无 → "";零解码,头注) |
csrf_set_cookie(tok: Str) |
Str |
Set-Cookie 行(SameSite=Lax 默认;HttpOnly 不设 —— 头注权衡;CRLF 自备) |
csrf_resp_403() |
Str |
拒响应面(composition 层校验 rc=0 即发;403 + body 13) |