From 384587bb047529086ec3151aaf3f2719efa979c0 Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Tue, 3 Mar 2026 07:08:19 +0000 Subject: [PATCH] addded PRs for fixing issues. --- ...04-runtime-vfs-path-traversal-hardening.md | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) diff --git a/docs/pull-requests/PR-004-runtime-vfs-path-traversal-hardening.md b/docs/pull-requests/PR-004-runtime-vfs-path-traversal-hardening.md index b0bddad1..b348a2b0 100644 --- a/docs/pull-requests/PR-004-runtime-vfs-path-traversal-hardening.md +++ b/docs/pull-requests/PR-004-runtime-vfs-path-traversal-hardening.md @@ -71,6 +71,161 @@ Passos: 3. Nunca aceitar segmentos `..`, `.` ou componentes de prefixo/plataforma. 4. Antes de retornar, garantir que o caminho construido continua sob `root`. +## Plano de Execucao + +### Gate arquitetural + +Antes de iniciar a implementacao, esta PR deve congelar a seguinte decisao: + +- `exists` permanece com retorno `bool` nesta PR. +- Consequencia: caminho invalido ou tentativa de traversal em `exists` deve resultar em `false`, sem acesso ao host. +- Justificativa: mudar `exists` para `Result` propaga alteracao de contrato para `FsBackend`, `VirtualFS`, runtime e syscall, o que expande o escopo desta PR. + +Se essa decisao nao for aceita, a PR deve voltar para discussao arquitetural antes de qualquer alteracao de codigo. + +### Fase 1 - Endurecer contrato de erro + +Arquivos alvo: + +- `crates/console/prometeu-system/src/services/fs/fs_error.rs` + +Passos: + +1. Introduzir um erro explicito para caminho invalido, por exemplo `FsError::InvalidPath(String)` ou equivalente. +2. Garantir mensagem clara para os casos: + - caminho com `..`; + - componente de plataforma/prefixo inesperado; + - caminho vazio estruturalmente invalido, se a implementacao optar por rejeita-lo. + +Objetivo: + +- impedir que traversal seja reportado genericamente como `IOError` ou `Other`. + +### Fase 2 - Endurecer o `VirtualFS` + +Arquivos alvo: + +- `crates/console/prometeu-system/src/services/fs/virtual_fs.rs` + +Passos: + +1. Trocar `normalize_path(&self, path: &str) -> String` por uma funcao fallible: + - `normalize_path(path: &str) -> Result`. +2. Implementar a normalizacao unica da camada virtual: + - converter `\` para `/`; + - garantir raiz virtual absoluta; + - colapsar `.` e segmentos vazios internos irrelevantes; + - rejeitar `..`. +3. Fazer `list_dir`, `read_file`, `write_file` e `delete` falharem antes de tocar no backend quando o caminho for invalido. +4. Manter `exists` como fronteira booleana: + - se a normalizacao falhar, retornar `false`; + - nao chamar o backend nesse caso. + +Objetivo: + +- estabelecer uma unica regra de caminho virtual para toda a API publica do VFS. + +### Fase 3 - Endurecer o `HostDirBackend` + +Arquivos alvo: + +- `crates/host/prometeu-host-desktop-winit/src/fs_backend.rs` + +Passos: + +1. Trocar `resolve(&self, path: &str) -> PathBuf` por uma resolucao fallible. +2. Iterar manualmente pelos componentes do caminho e rejeitar: + - `ParentDir`; + - `CurDir`; + - `RootDir`; + - `Prefix(_)` em plataformas que exponham prefixos. +3. Construir o `PathBuf` a partir de `root` apenas com segmentos normais. +4. Validar ao final que o caminho produzido continua estritamente sob `root`. +5. Fazer `list_dir`, `read_file`, `write_file` e `delete` retornarem erro estrutural em vez de acessar o host. +6. Fazer `exists` retornar `false` para caminhos invalidos, sem side effect. + +Objetivo: + +- manter defesa em profundidade mesmo que outra camada no futuro normalize errado. + +### Fase 4 - Cobertura de testes no `prometeu-system` + +Arquivos alvo: + +- `crates/console/prometeu-system/src/services/fs/virtual_fs.rs` + +Passos: + +1. Adicionar testes unitarios de normalizacao/rejeicao para: + - `../x` + - `/../x` + - `/user/../../x` + - `\\user\\..\\..\\x` +2. Adicionar um teste que prove que `exists("../x") == false`. +3. Adicionar um mock backend com contadores ou flags para comprovar que caminhos invalidos: + - nao chegam em `read_file`; + - nao chegam em `write_file`; + - nao chegam em `delete`; + - nao chegam em `list_dir`; + - nao chegam em `exists`. + +Objetivo: + +- provar que a barreira virtual bloqueia traversal antes de qualquer backend. + +### Fase 5 - Cobertura de testes no host + +Arquivos alvo: + +- `crates/host/prometeu-host-desktop-winit/src/fs_backend.rs` + +Passos: + +1. Adicionar teste positivo de round-trip: + - criar `/user/test.txt`; + - ler; + - verificar `exists`; + - apagar. +2. Adicionar teste de traversal em leitura e escrita usando diretorio temporario: + - garantir erro para `/user/../../outside.txt`; + - garantir que nenhum arquivo e criado fora de `root`. +3. Adicionar teste para `exists` e `list_dir` com traversal: + - `exists` retorna `false`; + - `list_dir` retorna erro; + - nenhum acesso fora da raiz e observado. + +Objetivo: + +- provar que a defesa em profundidade do backend funciona mesmo isoladamente. + +### Fase 6 - Validacao final + +Comandos: + +- `cargo test -p prometeu-system` +- `cargo test -p prometeu-host-desktop-winit` + +Checklist de saida: + +- nenhuma operacao acessa caminho fora da raiz montada; +- caminhos validos continuam funcionais; +- traversal falha de forma deterministica e explicita; +- `exists` preserva contrato booleano sem vazar acesso ao host. + +## Sequencia recomendada + +1. Implementar `FsError` primeiro. +2. Endurecer `VirtualFS` e fechar os testes unitarios da camada virtual. +3. Endurecer `HostDirBackend` com defesa em profundidade. +4. Adicionar os testes de host. +5. Rodar os testes dos dois crates. + +## Riscos de execucao + +- O comportamento atual aceita caminhos permissivos como `user/file.txt`; apos esta PR eles continuarao aceitos apenas se normalizarem para uma forma absoluta segura. +- A maior fonte de expansao de escopo e tentar mudar o contrato de `exists`; esta PR nao deve fazer isso. +- Se surgir necessidade de suportar links simbolicos ou canonicalizacao real de host, isso caracteriza outra PR. + ## Criterios de Aceite - Qualquer tentativa de traversal com `..` e rejeitada em `read_file`.