Commit bf78cd9
committed
release: 1.3.0 β observability, SQLite pool, CSP nonce, CLI split
Bumps server (pyproject.toml) and CLI (cli/pyproject.toml) in lockstep
so `v1.3.0` names a single consistent release across the Docker image
and the PyPI wheel.
Highlights since 1.2.0:
Security
* Webhook DNS-rebinding defense: resolve once at delivery time, pin
the TCP connection to that IP, reject the whole host on any private
address (fix(webhook): pin TCPβ¦).
* SSRF filter now uses ipaddress.is_global + is_multicast, covering
the ranges we were missing (CGNAT, benchmark, TEST-NET, IPv4/6
multicast, etc.) instead of a hand-rolled list that drifts.
* X-Forwarded-For now reads the rightmost entry β leftmost is
client-controlled and was bypassable. Documented the multi-hop
caveat.
* CSP script-src hardened: `'unsafe-inline'` replaced by a per-request
nonce; all inline `onclick=` handlers rewritten as
`addEventListener`. style-src keeps `'unsafe-inline'` while the
inline `style="β¦"` attributes remain β separate chore.
* DELETE endpoints return a uniform 403, not 404/403, so probing
with a bad token can't enumerate existing paste IDs.
Observability
* New /metrics endpoint (Prometheus) with business counters
(pastes created/viewed/deleted, webhook outcomes) and latency +
pool-wait histograms.
* /healthz is now documented as part of the operator surface.
Storage
* SQLite: single-conn + lock β pooled connections (WAL + busy_timeout
handle writer serialization). Configurable via SQLITE_POOL_SIZE,
observable via ghostbit_sqlite_pool_wait_seconds.
* iter_all() streams via fetchmany(500) so admin export doesn't
materialize huge DBs in memory.
* Redis save() on an already-expired paste now returns False instead
of a phantom True, so admin import counts it as skipped.
Code quality
* Root pyproject.toml with ruff config + package metadata; server
and CLI both pip install -e'able with [dev] extras.
* CI workflow runs ruff check + format check + pytest on every PR
touching app/, tests/, or cli/.
* Language metadata (slug β extensions, CM mode, Pygments aliases)
centralized in app/languages.json; the four previous duplicates in
main.py, detect.py, index.html, paste.html are now derived views.
* CLI split from one 827-line cli.py into a cli/ package (crypto,
config, history, api, completion, __init__ entry point).
* Per-page JS moved out of the templates into static/{index,paste,
raw,footer}.js, read bootstrap data from
<script type="application/json"> blocks.1 parent 356b1c4 commit bf78cd9
2 files changed
Lines changed: 2 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
| 7 | + | |
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
| 7 | + | |
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| |||
0 commit comments