Fraude em avaliações falsas: como vincular CPF para reviews autenticados

Descubra como usar validação de CPF via API para autenticar avaliações de produtos e eliminar reviews falsos em e-commerce.

Redação CPFHub.io
Redação CPFHub.io
··10 min de leitura
Fraude em avaliações falsas: como vincular CPF para reviews autenticados

Vincular cada avaliação a um CPF verificado é a forma mais eficaz de garantir que reviews são escritos por compradores reais — eliminando contas falsas e avaliações coordenadas de raiz. Com a API da CPFHub.io, a verificação de identidade acontece em milissegundos: basta uma chamada GET https://api.cpfhub.io/cpf/{CPF} com o header x-api-key para confirmar que o avaliador existe e é quem diz ser.

Introdução

Avaliações de produtos são um dos fatores mais influentes na decisão de compra online. Estudos indicam que mais de 90% dos consumidores leem avaliações antes de comprar, e produtos com notas altas vendem significativamente mais. Essa influência criou um mercado paralelo de avaliações falsas -- tanto positivas (para inflar vendas) quanto negativas (para sabotar concorrentes).

Vincular cada avaliação a um CPF verificado é a forma mais eficaz de garantir que reviews são escritos por compradores reais.


O problema das avaliações falsas

Fazendas de reviews

Empresas clandestinas oferecem pacotes de avaliações falsas -- por exemplo, "100 avaliações 5 estrelas por R$ 500". Essas empresas usam contas falsas criadas em massa para postar reviews genéricos e inautênticos.

Concorrência desleal

Vendedores concorrentes criam contas falsas para deixar avaliações negativas nos produtos rivais, prejudicando suas vendas e reputação.

Compradores incentivados

Alguns vendedores oferecem reembolso ou brindes em troca de avaliações positivas. Embora esses compradores sejam reais, a avaliação é enviesada e não reflete a experiência genuína.

Impacto no ecossistema

Avaliações falsas distorcem o mercado, prejudicam consumidores que tomam decisões baseadas em informações falsas, desvalorizam avaliações legítimas e corroem a confiança na plataforma como um todo.


Avaliações autenticadas por CPF

A ideia central é simples: somente contas com CPF verificado podem deixar avaliações, e cada avaliação exibe um selo de "Compra Verificada" vinculado à identidade do avaliador.

Requisitos para avaliar

O avaliador deve ter CPF verificado na plataforma. O avaliador deve ter comprado efetivamente o produto em questão. Cada CPF pode deixar apenas uma avaliação por produto. A avaliação só pode ser publicada após um período mínimo de uso do produto.

Benefícios do modelo

Elimina avaliações de contas falsas, pois cada conta exige um CPF real e único. Permite rastrear avaliadores que atuam de forma coordenada. Aumenta a confiança do consumidor nas avaliações. Protege vendedores legítimos contra sabotagem.


Implementação em Node.js

O exemplo a seguir demonstra um sistema de avaliações autenticadas com CPF.

const express = require("express");
const axios = require("axios");
const crypto = require("crypto");

const app = express();
app.use(express.json());

const CPFHUB_API_URL = "https://api.cpfhub.io/cpf";
const CPFHUB_API_KEY = "SUA_CHAVE_DE_API";
const REQUEST_TIMEOUT = 10000; // 10 segundos

// Simulação de banco de dados
const usuarios = new Map();
const compras = new Map(); // `${cpf}-${produtoId}` -> compra
const avaliacoes = new Map(); // `${cpf}-${produtoId}` -> avaliacao
const cpfsCadastrados = new Set();

function limparCpf(cpf) {
    return cpf.replace(/\D/g, "");
}

async function consultarCpf(cpf) {
    const cpfLimpo = limparCpf(cpf);

    try {
    const response = await axios.get(`${CPFHUB_API_URL}/${cpfLimpo}`, {
    headers: {
    "x-api-key": CPFHUB_API_KEY,
    Accept: "application/json",
    },
    timeout: REQUEST_TIMEOUT,
    });

    if (response.data.success) {
    return response.data.data;
    }
    return null;
    } catch (error) {
    if (error.code === "ECONNABORTED") {
    throw new Error("Timeout na consulta de CPF");
    }
    if (error.response) {
    const { status } = error.response;
    if (status === 401) throw new Error("API key inválida");
    if (status === 404) return null;
    }
    throw new Error("Erro na consulta de CPF");
    }
}

// Cadastro com CPF
app.post("/api/usuario/cadastro", async (req, res) => {
    const { nome, email, cpf } = req.body;

    if (!cpf || !nome || !email) {
    return res.status(400).json({
    erro: "Nome, email e CPF são obrigatórios",
    });
    }

    const cpfLimpo = limparCpf(cpf);

    if (cpfsCadastrados.has(cpfLimpo)) {
    return res.status(409).json({
    erro: "Este CPF já está cadastrado",
    });
    }

    try {
    const dados = await consultarCpf(cpfLimpo);
    if (!dados) {
    return res.status(422).json({
    erro: "CPF não encontrado na base de dados",
    });
    }

    const id = crypto.randomUUID();

    usuarios.set(id, {
    id,
    nome: dados.name,
    email,
    cpf: cpfLimpo,
    verificado: true,
    criadoEm: new Date().toISOString(),
    });

    cpfsCadastrados.add(cpfLimpo);

    res.json({ sucesso: true, usuarioId: id, nome: dados.name });
    } catch (error) {
    res.status(503).json({ erro: error.message });
    }
});

// Registrar compra (simulação)
app.post("/api/compra/registrar", (req, res) => {
    const { usuarioId, produtoId, nomeProduto, valor } = req.body;

    const usuario = usuarios.get(usuarioId);
    if (!usuario) {
    return res.status(404).json({ erro: "Usuário não encontrado" });
    }

    const chave = `${usuario.cpf}-${produtoId}`;

    compras.set(chave, {
    usuarioId,
    cpf: usuario.cpf,
    produtoId,
    nomeProduto,
    valor,
    dataCompra: new Date().toISOString(),
    entregue: true,
    });

    res.json({ sucesso: true, mensagem: "Compra registrada" });
});

// Publicar avaliação
app.post("/api/avaliacao/publicar", (req, res) => {
    const { usuarioId, produtoId, nota, titulo, texto } = req.body;

    // Validações básicas
    if (!usuarioId || !produtoId || nota === undefined || !texto) {
    return res.status(400).json({
    erro: "usuarioId, produtoId, nota e texto são obrigatórios",
    });
    }

    if (nota < 1 || nota > 5) {
    return res.status(400).json({
    erro: "Nota deve ser entre 1 e 5",
    });
    }

    const usuario = usuarios.get(usuarioId);
    if (!usuario) {
    return res.status(404).json({ erro: "Usuário não encontrado" });
    }

    // Verificação 1: CPF verificado
    if (!usuario.verificado) {
    return res.status(403).json({
    erro: "Apenas usuários com CPF verificado podem avaliar",
    });
    }

    // Verificação 2: Comprou o produto
    const chaveCompra = `${usuario.cpf}-${produtoId}`;
    const compra = compras.get(chaveCompra);

    if (!compra) {
    return res.status(403).json({
    erro: "Apenas compradores verificados podem avaliar este produto",
    seloDisponivel: false,
    });
    }

    // Verificação 3: Produto foi entregue
    if (!compra.entregue) {
    return res.status(403).json({
    erro: "Aguarde a entrega do produto para avaliar",
    });
    }

    // Verificação 4: Período mínimo após entrega (7 dias)
    const dataCompra = new Date(compra.dataCompra);
    const agora = new Date();
    const diasDesdeCompra = (agora - dataCompra) / (1000 * 60 * 60 * 24);

    // Em produção, usar data de entrega em vez de data de compra
    const DIAS_MINIMOS = 7;
    if (diasDesdeCompra < DIAS_MINIMOS) {
    return res.status(403).json({
    erro: `Aguarde ${DIAS_MINIMOS} dias após a compra para avaliar`,
    diasRestantes: Math.ceil(DIAS_MINIMOS - diasDesdeCompra),
    });
    }

    // Verificação 5: Apenas uma avaliação por CPF por produto
    const chaveAvaliacao = `${usuario.cpf}-${produtoId}`;
    if (avaliacoes.has(chaveAvaliacao)) {
    return res.status(409).json({
    erro: "Você já avaliou este produto",
    avaliacaoExistente: avaliacoes.get(chaveAvaliacao).id,
    });
    }

    // Cria avaliação autenticada
    const avaliacaoId = crypto.randomUUID();
    const avaliacao = {
    id: avaliacaoId,
    produtoId,
    cpfHash: crypto
    .createHash("sha256")
    .update(usuario.cpf)
    .digest("hex")
    .substring(0, 16),
    nomeExibicao: gerarNomeExibicao(usuario.nome),
    nota,
    titulo: titulo || "",
    texto,
    compraVerificada: true,
    dataPublicacao: agora.toISOString(),
    diasAposCompra: Math.floor(diasDesdeCompra),
    util: 0,
    denuncias: 0,
    };

    avaliacoes.set(chaveAvaliacao, avaliacao);

    res.json({
    sucesso: true,
    avaliacaoId,
    selo: "COMPRA_VERIFICADA",
    mensagem: "Avaliação publicada com sucesso",
    });
});

function gerarNomeExibicao(nomeCompleto) {
    const partes = nomeCompleto.split(" ");
    if (partes.length < 2) return `${partes[0].charAt(0)}***`;
    const primeiro = partes[0];
    const ultimo = partes[partes.length - 1];
    return `${primeiro} ${ultimo.charAt(0)}.`;
}

// Listar avaliações de um produto
app.get("/api/avaliacao/produto/:produtoId", (req, res) => {
    const { produtoId } = req.params;

    const avaliacoesProduto = [];

    for (const [chave, avaliacao] of avaliacoes) {
    if (avaliacao.produtoId === produtoId) {
    avaliacoesProduto.push({
    id: avaliacao.id,
    nome: avaliacao.nomeExibicao,
    nota: avaliacao.nota,
    titulo: avaliacao.titulo,
    texto: avaliacao.texto,
    selo: avaliacao.compraVerificada ? "COMPRA_VERIFICADA" : null,
    diasAposCompra: avaliacao.diasAposCompra,
    data: avaliacao.dataPublicacao,
    util: avaliacao.util,
    });
    }
    }

    // Calcula média
    const media =
    avaliacoesProduto.length > 0
    ? avaliacoesProduto.reduce((acc, a) => acc + a.nota, 0) /
    avaliacoesProduto.length
    : 0;

    res.json({
    produtoId,
    mediaNotas: Math.round(media * 10) / 10,
    totalAvaliacoes: avaliacoesProduto.length,
    percentualVerificado:
    avaliacoesProduto.length > 0
    ? Math.round(
    (avaliacoesProduto.filter((a) => a.selo).length /
    avaliacoesProduto.length) *
    100
    )
    : 0,
    avaliacoes: avaliacoesProduto.sort(
    (a, b) => new Date(b.data) - new Date(a.data)
    ),
    });
});

// Denunciar avaliação suspeita
app.post("/api/avaliacao/:avaliacaoId/denunciar", (req, res) => {
    const { avaliacaoId } = req.params;
    const { motivo } = req.body;

    for (const [, avaliacao] of avaliacoes) {
    if (avaliacao.id === avaliacaoId) {
    avaliacao.denuncias += 1;

    // Auto-ocultação após 5 denúncias
    if (avaliacao.denuncias >= 5) {
    avaliacao.status = "OCULTA_POR_DENUNCIAS";
    }

    return res.json({
    sucesso: true,
    mensagem: "Denúncia registrada",
    });
    }
    }

    res.status(404).json({ erro: "Avaliação não encontrada" });
});

app.listen(3000, () => {
    console.log("Servidor rodando na porta 3000");
});

Detecção de padrões suspeitos

Mesmo com a exigência de CPF verificado, é possível que avaliações enviesadas passem pelo sistema -- por exemplo, quando vendedores oferecem incentivos para compradores reais. A análise de padrões ajuda a detectar esses casos.

Indicadores de reviews incentivados

Múltiplas avaliações 5 estrelas publicadas no mesmo dia para o mesmo produto. Avaliações com texto muito curto ou genérico, como "Produto excelente, recomendo". Compradores que avaliam muitos produtos do mesmo vendedor em curto período. Compras de valor mínimo seguidas de avaliação positiva detalhada.

Indicadores de sabotagem

Múltiplas avaliações 1 estrela de contas recém-criadas. Texto das avaliações negativas com estrutura similar, sugerindo coordenação. Avaliações negativas concentradas em produtos de um mesmo vendedor.


Exibição e transparência

A forma como as avaliações são exibidas ao consumidor é tão importante quanto a validação.

O selo "Compra Verificada" deve ser visualmente destacado, indicando que o avaliador comprou o produto e tem CPF verificado. O nome do avaliador deve ser parcialmente mascarado para proteger a privacidade, mas suficientemente identificável para transmitir autenticidade. O tempo entre a compra e a avaliação deve ser exibido, pois avaliações feitas após semanas de uso são mais confiáveis. A porcentagem de avaliações verificadas no total indica o nível de confiabilidade das notas do produto.


Privacidade e LGPD

Vincular avaliações a CPFs exige cuidado especial com a proteção de dados.

O CPF nunca deve ser exibido publicamente nas avaliações. Em vez disso, use um hash parcial como identificador interno. O consumidor deve ser informado, de forma clara e acessível, que sua avaliação será vinculada ao seu CPF para fins de autenticação. A ANPD orienta que o tratamento de dados pessoais deve ser transparente e proporcional à finalidade declarada. A API da CPFHub.io opera em conformidade com a LGPD, garantindo que os dados trafeguem de forma segura e sejam usados exclusivamente para a finalidade de verificação.


Perguntas frequentes

O que são reviews fraudulentos e como afetam e-commerces?

São avaliações criadas por contas falsas para inflar ou derrubar a reputação de produtos. Afetam a decisão de compra de clientes legítimos e podem gerar penalizações em marketplaces. Contas com CPF verificado têm custo de criação muito maior para fraudadores.

Como vincular avaliações ao CPF do comprador?

Permita avaliações apenas de compradores que tenham CPF verificado na conta e tenham realizado a compra do produto avaliado. Esse duplo vínculo (CPF real + compra confirmada) garante que a avaliação vem de uma pessoa real com experiência direta com o produto.

Isso não viola a privacidade do avaliador?

O CPF é usado internamente para verificar a autenticidade — não é exibido publicamente. A avaliação é vinculada à conta do usuário, não ao número do CPF. A LGPD permite esse uso com base em interesse legítimo (integridade do sistema de avaliações).

Um mesmo CPF pode avaliar o mesmo produto várias vezes?

Com a validação ativa, não. O sistema limita uma avaliação por CPF por produto comprado. Isso impede que a mesma pessoa crie múltiplas contas para avaliar repetidamente, mesmo que use e-mails diferentes.


Conclusão

Avaliações falsas são um problema que corrói a confiança no e-commerce. Vincular cada review a um CPF verificado e a uma compra real transforma o sistema de avaliações de um campo aberto para manipulação em uma fonte confiável de informação para consumidores. A API da CPFHub.io torna essa verificação simples e escalável, operando em ~900ms sem bloquear requisições mesmo quando o volume de consultas ultrapassa o plano contratado.

Cadastre-se em cpfhub.io — 50 consultas mensais gratuitas, sem cartão de crédito — e comece hoje mesmo.

CPFHub.io

Pronto para integrar a API?

50 consultas gratuitas para testar agora. Sem cartão de crédito. Acesso imediato à documentação.

Redação CPFHub.io

Sobre a redação

Redação CPFHub.io

Time editorial especializado em APIs de CPF, identidade digital e compliance no mercado brasileiro. Produzimos guias técnicos, análises regulatórias e tutoriais sobre LGPD e KYC para desenvolvedores e líderes de produto.

WhatsAppFale conosco via WhatsApp