feat(upload): require approved account for log uploads - #1
Draft
dakejahl wants to merge 4 commits into
Draft
Conversation
The root Dockerfile ran setup_db.py only at build time, against the throwaway image layer — never against the mounted persistent data volume. A persistent prod DB therefore never received the ContentHash (b66bb97) and Pending (2db03b1) columns, so every upload hit "no such column: ContentHash" on the dedupe lookup and returned 500. Run the idempotent migration at startup so the live DB is upgraded on every deploy/restart.
Anonymous uploads are rejected with 403 in prepare(), before the request body is streamed. Since login already requires an approved account, every accepted upload is parsed immediately and the deferred/pending state is no longer reachable at upload time. This also closes the client-controlled source=CI path for anonymous users, which previously stored an unparsed, non-pending log whose plot URL triggered an unbounded in-process parse. Anonymous visitors to the upload form are redirected to the login page; viewing plots stays public.
Anonymous pending logs predate the anonymous-upload ban and are never parsed by policy; the script deletes them (list-only by default, --delete to act). Pending logs with a named uploader are left alone — they are parsed automatically when the account is approved.
dakejahl
force-pushed
the
fix/restore-broken-uploads
branch
from
July 9, 2026 21:41
20aa55d to
1a50ce2
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Rejects anonymous uploads: a registered, admin-approved account is now required to upload logs. Supersedes the earlier approach on this branch of parsing anonymous uploads immediately.
Problem
Anonymous uploads fed attacker-controlled files into the log parser. The upload-time parse runs in a bounded worker process, but once a log is stored non-pending its plot page parses the file unbounded in the main server process — and the client-controlled
source=CIfield let an anonymous client store an unparsed, non-pending log and trigger exactly that via the plot URL. Deferred anonymous logs were also stranded: nothing ever un-defers a log with an empty uploader, so they sat pending forever.Solution
Uploads are rejected with 403 in
prepare(), before the request body is streamed, unless the client is logged in and the account is still approved (the re-check covers accounts revoked after their login cookie was issued). Since login already requires approval, every accepted upload is parsed immediately and the deferred/pending state is unreachable at upload time; the deferral branch is removed. Anonymous visitors to the upload form are redirected to the login page; viewing plots stays public. The backfill script is replaced bycleanup_pending_logs.py, which deletes stranded anonymous pending logs (list-only by default,--deleteto act) and leaves named-uploader pending logs to be parsed on account approval. Run once after deploy:cd app && python cleanup_pending_logs.py --delete.