Problema
O endpoint público POST /api/enterprise interpola cinco campos controlados pelo remetente direto no
corpo HTML de um e-mail enviado para contact@anoma.ly, sem nenhum escape. AWS.sendEmail usa a mesma
string simultaneamente como corpo Text e como corpo Html, portanto o cliente de e-mail do
destinatário interpreta a marcação.
Por que é explorável
O endpoint não tem autenticação — apenas um honeypot de campo alias (linhas 65-69) e um regex de
formato de e-mail (75-78). Não há rate limit nem limite de tamanho por campo. Os campos message,
name, role, company e phone entram na string sem tratamento, e a string já contém tags <br>,
isto é, é tratada como HTML por construção.
O projeto tem DOMPurify 3.3.1 como dependência e o aplica corretamente na renderização de markdown
(packages/ui/src/components/markdown.tsx:45-48), mas não há nenhuma função de escape no caminho do
e-mail.
Evidência
packages/console/app/src/routes/api/enterprise.ts:80-86:
const emailContent = `
${body.message}<br><br>
--<br>
${body.name}<br>
${body.role}<br>
${body.company ? `${body.company}<br>` : ""}${body.email}<br>
${body.phone ? `${body.phone}<br>` : ""}`.trim()
Linhas 100-105 — o envio, com Reply-To também controlado pelo remetente:
AWS.sendEmail({
to: "contact@anoma.ly",
subject: `Enterprise Inquiry from ${body.name}`,
body: emailContent,
replyTo: body.email,
})
packages/console/core/src/aws.ts:46-55 — a mesma string vai como Text e como Html:
Body: {
Text: {
Charset: "UTF-8",
Data: input.body,
},
Html: {
Charset: "UTF-8",
Data: input.body, // <-- mesma string, interpretada como HTML
},
},
Impacto
Injeção de HTML em caixa de entrada interna. Permite:
- montar mensagens que se passam por comunicação legítima do próprio sistema
- inserir links de phishing com texto de âncora enganoso (
<a href="https://atacante">clique aqui para aprovar</a>)
- esconder o conteúdo real com marcação e inserir imagens de rastreamento
- falsificar o bloco de assinatura inteiro, inclusive o e-mail de contato, que também é interpolado
Como Reply-To é definido com body.email, a resposta da equipe vai para o endereço escolhido pelo
atacante. A execução de script não é o vetor principal (clientes de e-mail bloqueiam); a fraude visual é.
Sugestão de correção
- Escapar cada campo de usuário antes de interpolar no HTML.
- Melhor: separar os dois corpos. Mudar a assinatura de
AWS.sendEmail para receber text e html
distintos, montar o text com os valores crus e o html com os valores escapados.
- Adicionar limite de tamanho por campo.
- Adicionar rate limit por IP no endpoint, que hoje não tem nenhum.
Critérios de aceite
Labels sugeridas: security, alta
Achado da auditoria estatica de seguranca do commit 0465a5d. Relatorio completo em docs/security-audit/relatorio-auditoria-seguranca.pdf.
Problema
O endpoint público
POST /api/enterpriseinterpola cinco campos controlados pelo remetente direto nocorpo HTML de um e-mail enviado para
contact@anoma.ly, sem nenhum escape.AWS.sendEmailusa a mesmastring simultaneamente como corpo
Texte como corpoHtml, portanto o cliente de e-mail dodestinatário interpreta a marcação.
Por que é explorável
O endpoint não tem autenticação — apenas um honeypot de campo
alias(linhas 65-69) e um regex deformato de e-mail (75-78). Não há rate limit nem limite de tamanho por campo. Os campos
message,name,role,companyephoneentram na string sem tratamento, e a string já contém tags<br>,isto é, é tratada como HTML por construção.
O projeto tem DOMPurify 3.3.1 como dependência e o aplica corretamente na renderização de markdown
(
packages/ui/src/components/markdown.tsx:45-48), mas não há nenhuma função de escape no caminho doe-mail.
Evidência
packages/console/app/src/routes/api/enterprise.ts:80-86:Linhas 100-105 — o envio, com
Reply-Totambém controlado pelo remetente:packages/console/core/src/aws.ts:46-55— a mesma string vai como Text e como Html:Impacto
Injeção de HTML em caixa de entrada interna. Permite:
<a href="https://atacante">clique aqui para aprovar</a>)Como
Reply-Toé definido combody.email, a resposta da equipe vai para o endereço escolhido peloatacante. A execução de script não é o vetor principal (clientes de e-mail bloqueiam); a fraude visual é.
Sugestão de correção
AWS.sendEmailpara recebertextehtmldistintos, montar o
textcom os valores crus e ohtmlcom os valores escapados.Critérios de aceite
AWS.sendEmailrecebe corposTexteHtmlseparados e não reaproveita a mesma stringPOST /api/enterprisePOST /api/enterprise<a href>e<img>chega ao destinatário como texto literalLabels sugeridas: security, alta
Achado da auditoria estatica de seguranca do commit
0465a5d. Relatorio completo emdocs/security-audit/relatorio-auditoria-seguranca.pdf.