3.9 KiB
PR-004: Runtime VFS Path Traversal Hardening
Briefing
Hoje o VirtualFS normaliza barras, mas nao canonicaliza nem rejeita segmentos ... Em seguida, o backend de host concatena o caminho recebido com a raiz montada. Isso abre espaco para escapar da raiz virtual com caminhos como /user/../../outside.txt.
Este PR endurece a fronteira entre o filesystem virtual e o filesystem do host. O objetivo e garantir que toda operacao de read/write/delete/list/exists permaneça estritamente dentro da raiz montada.
Problema
- O
VirtualFSaceita caminhos relativos e absolutos sem validacao estrutural suficiente. - O backend
HostDirBackendfazroot.join(path)sem bloquear traversal. - O problema afeta confidencialidade, integridade e isolamento do runtime.
Escopo
- Endurecer a normalizacao de caminhos no
VirtualFS. - Endurecer a resolucao no
HostDirBackend. - Garantir comportamento consistente para
read_file,write_file,delete,list_direexists. - Cobrir casos de traversal em testes unitarios.
Fora de Escopo
- Suporte a links simbolicos com politicas avancadas.
- Politicas de permissao por namespace (
/system,/user,/apps, etc). - Refactor completo da API de filesystem.
Abordagem
- Introduzir uma regra unica de validacao de caminho virtual:
- converter
\para/; - exigir caminho absoluto virtual;
- colapsar
.quando aparecer; - rejeitar qualquer segmento vazio ambiguo ou
..; - retornar erro explicito em vez de tentar "corrigir" traversal.
- converter
- Fazer o
VirtualFSoperar apenas sobre caminhos validados. - Endurecer o
HostDirBackendpara nunca confiar apenas na normalizacao acima:- resolver o caminho relativo a partir da raiz;
- rejeitar novamente qualquer tentativa de escapar;
- manter defesa em profundidade mesmo se outro backend ou chamador evoluir errado.
- Garantir que operacoes booleanas como
existsnao silenciem traversal como se fosse "arquivo inexistente" sem distinguir erro estrutural quando isso for relevante para a API.
Algoritmo
Normalizacao de caminho virtual
Entrada: path: &str
Saida: caminho virtual sanitizado ou erro.
Passos:
- Substituir
\por/. - Se o caminho nao comecar com
/, prefixar/. - Separar por
/. - Ignorar segmentos vazios e
.. - Se algum segmento for
.., falhar comFsError. - Reconstruir o caminho como
/<seg1>/<seg2>/.... - Preservar
/como raiz quando nao houver segmentos.
Resolucao no backend do host
Entrada: caminho virtual sanitizado.
Saida: PathBuf dentro de root ou erro.
Passos:
- Remover o
/inicial do caminho virtual. - Concatenar cada segmento validado manualmente em um
PathBufiniciado emroot. - Nunca aceitar segmentos
..,.ou componentes de prefixo/plataforma. - Antes de retornar, garantir que o caminho construido continua sob
root.
Criterios de Aceite
- Qualquer tentativa de traversal com
..e rejeitada emread_file. - Qualquer tentativa de traversal com
..e rejeitada emwrite_file. - Qualquer tentativa de traversal com
..e rejeitada emdelete. existselist_dirnao acessam caminhos fora da raiz montada.- Caminhos normais como
/user/save.datcontinuam funcionando. - O backend de host continua criando subdiretorios validos dentro da raiz.
Tests
- Teste unitario no
VirtualFSpara rejeitar:../x/../x/user/../../x\\user\\..\\..\\x
- Teste unitario no backend do host validando que um caminho de traversal nao resulta em acesso fora da raiz temporaria.
- Teste positivo para operacoes validas:
- criar arquivo em
/user/test.txt; - ler o mesmo arquivo;
- confirmar
exists; - apagar o arquivo.
- criar arquivo em
- Rodar:
cargo test -p prometeu-systemcargo test -p prometeu-host-desktop-winit
Risco
Baixo para a arquitetura e medio para compatibilidade, porque caminhos hoje aceitos de forma permissiva podem passar a falhar explicitamente. Esse endurecimento e desejado.