Parte IV — Copa, chão e cuidado
11 · Cuidar da árvore
Baobá velho tem oco no tronco, e o oco também é parte da árvore. Este módulo lista os ocos que a análise de outubro de 2026 encontrou — os que foram fechados e os que ficam como trabalho da comunidade.
Corrigidos na 3.3
| # | Problema | Onde | Como foi fechado | Teste |
|---|---|---|---|---|
| 1 | Inbox ActivityPub sempre montada, sem assinatura, com upsert no uuid escolhido por quem envia: qualquer pessoa sobrescrevia o saber de um OXALÁ, da mucua ou da galáxia, e o commit se espalhava no sync | api/v3/activitypub.py, federacao/ingestao.py | rota só com BBX_FED_AP=on; HTTP Signature de mucua conhecida (Digest + Date); ingestão não toca saber local, não aceita identidade nem uuid malformado | test_federacao_inbox_segura.py |
| 2 | Token EdDSA de outra mucua: qualquer mucua conhecida emitia token com o sub de um OXALÁ local e mucua = local, e ganhava a administração da instância; uma cópia forjada do saber da mucua local permitia emitir tokens "locais" | services/auth.py | emissor local só com a chave do disco; mucua de fora só responde pelas próprias mocambolas; mucua e username recalculados; IdP externo sempre USER | test_token_federado_recalcula_papel.py |
| 3 | Download de anexo, thumbnail e capa de coleção sem checagem de leitura: acl, privado, rascunho e galáxia restrita saíam para anônimo | services/saber_service.py, api/v3/saberes.py, colecoes.py | content_path, thumbnail_path, colecao_mosaico_path recebem actor e passam por can(READ) | test_vazamentos_de_leitura.py |
| 4 | XSS: [x](javascript:…) no markdown e URLs de campos do saber viravam links executáveis | front lib/util/markdown.ts e páginas | hrefSeguro | — |
| 5 | SVG servido inline pela API na mesma origem do site executava script | api/v3/saberes.py | CSP sandbox + nosniff | — |
| 6 | Sem limite de tentativas de senha (/auth/login, /auth/token, /xmpp/extauth) | services/auth.py | freio por conta (10 erros em 15 min) | test_freio_login.py |
| 7 | git clone <url> com url vinda da API: --upload-pack=… executaria comando | infra/sync/*.py | -- e recusa de url que começa com - | — |
| 8 | extauth do XMPP alcançável pela internet | nginx | allow 127.0.0.1 | — |
Ocos que ficam (para a comunidade decidir)
password_hashviaja no git. Toda galáxia clonada leva os hashes de todas as contas. PBKDF2 com 200 mil rodadas atrasa, mas não impede ataque offline. Caminho: mover a senha para fora dosaber.bbx(como as chaves privadas) ou trocar por Argon2/scrypt mais caro.- Token de 7 dias com o papel carimbado. Rebaixar alguém só vale no próximo login. Os grupos já são resolvidos por requisição — o papel pode seguir o mesmo caminho, ou o token pode durar menos com renovação.
- Token na query string (
?access_token=) para<img>/<video>: fica no log do nginx e no histórico. Caminho: token curto só para mídia, ou cookieHttpOnlylido pela API. - Token no
localStorage+ cookie semHttpOnly. Qualquer XSS rouba a sessão. OhrefSegurofecha o caso conhecido; uma CSP no front fecharia a classe inteira. BBX_CADASTRO_ABERTO=onpor padrão no pacote: numa mucua exposta na internet, qualquer pessoa cria conta e envia arquivos de até 4 GB, que sincronizam para a rede.- API escuta em
0.0.0.0:8000(necessário para a rede local e para o Tor), com/docsaberto. ConsiderarBBX_DOCS=offem produção. - Federação AP incompleta: as entregas agora saem assinadas, mas não há registro de seguidores (
seguidores_inbox), e a pubkey de uma mucua pode vir de qualquer galáxia instalada. Antes de ligarBBX_FED_AP, definir de quais galáxias vale a confiança. SaberServicecom 4000 linhas. Dividir por assunto (leitura, escrita, coleções, eventos, estrutura) facilita revisão de segurança.- Front com ~55 erros de tipo (
npm run check). permissions.pode_administrar_instanciadevolveTruequando não consegue ler a identidade local ("comportamento antigo"). Em produção isso não acontece, mas falhar fechado seria mais seguro.
Exercícios de fim de curso
- Oco 2: faça o papel ser recalculado em
deps._moc_from_tokena cada requisição (como os grupos), com cache curto. Escreva o teste antes. - Oco 6: acrescente
BBX_DOCS=offemapi/v3/app.pye nobackend.envdo pacote. - Oco 4: escreva uma Content-Security-Policy para o SvelteKit (
kit.cspemsvelte.config.js) e descubra o que quebra. - Nova nature: crie a nature
cantiga(letra, intérprete, território, áudio) só pela API, sem mexer no código. O que faltou? - Rota de sneakernet real: monte, com duas máquinas e um pendrive, um pedido que atravesse três mucuas.
Glossário
| Termo | No código | Quer dizer |
|---|---|---|
| saber | core/saber.py | qualquer coisa guardada; a unidade |
| nature | natures/ | o tipo de um saber |
| mucua | infra/mucua_local.py | uma instância (o fruto do baobá) |
| galáxia | SaberRepository | um acervo = um repositório git |
| mocambola | nature mocambola | uma pessoa |
| território | nature territorio | o chão de uma mucua |
| Sankofa | infra/sankofa.py | a fachada do git/annex (voltar e buscar) |
| link | services/links.py | um remote git de uma galáxia |
| rota | nature rota | caminho físico de sneakernet |
| pedido | nature pedido | "quero uma cópia deste arquivo" |
| lente / aplicação | applications/ | um jeito de ver os saberes |
| OXALÁ, PAJÉ, USER | constants.ROLE_* | papéis (galáxia, mucua, si mesmo) |
| gestor local | mucua_local.gestores_locais | co-administrador convidado por esta máquina |
| procedência | data.enriquecimento | o que a máquina fez com um anexo |
| farol | infra/farol_lan.py | o anúncio na rede local |
Fechamento
Um baobá não é de quem plantou: é de quem senta embaixo dele. O código também. Leiam juntos, discordem dos comentários, escrevam testes para as histórias da sua comunidade.
