Detecção de fraude em extrato bancário, como API

Para quem tem um endpoint de upload, uma pilha crescente de extratos em PDF e nenhum orçamento de compras.

Se o seu produto aceita um extrato bancário como comprovante de renda, de endereço ou de saldo, você tem um problema de fraude documental — tendo ou não um programa de fraude documental. Esta página é sobre o formato desse problema e sobre um pedaço pequeno e self-service dele: ler o que um PDF registra sobre o próprio histórico de edição e devolver isso para a sua lógica de decisão como JSON.

Por que extratos são forjados

Um extrato bancário é o documento mais aceito e menos verificável do crédito ao consumidor. Ele é pedido por financeiras e plataformas de parcelamento como prova de renda e capacidade de pagamento, por imobiliárias e proptechs como prova de que o aluguel cabe no orçamento, por plataformas de trabalho e marketplaces no cadastro para repasses, por bancos digitais como comprovante de endereço no KYC, e por corretores na renovação cadastral. Na maioria desses fluxos ele chega como um PDF que o próprio solicitante enviou, e em boa parte deles nada adiante compara aquele arquivo com o banco emissor.

Essa combinação — peso alto na decisão, artefato fornecido pelo próprio interessado, nenhuma contraparte com autoridade — é o que o torna atraente. O Open Finance elimina o problema onde está disponível e o cliente consente; o caminho do upload de PDF é o plano B que continua aberto, e é para o plano B que a pressão vai.

O incentivo nem sempre tem escala de quadrilha. Boa parte disso é uma única pessoa, dez minutos antes de um prazo, que está R$ 2.000 abaixo de um limite e acabou de descobrir que um editor de PDF gratuito online deixa redigitar um número. Essa população é grande, pouco sofisticada e — exatamente por isso — detectável.

Como é a fraude ingênua de extrato

Fraude documental sofisticada existe, e nada nesta página afirma detê-la. Mas o volume do dia a dia cai num punhado de padrões reconhecíveis:

  • Editar o original. Baixar o extrato verdadeiro do internet banking, abrir num editor de PDF no navegador, apagar um valor com branco, digitar outro, baixar o resultado. Tempo total: dois minutos. O editor escreve o próprio nome nos metadados do arquivo e, dependendo da ferramenta, anexa uma atualização incremental ou reescreve o documento inteiro.
  • Imprimir, alterar, digitalizar de novo. Ou o equivalente digital: renderizar o extrato como imagem, editar a imagem, embrulhar de volta num PDF. Isso derrota verificações no nível do texto e produz um arquivo cujas páginas são imagens de página inteira. Muitas vezes o falsificador quer que os números sejam selecionáveis e acrescenta uma camada de texto, ou a ferramenta de edição joga texto vetorial por cima da imagem.
  • Gerar a partir de um modelo. Comprar ou montar um modelo de extrato, preencher com transações inventadas, exportar. Esses arquivos podem parecer impecáveis na tela e carregar metadados perfeitamente coerentes, porque foram genuinamente gerados uma vez por uma única ferramenta. A forense estrutural é fraca aqui; o que os denuncia normalmente é layout, tipografia e aritmética — outra classe de verificação.
  • Reaproveitar o de outra pessoa. O mesmo PDF, reenviado com um nome trocado, ou um extrato intacto pertencente a outra pessoa. Não há absolutamente nada de errado com a estrutura do arquivo.
  • Assinar e depois modificar. Onde extratos são assinados digitalmente — comum em partes da Europa e da América Latina — anexar uma atualização incremental depois da assinatura deixa a assinatura intacta sobre o intervalo de bytes original e o conteúdo novo fora dele. Alguns leitores mostram isso claramente; os usuários clicam adiante.

Repare quais desses são atacáveis olhando a estrutura do arquivo: os dois primeiros e o quinto, com força; o terceiro e o quarto, mal ou nada. Uma ferramenta honesta diz em qual balde ela joga.

Os rastros que ela deixa

Um extrato é um documento gerado por máquina. Essa é toda a base do método: o arquivo deveria ter sido escrito exatamente uma vez, por uma biblioteca do lado do servidor, numa única passada, com um conjunto de metadados e um subconjunto de fonte por tipografia. Cada desvio de "escrito uma vez por uma ferramenta" é uma pergunta que você pode fazer ao solicitante.

  • Mais de uma revisão. Bytes anexados depois do primeiro %%EOF. Mais forte quando uma revisão posterior sobrescreve um objeto que já existia e que carrega dados de página, de fluxo de conteúdo ou de imagem — a aparência exibida mudou depois da geração.
  • Um editor de consumo na cadeia de ferramentas. Conversores online, editores de PDF de desktop, editores de imagem, esteiras de re-salvamento do Office. Um core bancário não emite extratos passando pelo Photoshop.
  • Dois repositórios de metadados que discordam. Dicionário Info contra pacote XMP. Editores frequentemente atualizam um e esquecem o outro, e às vezes só um deles chega a nomear o editor.
  • Dois subconjuntos de uma mesma tipografia. Glifos da mesma fonte incorporados em duas ocasiões separadas — a assinatura de texto acrescentado a um documento existente por uma segunda ferramenta.
  • Texto vetorial visível sobre uma digitalização de página inteira. Documentos digitalizados legítimos carregam nenhuma camada de texto ou uma camada de OCR invisível. Um punhado de trechos de glifos visíveis sobre uma página rasterizada é como valores numa digitalização são alterados.
  • Bytes fora do /ByteRange de uma assinatura. Conteúdo anexado depois da assinatura, comprovável comparando dois números inteiros, independentemente de o certificado validar.

Cada um deles está documentado por completo — incluindo as explicações benignas, que importam mais que as maliciosas para quem monta uma fila de revisão — no guia das famílias de sinais. A versão manual das mesmas verificações está em como saber se um PDF foi editado.

Por que a ferramenta corporativa está fora de alcance

Detecção de fraude documental é um problema comercial resolvido no topo do mercado. As plataformas estabelecidas são genuinamente boas e genuinamente do tamanho de uma corporação: um formulário de "solicite uma demonstração" em vez de uma página de cadastro, um ciclo de vendas, um contrato, um mínimo anual e um preço por documento que pressupõe volume institucional. Várias delas também envolvem uma etapa de revisão humana, o que significa latência medida em minutos e os documentos dos seus clientes parados na fila de revisão de outra empresa.

Se vocês são três pessoas de engenharia numa financeira em estágio inicial processando algumas centenas de extratos por mês, nada disso é comprável. O resultado de sempre é que o endpoint de upload sobe sem nenhuma verificação documental e o problema é redescoberto depois do primeiro prejuízo.

A Tamperlens é deliberadamente a ponta pequena desse mercado: crie uma conta, pegue uma chave, faça uma chamada HTTP. Sem conversa de vendas, sem mínimo, sem fila de revisão. A troca é honesta — é um motor de forense estrutural, não uma plataforma completa de fraude, e devolve evidência em vez de decisões.

Sem estado, por projeto. Os bytes enviados são lidos em memória e descartados quando a resposta é escrita. Nenhum documento é armazenado, nenhum documento é registrado em log, nada é enviado a terceiros, e não há etapa de revisão humana. Para um time de compliance, "nós nunca ficamos com o arquivo" é uma conversa materialmente mais fácil que um aditivo de tratamento de dados sobre uma fila de revisão.

A API, em uma chamada

Um endpoint: POST /api/v1/inspect. Ele aceita multipart/form-data com um campo file, ou um corpo application/pdf puro, até 10 MB. A autenticação é uma chave bearer. Plano gratuito: 25 documentos por mês, sem cartão.

multipart

curl -s https://tamperlens.com/api/v1/inspect \
  -H "Authorization: Bearer tl_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -F [email protected] | jq .

corpo puro — sem codificação multipart, útil a partir de um worker

curl -s https://tamperlens.com/api/v1/inspect \
  -H "Authorization: Bearer tl_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/pdf" \
  --data-binary @extrato.pdf | jq .

A resposta para um extrato que passou por um editor online gratuito é assim. As strings de detail estão abreviadas aqui por causa da largura; na resposta real são parágrafos completos, e evidence carrega os deslocamentos e números de objeto por trás de cada afirmação. O relatório sai em inglês na API e em português nas páginas /pt/ — a mesma resposta traz um message com código e valores, para você renderizar no idioma que quiser.

200 OK

{
  "id": "insp_2f1e9c04-7b3a-4d51-9f0e-6c2a18d4bb71",
  "engineVersion": "1.2.0",
  "summary": {
    "riskScore": 100,
    "riskBand": "high",
    "signalCount": 3,
    "revisions": 2
  },
  "signals": [
    {
      "id": "incremental-updates",
      "severity": "high",
      "title": "Page content was replaced after the document was generated",
      "detail": "The file contains 2 revisions. A later revision re-writes 2 object(s) that already existed in an earlier revision and that carry page, content-stream or image data (objects 12, 14). …",
      "evidence": {
        "revisions": 2,
        "updatesAfterCreation": 1,
        "eofOffsets": [118842, 184102],
        "startxrefValues": [118201, 183640],
        "revisionChainBroken": false,
        "contentObjectsOverwritten": [
          { "obj": 12, "kind": "content" },
          { "obj": 14, "kind": "page" }
        ]
      }
    },
    {
      "id": "producer-fingerprint",
      "severity": "high",
      "title": "Consumer editing tool in the production chain (iLovePDF)",
      "detail": "The document's metadata names iLovePDF in its production chain. Statements, invoices and certificates are normally emitted directly by a server-side generator … corroborated here by 2 document revisions.",
      "evidence": {
        "tools": ["iLovePDF"],
        "matches": [
          { "field": "Info:Producer", "value": "iLovePDF", "tool": "iLovePDF", "category": "online-editor" }
        ],
        "producer": "iLovePDF",
        "creator": "iText 7.2.5",
        "revisions": 2,
        "fullPageImagePages": []
      }
    },
    {
      "id": "id-inconsistency",
      "severity": "medium",
      "title": "Trailer /ID marks the file as changed since creation",
      "detail": "The trailer /ID array holds two different identifiers. The first element is set once when a document is created and must never change …",
      "evidence": {
        "idOriginal": "8f2c...a91b",
        "idCurrent": "41de...77c0",
        "trailerCount": 2
      }
    }
  ],
  "document": {
    "pages": 2,
    "producer": "iLovePDF",
    "creator": "iText 7.2.5",
    "creationDate": "2026-01-04T10:02:00.000Z",
    "modDate": "2026-01-06T18:41:00.000Z",
    "encrypted": false,
    "signed": false,
    "revisions": 2,
    "sizeBytes": 184320
  },
  "disclaimer": "Tamperlens reports risk signals, not authenticity verdicts. Signals can have benign causes; combine them with your own decision logic."
}

riskScore é uma agregação ponderada, não uma probabilidade. O contrato é deliberadamente estreito: qualquer sinal de gravidade alta força a pontuação a pelo menos 70, e a faixa alta é reservada para sinais de gravidade alta — um acúmulo de achados fracos é limitado a 69. Então riskBand === "high" significa "pelo menos um achado que por si só estabelece uma alteração", que é uma afirmação defensável num parecer. Os pesos são versionados por engineVersion; os mesmos bytes sempre produzem a mesma pontuação.

Referência completa dos campos, códigos de erro e cotas: guia da API e a especificação OpenAPI em /docs.

Ligando sinais a uma decisão

Todo o desenho pressupõe que a decisão é sua. Alguns padrões que funcionam:

  1. Encaminhe, não recuse. Mapeie riskBand a uma fila: low segue automaticamente, elevated vai para revisão manual, high vai para revisão manual com a evidência anexada e um pedido de documento novo. Recusar automaticamente com base num sinal estrutural vai recusar clientes reais que apenas re-salvaram um arquivo no visualizador do sistema.
  2. Guarde a evidência, não o arquivo. Persista os ids dos sinais, as gravidades e os objetos evidence junto à proposta. Essa é a sua trilha de auditoria, ela é pequena e não contém conteúdo do documento.
  3. Peça uma substituição específica. A resposta mais eficaz a um sinal estrutural é "por favor baixe de novo o PDF original do seu banco e envie sem abrir em nenhum outro aplicativo". Clientes genuínos conseguem fazer isso; o segundo envio costuma ser mais informativo que o primeiro.
  4. Ajuste por sinal, não por pontuação. Se o seu fluxo legitimamente envolve clientes assinando extratos, incremental-updates vai disparar o tempo todo e você deve reduzir o peso dele nesse fluxo, mantendo signature-coverage e font-anomalies com peso cheio.
  5. Meça o seu próprio tráfego primeiro. Rode o verificador ou o plano gratuito sobre uma amostra de extratos que você já acredita serem genuínos, por banco emissor, antes de definir qualquer limiar. Strings de produtor e hábitos de revisão variam enormemente entre bancos, e saber como é o "normal" da sua população real de clientes vale mais que qualquer padrão que a gente pudesse embarcar.

O que isto não faz

Dito com todas as letras, porque uma ferramenta de fraude que se vende além do que entrega é pior que nenhuma:

  • Não lê o seu extrato. Não há OCR, nem interpretação de transações, nem aritmética de saldo, nem conferência de nome. Ele não vai dizer que um saldo final não bate com a soma das transações.
  • Não verifica identidade nem titularidade da conta. Um extrato perfeitamente genuíno e intocado pertencente a outra pessoa pontua low, corretamente.
  • Não detecta uma falsificação bem-feita a partir de modelo. Um arquivo gerado uma vez, de forma limpa, a partir de um modelo falso não tem nada de errado estruturalmente.
  • Não valida a criptografia da assinatura. Ele reporta o que uma assinatura cobre. Validar certificado e cadeia de confiança é outro trabalho.
  • Não resiste para sempre a um adversário determinado. Um falsificador que conhece o histórico de revisões consegue achatá-lo. Esse é um limite real — e também o motivo de o conjunto de sinais ser versionado e crescer: cada nova técnica de evasão deixa o seu próprio rastro.
  • Não emite veredicto. Não existe um campo "fraud": true e não vai existir.

Teste primeiro num arquivo real

O verificador gratuito aceita um PDF arrastado e mostra o mesmo relatório que a API devolve — sem conta, nada armazenado. Passe por ele um extrato que você sabe ser genuíno, depois um que você editou de propósito numa ferramenta online, e você verá na hora se os sinais são úteis para o seu fluxo. Depois pegue uma chave: 25 documentos por mês de graça, e os planos pagos estão em preços.

A Tamperlens reporta sinais de risco, não veredictos de autenticidade. Sinais podem ter causas benignas; combine-os com a sua própria lógica de decisão.

Leitura relacionada