No paste expiry / TTL — database grows indefinitely #1

Closed
opened 2026-05-18 04:05:17 -04:00 by everestmcarthur · 0 comments
everestmcarthur commented 2026-05-18 04:05:17 -04:00 (Migrated from github.com)

Summary

Pastes stored in SQLite have no expiry time or TTL. The database will grow without bound and there is no cleanup mechanism.

Details

In forge-paste.py, the pastes table has no expires_at column and no scheduled purge:

db.execute("""
    CREATE TABLE IF NOT EXISTS pastes (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        slug TEXT UNIQUE NOT NULL,
        content TEXT NOT NULL,
        language TEXT,
        created_at REAL NOT NULL DEFAULT (unixepoch()),
        views INTEGER NOT NULL DEFAULT 0,
        ip TEXT        -- stored indefinitely, no cleanup
    )
""")

There is also no DELETE or VACUUM call anywhere in the codebase.

Suggested Fix

  1. Add an expires_at column (e.g. default 30 days from creation)
  2. Add a cleanup routine (run periodically or on each request at low frequency):
    db.execute("DELETE FROM pastes WHERE expires_at < ?", (time.time(),))
    db.execute("PRAGMA wal_checkpoint(TRUNCATE)")
    
  3. Expose a --max-age CLI flag (default: 30 days)

Also: IP addresses stored without expiry

Client IPs are logged to the ip column with no TTL or privacy notice. These should either be dropped or expire with the paste.

## Summary Pastes stored in SQLite have no expiry time or TTL. The database will grow without bound and there is no cleanup mechanism. ## Details In `forge-paste.py`, the `pastes` table has no `expires_at` column and no scheduled purge: ```python db.execute(""" CREATE TABLE IF NOT EXISTS pastes ( id INTEGER PRIMARY KEY AUTOINCREMENT, slug TEXT UNIQUE NOT NULL, content TEXT NOT NULL, language TEXT, created_at REAL NOT NULL DEFAULT (unixepoch()), views INTEGER NOT NULL DEFAULT 0, ip TEXT -- stored indefinitely, no cleanup ) """) ``` There is also no `DELETE` or `VACUUM` call anywhere in the codebase. ## Suggested Fix 1. Add an `expires_at` column (e.g. default 30 days from creation) 2. Add a cleanup routine (run periodically or on each request at low frequency): ```python db.execute("DELETE FROM pastes WHERE expires_at < ?", (time.time(),)) db.execute("PRAGMA wal_checkpoint(TRUNCATE)") ``` 3. Expose a `--max-age` CLI flag (default: 30 days) ## Also: IP addresses stored without expiry Client IPs are logged to the `ip` column with no TTL or privacy notice. These should either be dropped or expire with the paste.
Sign in to join this conversation.
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: SheWhoReignsSupreme/forge-paste#1
No description provided.