No CSRF protection on people.php label-save POST endpoint #4

Open
opened 2026-05-14 20:35:16 +02:00 by Claude · 0 comments

Problem

The people.php form that saves person labels has no CSRF token. Any page on any origin can submit a cross-site form POST to the running viewer and overwrite or delete entries in people_labels.json:

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['cluster'])) {
    // ... writes $labelsFile without any token check
    file_put_contents($labelsFile, json_encode($labels, ...));

Location

people.php — POST handler at the top of the file (~lines 9–18) and the <form> element in the detail view (~line 80).

Risk

While the server listens only on 127.0.0.1 by default, a malicious web page visited in the same browser session can silently POST to http://127.0.0.1:8123/people.php and rename or delete any person label. For users who expose the viewer on a LAN address (by changing run.sh) the attack surface is wider.

Suggested fix direction

Generate a random token per session (e.g., session_start() + $_SESSION['csrf']), embed it as a hidden field in the form, and verify it matches on POST before writing the file. Alternatively, check $_SERVER['HTTP_ORIGIN'] or HTTP_REFERER against the expected host as a lightweight mitigation.

Severity

minor

Found by

Automated audit by Claude Code

## Problem The `people.php` form that saves person labels has no CSRF token. Any page on any origin can submit a cross-site form POST to the running viewer and overwrite or delete entries in `people_labels.json`: ```php if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['cluster'])) { // ... writes $labelsFile without any token check file_put_contents($labelsFile, json_encode($labels, ...)); ``` ## Location `people.php` — POST handler at the top of the file (~lines 9–18) and the `<form>` element in the detail view (~line 80). ## Risk While the server listens only on `127.0.0.1` by default, a malicious web page visited in the same browser session can silently POST to `http://127.0.0.1:8123/people.php` and rename or delete any person label. For users who expose the viewer on a LAN address (by changing `run.sh`) the attack surface is wider. ## Suggested fix direction Generate a random token per session (e.g., `session_start()` + `$_SESSION['csrf']`), embed it as a hidden field in the form, and verify it matches on POST before writing the file. Alternatively, check `$_SERVER['HTTP_ORIGIN']` or `HTTP_REFERER` against the expected host as a lightweight mitigation. ## Severity minor ## Found by Automated audit by Claude Code
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
bc1bb/BeReal-extractor#4
No description provided.