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

#ProblemWhereHow it was closedTest
1ActivityPub 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 syncapi/v3/activitypub.py, federacao/ingestao.pyroute 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 uuidstest_federacao_inbox_segura.py
2EdDSA 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" tokensservices/auth.pylocal issuer only with the key on disk; an outside mucua only vouches for its own mocambolas; mucua and username recomputed; external IdP always USERtest_token_federado_recalcula_papel.py
3Attachment download, thumbnail and collection cover without a read check: acl, private, draft and restricted-galaxy content went out to anonymous usersservices/saber_service.py, api/v3/saberes.py, colecoes.pycontent_path, thumbnail_path, colecao_mosaico_path receive actor and go through can(READ)test_vazamentos_de_leitura.py
4XSS: [x](javascript:…) in markdown and URLs from saber fields became executable linksfront lib/util/markdown.ts and pageshrefSeguro—
5SVG served inline by the API on the same origin as the site ran scriptsapi/v3/saberes.pyCSP sandbox + nosniff—
6No limit on password attempts (/auth/login, /auth/token, /xmpp/extauth)services/auth.pyper-account brake (10 errors in 15 min)test_freio_login.py
7git clone <url> with a url coming from the API: --upload-pack=… would run a commandinfra/sync/*.py-- and rejecting urls that start with -—
8XMPP extauth reachable from the internetnginxallow 127.0.0.1—

Hollows that remain (for the community to decide)

  1. password_hash travels 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 of saber.bbx (like the private keys) or switch to a costlier Argon2/scrypt.
  2. 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.
  3. 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 an HttpOnly cookie read by the API.
  4. Token in localStorage + cookie without HttpOnly. Any XSS steals the session. hrefSeguro closes the known case; a CSP on the front would close the whole class.
  5. BBX_CADASTRO_ABERTO=on by 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.
  6. The API listens on 0.0.0.0:8000 (needed for the local network and Tor), with /docs open. Consider BBX_DOCS=off in production.
  7. 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 on BBX_FED_AP, decide which galaxies are trusted.
  8. A 4000-line SaberService. Splitting it by subject (reading, writing, collections, events, structure) makes security review easier.
  9. The front has ~55 type errors (npm run check).
  10. permissions.pode_administrar_instancia returns True when 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

  1. Hollow 2: make the role be recomputed in deps._moc_from_token on every request (like the groups), with a short cache. Write the test first.
  2. Hollow 6: add BBX_DOCS=off to api/v3/app.py and to the package's backend.env.
  3. Hollow 4: write a Content-Security-Policy for SvelteKit (kit.csp in svelte.config.js) and find out what breaks.
  4. New nature: create the cantiga nature (lyrics, performer, territory, audio) through the API only, without touching the code. What was missing?
  5. A real sneakernet route: with two machines and a USB stick, set up a request that crosses three mucuas.

Glossary

TermIn the codeMeans
sabercore/saber.pyanything kept; the unit
naturenatures/the type of a saber
mucuainfra/mucua_local.pyan instance (the baobab's fruit)
galaxy (galáxia)SaberRepositorya collection = a git repository
mocambolanature mocambolaa person
territory (território)nature territoriothe ground of a mucua
Sankofainfra/sankofa.pythe git/annex facade (go back and fetch it)
linkservices/links.pya git remote of a galaxy
route (rota)nature rotaa physical sneakernet path
request (pedido)nature pedido"I want a copy of this file"
lens / applicationapplications/a way of looking at the sabers
OXALÁ, PAJÉ, USERconstants.ROLE_*roles (galaxy, mucua, oneself)
local manager (gestor local)mucua_local.gestores_locaisco-administrator invited by this machine
provenance (procedência)data.enriquecimentowhat the machine did with an attachment
lighthouse (farol)infra/farol_lan.pythe 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.

vedi questo capitolo come sapere