Skip to content

Botão para remover Status de Projetos - #1974

Open
hananvictor2008 wants to merge 15 commits into
LabRedesCefetRJ:pre-master-vida-relevante-260805from
hananvictor2008:master
Open

Botão para remover Status de Projetos#1974
hananvictor2008 wants to merge 15 commits into
LabRedesCefetRJ:pre-master-vida-relevante-260805from
hananvictor2008:master

Conversation

@hananvictor2008

Copy link
Copy Markdown
Collaborator

Adicionei um botão que permite que status de projetos sejam removidos caso não estejam sendo utilizados, permitindo assim correção de erros caso um status incorreto tenha sido criado
Captura de tela de 2026-08-14 18-11-46

…rw4-cmr2

Nome e extensão de anexos de despacho eram concatenados sem escape em
listar_despachos.php (via jQuery .html()) e em gerar_tabela_impressao.php
(saída PHP direta), permitindo que um remetente autenticado injetasse
HTML/JS executado no navegador do destinatário através do nome do arquivo
anexado. Corrigido construindo o link via DOM (.attr()/.text()) e aplicando
htmlspecialchars() na versão impressa.
O texto do despacho (CKEditor) era gravado já convertido em entidades
numéricas via FILTER_SANITIZE_SPECIAL_CHARS e depois exibido com
jQuery .text(), causando exibição de código de entidade literal em
vez do conteúdo formatado (ex.: "&LabRedesCefetRJ#60;p&LabRedesCefetRJ#62;Teste&LabRedesCefetRJ#60;/p&LabRedesCefetRJ#62;").

Além do bug de exibição, o texto era ecoado sem escape na tela de
impressão (gerar_tabela_impressao.php), permitindo XSS armazenado via
o campo de despacho.

Corrigido centralizando a sanitização em Despacho::setTexto(), que
agora usa Util::sanitizarHtmlRico() — um allowlist de tags de
formatação via DOMDocument que remove todos os atributos (inclusive
event handlers e style) e descarta tags perigosas por completo
(script, iframe, object etc.). Com o texto já sanitizado na gravação,
a exibição em listar_despachos.php passou a usar .html() para
renderizar a formatação corretamente.
Ao remover o FILTER_SANITIZE_SPECIAL_CHARS (commit a99f676), passou a
ser possível repassar $_REQUEST['texto'] como array diretamente para
Despacho::setTexto(string \$texto), disparando um TypeError não capturado
pelo catch(Exception) existente (TypeError estende Error, não Exception).
Antes, filter_var() em array retornava false, que era silenciosamente
coagido para string vazia. Agora valida explicitamente is_string() antes
de instanciar Despacho, preservando o fluxo de erro tratado original.
…idade)

listar_despachos.php passou a renderizar item.texto via .html() após
a09f6769. Isso é seguro para registros novos (sanitizados na gravação
em Despacho::setTexto), mas despachos gravados antes da existência de
qualquer sanitização (antes do commit 52b61c8, 2026-04-06) podem
conter HTML não tratado no banco. Sanitizar também em
DespachoDAO::listarTodos() garante que a leitura nunca devolve HTML
não confiável, independente de quando/como o registro foi gravado.
…ty-encoded

Registros de despacho gravados entre 2026-04-06 e o commit a99f676
tinham "<" e ">" convertidos em entidades numéricas (&LabRedesCefetRJ#60;, &LabRedesCefetRJ#62;) antes
de ir para o banco (efeito do FILTER_SANITIZE_SPECIAL_CHARS removido
naquele commit). Como essas entidades já eram texto puro, o sanitizador
apenas as re-escapava, e o navegador exibia "<p>...</p>" como texto
literal em vez de renderizar o parágrafo.

Util::sanitizarHtmlRico() agora aplica html_entity_decode() antes de
sanitizar, recuperando a marcação original desses registros. Testado
contra 18 casos (incluindo texto legítimo, payloads XSS simples e
double-encoded, e entidades legítimas) — todos permanecem seguros e
idempotentes.
…hp — refs GHSA-mxh9-855w-547r

O endpoint permitia que qualquer requisição não autenticada inserisse
registros arbitrários na tabela remessa (código, datas, valores,
id_socio), sem nenhuma checagem de sessão, permissão ou propriedade.
Também usava extract($_REQUEST), permitindo injeção de variáveis
(ex.: sobrescrever $conexao via parâmetro da requisição).

Corrigido adicionando o mesmo padrão de autenticação usado em arquivos
irmãos do diretório (session_start() + checagem de $_SESSION['usuario']
+ permissao($_SESSION['id_pessoa'], 4, 7), módulo Sócio, nível
LER/GRAVAR/EXECUTAR — mesmo nível usado por psocio_geracao.php). O
extract($_REQUEST) foi substituído por leitura explícita e tipada de
cada campo a partir de $_POST, o que também corrige um bug: como
reatribuir $_POST não atualiza $_REQUEST, o fallback de corpo JSON
(linhas que decodificam php://input) nunca alimentava os campos
quando lidos via $_REQUEST, permitindo inserção silenciosa de
registros vazios.
Endpoint não é referenciado por nenhum link, formulário ou chamada
AJAX no restante do sistema (menu.php, home.php e demais telas não
apontam para ele) — busca em todo web/ por "cadastro_remessas_geracao"
e "remessas" não encontrou nenhum caller.

Sua função (inserir remessas de boleto/carnê para sócios) já é coberta
por psocio_geracao.php, que usa o mesmo permissao(4, 7) mas com CSRF
token, security_headers.php e session_regenerate_id() — controles que
este arquivo nunca teve. Havia sido alvo do GHSA-mxh9-855w-547r
(inserção sem autenticação) corrigido no commit 7218353; como o
arquivo é código morto duplicando um fluxo já protegido, removê-lo
elimina a superfície de ataque em vez de apenas mitigá-la.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…SA-jcx6-7c59-xh2x

O endpoint redirecionava usuários não autenticados para o login, mas
não interrompia a execução (sem exit/die), então o UPDATE em
saude_medicacao rodava mesmo assim usando id_status/id_medicacao
vindos de $_REQUEST via extract(). Um atacante não autenticado podia
alterar o status de qualquer medicação sabendo/adivinhando o
id_medicacao.

Corrigido adicionando exit() após o redirect de login e
permissao($_SESSION['id_pessoa'], 5, 5) — mesmo padrão usado pelos
arquivos irmãos do módulo Saúde relacionados a medicação/prontuário
(administrar_medicamento.php, historico_prontuarios.php,
listar_sinais_vitais.php). O extract($_REQUEST) foi substituído por
filter_input(INPUT_POST, ..., FILTER_VALIDATE_INT) com validação
explícita de id_status e id_medicacao, e o tratamento de erro deixou
de ecoar a exceção para o cliente (agora vai para error_log()).

Reproduzi o PoC do advisory (POST sem cookie de sessão) contra o
ambiente local: a resposta passou a ser 302 apenas para o login, e um
teste contra um registro real confirmou que o status não é mais
alterado sem autenticação.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…p — refs GHSA-9grh-ch4x-xq8c

O endpoint redirecionava usuários não autenticados para o login, mas
não interrompia a execução (sem exit()), permitindo que um atacante
sem sessão alcançasse a lógica de validação/inserção em
funcionario_dependentes_docs usando extract($_POST) e id_dependente /
id_docdependente arbitrários. Reproduzi o PoC do advisory: o redirect
de login e a mensagem de validação de upload coexistiam na mesma
resposta, confirmando que a execução seguia após o "redirect".

Arquivo não é referenciado por nenhum form, link ou fetch em todo o
repositório, e seu próprio redirect de sucesso aponta para
web/html/profile_dependente.php, que não existe (404 confirmado) —
ou seja, estava quebrado mesmo no caminho feliz para um usuário
autenticado legítimo. Já existe um equivalente funcional e seguro em
web/html/funcionario/docdependente_upload.php (mesma tabela, com
exit() após o redirect, permissao(11, 3), validação de extensão E
mime type, e redirect que funciona). Removê-lo elimina a vulnerabilidade
por completo em vez de remendar código morto.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… refs GHSA-4724-gfqp-26jf

Arquivo web/dao/acesso.php.old ficava dentro do docroot público. Como
a extensão .old não é mapeada para o handler PHP, o Apache o servia
como texto puro em vez de executá-lo, expondo o código-fonte da classe
Acesso sem autenticação — incluindo credenciais hardcoded de banco
(usuário root, senha vazia). Confirmado ao vivo: GET no arquivo
retornava 200 com Content-Type application/x-trash e o source completo.

A classe Acesso não é referenciada em nenhum lugar do sistema (nem
esta versão .old, nem o equivalente já corrigido em
web/classes/acesso.php, que usa as constantes de config.php em vez de
credenciais hardcoded) — a aplicação usa Conexao::connect() para tudo.
Por ser um backup abandonado de uma classe obsoleta, sem nenhuma
referência, remover o arquivo elimina a exposição por completo em vez
de tentar corrigi-lo.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…view do PR LabRedesCefetRJ#1964

sanitizarHtmlRico() (adicionada no commit a99f676 para corrigir o XSS
armazenado no texto do despacho) removia incondicionalmente todos os
atributos de toda tag, incluindo style — e não permitia <span>, tag
que o CKEditor usa para aplicar cor de texto. Resultado: qualquer
formatação de cor/fundo de texto feita no editor era descartada ao
salvar, mesmo sem risco de segurança nenhum envolvido.

Corrigido permitindo <span> na allowlist de tags e adicionando
sanitizarAtributoStyle(), que filtra o atributo style mantendo
somente declarações color/background-color cujo valor bate um
formato seguro conhecido (nome de cor, hexadecimal ou rgb()/rgba());
qualquer outra propriedade ou valor fora desse formato é descartado
por completo — o valor bruto do cliente nunca é copiado pra saída,
só os valores que passaram na validação.

Testado: cor/fundo (nome, hex, rgb) preservados corretamente;
tentativas de injeção via style (expression(), url(javascript:...),
fechamento de declaração CSS pra injetar regra nova) continuam
bloqueadas; e reconfirmado que nenhum dos payloads de XSS cobertos
anteriormente (script, iframe, img onerror, svg onload, style tag,
onclick, double/entity encoding) voltou a passar.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Mapeei o preset "basic" do CKEditor configurado no build-config.js
(plugins about, basicstyles, clipboard, colorbutton, enterkey,
entities, floatingspace, indentlist, link, list, toolbar, undo,
wysiwygarea) contra o removeButtons do config.js. O recurso restante
que ainda não tinha suporte no sanitizador era o botão de Link
(criar/editar hyperlink, com aba "Target" pra abrir em nova aba) —
<a> não estava na allowlist de tags, então links viravam texto puro
sem href ao salvar.

Adicionado suporte a <a> com:
- href validado por scheme (só http/https/mailto ou URL relativa sem
  scheme; qualquer outro scheme, incluindo variantes ofuscadas com
  caracteres de controle como "java\tscript:", é bloqueado);
- target restrito aos 4 valores válidos de HTML (_blank/_self/_parent/_top);
- rel="noopener noreferrer" adicionado automaticamente quando
  target="_blank", para evitar reverse tabnabbing.

Testado: http/https/mailto/relativo/âncora preservados; target=_blank
ganha rel automaticamente; target inválido é descartado; javascript:,
data:, vbscript: e variantes com maiúsculas/caracteres de controle
continuam bloqueados; onclick e outros atributos continuam sendo
removidos normalmente. Reconfirmado que nenhum dos casos de regressão
anteriores (XSS clássico, cor/fundo do fix anterior) foi afetado.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…-advisories-fixes

Fix: 5 security advisories (unauthenticated access, source disclosure)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants