fix(resources): stop exposing author email in page props - #1
Open
Guajir0-code wants to merge 1 commit into
Open
Conversation
WpPostResource serialized the whole author model into the Inertia payload. The author relation selects user_email (needed by WpAuthorService::getAvatar for the Gravatar hash), so every author address was shipped to the browser on every post of every listing. Replace it with the three fields the frontend declares in PostAuthor, and add $hidden on WpUser so an accidental full-model serialization cannot leak credentials again. Attribute access is unaffected, so getAvatar still works. phpunit.xml now pins sqlite/:memory: so the suite can boot at all. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problema
O endereço de e-mail de cada autor é servido no HTML de todas as páginas que listam posts — home, categoria, tag, autor, arquivo e post interno. Qualquer visitante lê os e-mails com um "ver código-fonte", sem login e sem ferramenta nenhuma.
Evidência
Verificado em
https://beta.sourcevortex.com.br/no dia da abertura deste PR. Lendo odata-pagedo Inertia direto do DOM:{ "ID": 2, "display_name": "Mayron Câmara", "user_nicename": "mayron", "user_email": "ma***@gmail.com" }A string
user_emailaparece 15 vezes no HTML da home (10 posts da listagem + 5 destaques do carrossel).O front-end não usa esse campo. O contrato declarado em
resources/js/types/index.d.tsé:Ou seja: o dado é enviado, ninguém consome, e ele expõe o endereço pessoal de quem escreve no site.
Causa
app/Http/Resources/WpPostResource.php:41serializa o model inteiro:A relação em
app/Models/WpPost.php:33seleciona o e-mail de propósito:E
WpUsernão define$hidden, então nada filtra o campo na serialização. Ouser_emailé legitimamente necessário —WpAuthorService::getAvatar()usa ele para montar o hash do Gravatar — só não deveria chegar ao navegador.Solução
1. Enviar apenas os campos que o front declara (
WpPostResource):2.
$hiddennoWpUsercomo segunda barreira:$hiddenafeta sótoArray()/toJson()— o acesso por atributo continua funcionando, entãogetAvatar()segue lendo$user->user_emailnormalmente. É o que impede que um futuro'author' => $modelvolte a vazar.Por que não simplesmente tirar
user_emaildoselect()Foi a primeira alternativa que considerei e ela quebra o avatar:
WpAuthorService::getAvatar()precisa do e-mail carregado na relação para gerar o hash do Gravatar na página do post. Manter o campo carregado e controlar o que sai na resposta preserva o comportamento atual.Como validar
Os testes foram verificados nos dois sentidos — rodando contra o código antes da correção, 2 deles falham como esperado:
Em produção, depois do deploy, o payload não deve mais conter a string
user_email:Impacto
user_email; os três campos que ele declara continuam idênticos.post_authorórfão serializavanull; continuanull, agora sem risco de erro no servidor.Nota sobre
phpunit.xmlO
phpunit.xmldefineDB_DATABASE=testingsemDB_CONNECTION, o que faz a suíte abortar antes de rodar qualquer teste:Este PR fixa
sqlite/:memory:para que a suíte consiga iniciar — sem isso o teste de regressão acima não roda em lugar nenhum, nem no CI. É a mudança mínima para tornar o PR verificável, não uma reforma do ambiente de testes.Fora de escopo
Tests\Feature\ExampleTestcontinua falhando. É pré-existente e não relacionado: ele fazGET /, que exige as tabelaswp_*, inexistentes no ambiente de teste. Antes deste PR a suíte nem chegava a executá-lo. A infraestrutura de fixtures que resolve isso vem em PR separado.wpAdmin.user.email. OHandleInertiaRequests::share()também expõe o e-mail do administrador, por um caminho diferente (WpAuthService). Não mexi aqui para manter este PR focado; será tratado à parte.beforeEachdo teste são o recorte mínimo do schema do WordPress que este resource toca. Um conjunto de fixtures reutilizável para todas as tabelaswp_*vem no PR de infraestrutura de testes.