tlamatini-csrf-exempt-audit ยท git:20261022.8c577d3 ยท 2026-10-22 ยท sha256 46a1dc8d56f7db1c

tlamatini-csrf-exempt-audit git:20261022.8c577d3A

Immutable. This exact content never changes and is served at /api/v1/blob/46a1dc8d56f7db1c.

---
name: tlamatini-csrf-exempt-audit
description: Enumerate every @csrf_exempt-decorated view in Tlamatini/agent/views.py and classify whether each one really needs the exemption.
metadata:
  openclaw:
    emoji: "๐Ÿ›ก"
  tlamatini:
    runtime: in-process
    requires_tools: ["chat_agent_executer"]
    requires_mcps: ["Files-Search"]
    budget:
      max_iterations: 4
      max_seconds: 60
      max_tokens: 12000
    permissions:
      filesystem:
        read:  ["Tlamatini/agent/views.py","Tlamatini/agent/urls.py"]
        write: []
      shell:   []
      network: deny
      db:      deny
    inputs: []
    outputs:
      - { name: total,            type: integer, required: true }
      - { name: classifications,  type: array,   required: true }
      - { name: recommendations,  type: array,   required: true }
    triggers:
      keywords: ["csrf","csrf_exempt","csrf audit"]
---
<!--
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
  โœฆ  T L A M A T I N I  โœฆ   โ€”   "one who knows"
  Created by  Angela Lรณpez Mendoza   ยท   @angelahack1
  Developer ยท Architect ยท Creator of Tlamatini
  Tlamatini Author Banner โ€” do not remove (Angela's name is kept in every build)
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
-->

# CSRF-exempt audit

> Current release: **[v1.90.0](../../../../docs/changes/2026-10-22-v1.90.0.md)**. Dated records below retain their original evidence dates.


> **HEADLESS IS FORBIDDEN. VISIBLE FOREGROUND EXECUTION ONLY.** Every command, automated test, diagnostic, script, build, agent and browser must run in a visible foreground window on Angela's real desktop. Use forked CMD/PowerShell windows, `execute_forked_window: true`, and `headless: false`. Monitor live; if visibility cannot be confirmed, do not run. Read the [mandatory execution policy](../../../../TestsVisiblesAndVisibleExecutionFromClaude2Codex.md).

Inventory every `@csrf_exempt` in `Tlamatini/agent/views.py` and classify each
one against the protection the server actually applies. **Read-only** unless
remediation is separately requested.

## โš ๏ธ Find the RIGHT function

`@csrf_exempt` decorates the function that **FOLLOWS** it. Inspecting the view
above a decorator audits the wrong endpoint. Anchor on the `def` immediately
beneath the decorator stack.

## โš ๏ธ "Called by our own JavaScript" IS NOT A CLASSIFICATION

Two labels were previously handed out on the caller's identity alone:

* *safe-because-internal-tool* โ€” but CSRF is precisely the attack where a
  **third-party page** issues the request while the victim's cookies ride
  along. That our own JS also calls the endpoint says nothing about who else
  can.
* *safe-because-websocket* โ€” the WebSocket consumer is a different transport
  with a different origin check. It does not protect the HTTP view that
  happens to sit near it.

Neither establishes anything. Delete them.

## What actually decides it โ€” inspect the view body

For each exempt endpoint record, with a line reference:

1. **Authentication** โ€” `@login_required` / an explicit `request.user`
   check / none.
2. **Allowed methods** โ€” `@require_POST` and friends, or an unguarded handler.
3. **State change** โ€” does it write a file, a DB row, config, or spawn a
   process? A read-only endpoint has a different risk profile from one that
   writes `config.json`.
4. **Credential mechanism** โ€” session cookie (CSRF-relevant) vs a bearer
   token or signature in the body (usually not).
5. **Origin / token protection** โ€” an explicit `Origin`/`Referer` check, an
   HMAC, a shared secret, or nothing.
6. **Reachability** โ€” is it bound to loopback, or served on every interface
   the `django_port` listens on?

## The four verdicts (nothing else)

| verdict | meaning |
|---|---|
| `justified_exemption` | the endpoint does not rely on cookie auth (e.g. a signed webhook), so CSRF does not apply โ€” cite the mechanism. |
| `protected_by_other_means` | cookie-authenticated, but an origin/token/HMAC check is present โ€” cite the line. |
| `protection_missing` | cookie-authenticated, state-changing, no compensating check. Report it; do not fix it here. |
| `insufficient_evidence` | you could not establish one of the six facts above. **Leave it unresolved.** |

Every verdict must cite the SERVER-SIDE check that supports it. A caller's
name is never a citation.

Return `{ endpoints: [{name, line, verdict, evidence, state_changing}],
summary }`.