privatebin: drop Anubis — broke XHR paste creation

PrivateBin's UI POSTs the encrypted blob to `/` via XHR. With Anubis in
front, the catch-all CHALLENGE rule returned an HTML challenge page
where the JS expected JSON, so paste creation failed silently for every
user. The challenge cookie didn't bypass it — Anubis appears to issue a
fresh challenge on POST regardless of cookie state.

Pastes are client-side encrypted; AI scrapers gain nothing from
indexing them, so the default `anti_ai_scraping` middleware is enough
protection. Restoring the ingress to point straight at the privatebin
service. CSP `wasm-unsafe-eval` retained — PrivateBin's zlib.wasm
needs it independent of Anubis.

This matches the rule already documented in infra/.claude/CLAUDE.md:
"DO NOT put Anubis in front of Git/API/WebDAV/CLI endpoints — clients
without JS can't solve PoW." A SPA's XHR is the same shape.

Verified: GET / returns PrivateBin HTML (not the Anubis challenge),
POST / returns PrivateBin's own JSON error envelope.
This commit is contained in:
Viktor Barzin 2026-05-10 14:47:48 +00:00
parent 34acd98785
commit dc286a67d1

View file

@ -131,12 +131,11 @@ resource "kubernetes_service" "privatebin" {
}
}
module "anubis" {
source = "../../modules/kubernetes/anubis_instance"
name = "privatebin"
namespace = kubernetes_namespace.privatebin.metadata[0].name
target_url = "http://${kubernetes_service.privatebin.metadata[0].name}.${kubernetes_namespace.privatebin.metadata[0].name}.svc.cluster.local"
}
# Anubis intentionally NOT used here PrivateBin creates pastes via XHR
# `POST /`, which Anubis's catch-all CHALLENGE rule intercepts and serves
# an HTML challenge page where the JS expects JSON. PrivateBin pastes are
# client-side encrypted, so AI scrapers gain nothing from indexing them;
# the default `anti_ai_scraping` middleware is sufficient protection.
module "ingress" {
source = "../../modules/kubernetes/ingress_factory"
@ -144,10 +143,7 @@ module "ingress" {
name = "privatebin"
host = "pb"
dns_type = "proxied"
service_name = module.anubis.service_name
port = module.anubis.service_port
extra_middlewares = ["traefik-x402@kubernetescrd"]
anti_ai_scraping = false
tls_secret_name = var.tls_secret_name
custom_content_security_policy = "script-src 'self' 'unsafe-inline' 'unsafe-eval' 'wasm-unsafe-eval'"
extra_annotations = {