Part IV — Canopy, ground and care
11 · Caring for the tree
An old baobab has a hollow in its trunk, and the hollow is part of the tree too. This module lists the hollows that the October 2026 review found — the ones that were closed and the ones that remain as work for the community.
Fixed in 3.3
| # | Problem | Where | How it was closed | Test |
|---|---|---|---|---|
| 1 | ActivityPub inbox always mounted, unsigned, with an upsert on a uuid chosen by the sender: anyone could overwrite the saber of an OXALÁ, of the mucua or of the galaxy, and the commit spread through sync | api/v3/activitypub.py, federacao/ingestao.py | route only with BBX_FED_AP=on; HTTP Signature from a known mucua (Digest + Date); ingestion doesn't touch local sabers, rejects identity natures and malformed uuids | test_federacao_inbox_segura.py |
| 2 | EdDSA token from another mucua: any known mucua could issue a token with the sub of a local OXALÁ and mucua = local, and gain administration of the instance; a forged copy of the local mucua's saber allowed issuing "local" tokens | services/auth.py | local issuer only with the key on disk; an outside mucua only vouches for its own mocambolas; mucua and username recomputed; external IdP always USER | test_token_federado_recalcula_papel.py |
| 3 | Attachment download, thumbnail and collection cover without a read check: acl, private, draft and restricted-galaxy content went out to anonymous users | services/saber_service.py, api/v3/saberes.py, colecoes.py | content_path, thumbnail_path, colecao_mosaico_path receive actor and go through can(READ) | test_vazamentos_de_leitura.py |
| 4 | XSS: [x](javascript:…) in markdown and URLs from saber fields became executable links | front lib/util/markdown.ts and pages | hrefSeguro | — |
| 5 | SVG served inline by the API on the same origin as the site ran scripts | api/v3/saberes.py | CSP sandbox + nosniff | — |
| 6 | No limit on password attempts (/auth/login, /auth/token, /xmpp/extauth) | services/auth.py | per-account brake (10 errors in 15 min) | test_freio_login.py |
| 7 | git clone <url> with a url coming from the API: --upload-pack=… would run a command | infra/sync/*.py | -- and rejecting urls that start with - | — |
| 8 | XMPP extauth reachable from the internet | nginx | allow 127.0.0.1 | — |
Hollows that remain (for the community to decide)
password_hashtravels in git. Every cloned galaxy carries the hashes of every account. PBKDF2 with 200 thousand rounds slows down an offline attack but doesn't prevent it. Way forward: move the password out ofsaber.bbx(like the private keys) or switch to a costlier Argon2/scrypt.- 7-day token with the role stamped in it. Demoting someone only takes effect at their next login. Groups are already resolved per request — the role could follow the same path, or the token could be shorter with renewal.
- Token in the query string (
?access_token=) for<img>/<video>: it ends up in the nginx log and in the history. Way forward: a short token only for media, or anHttpOnlycookie read by the API. - Token in
localStorage+ cookie withoutHttpOnly. Any XSS steals the session.hrefSegurocloses the known case; a CSP on the front would close the whole class. BBX_CADASTRO_ABERTO=onby default in the package: on a mucua exposed to the internet, anyone can create an account and upload files of up to 4 GB, which sync out to the network.- The API listens on
0.0.0.0:8000(needed for the local network and Tor), with/docsopen. ConsiderBBX_DOCS=offin production. - Incomplete AP federation: deliveries now go out signed, but there is no follower registry (
seguidores_inbox), and a mucua's pubkey may come from any installed galaxy. Before turning onBBX_FED_AP, decide which galaxies are trusted. - A 4000-line
SaberService. Splitting it by subject (reading, writing, collections, events, structure) makes security review easier. - The front has ~55 type errors (
npm run check). permissions.pode_administrar_instanciareturnsTruewhen it can't read the local identity ("old behaviour"). This doesn't happen in production, but failing closed would be safer.
End-of-course exercises
- Hollow 2: make the role be recomputed in
deps._moc_from_tokenon every request (like the groups), with a short cache. Write the test first. - Hollow 6: add
BBX_DOCS=offtoapi/v3/app.pyand to the package'sbackend.env. - Hollow 4: write a Content-Security-Policy for SvelteKit (
kit.cspinsvelte.config.js) and find out what breaks. - New nature: create the
cantiganature (lyrics, performer, territory, audio) through the API only, without touching the code. What was missing? - A real sneakernet route: with two machines and a USB stick, set up a request that crosses three mucuas.
Glossary
| Term | In the code | Means |
|---|---|---|
| saber | core/saber.py | anything kept; the unit |
| nature | natures/ | the type of a saber |
| mucua | infra/mucua_local.py | an instance (the baobab's fruit) |
| galaxy (galáxia) | SaberRepository | a collection = a git repository |
| mocambola | nature mocambola | a person |
| territory (território) | nature territorio | the ground of a mucua |
| Sankofa | infra/sankofa.py | the git/annex facade (go back and fetch it) |
| link | services/links.py | a git remote of a galaxy |
| route (rota) | nature rota | a physical sneakernet path |
| request (pedido) | nature pedido | "I want a copy of this file" |
| lens / application | applications/ | a way of looking at the sabers |
| OXALÁ, PAJÉ, USER | constants.ROLE_* | roles (galaxy, mucua, oneself) |
| local manager (gestor local) | mucua_local.gestores_locais | co-administrator invited by this machine |
| provenance (procedência) | data.enriquecimento | what the machine did with an attachment |
| lighthouse (farol) | infra/farol_lan.py | the announcement on the local network |
Closing
A baobab doesn't belong to whoever planted it: it belongs to whoever sits beneath it. So does the code. Read together, disagree with the comments, write tests for your community's stories.
