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 extrato bancário como comprovante, você tem um problema de fraude documental: tendo ou não um programa de fraude documental. Esta página cobre o pedaço self-service dele: ler o que o PDF registra do próprio histórico e devolver isso como JSON.

A estrutura do arquivo alcança três destes cinco padrões com força e não alcança os outros dois: uma ferramenta honesta diz em quais atua.
O PADRÃO ALCANCE DA ESTRUTURA Editar o original num editor de PDF Imprimir, alterar, digitalizar de novo Gerar a partir de um modelo Reaproveitar o extrato de outra pessoa Assinar e depois modificar com força com força mal ou nada nada com força

As duas caixas tracejadas são o limite honesto: um extrato gerado uma vez, de forma limpa, a partir de um modelo falso não tem nada de errado estruturalmente, e um extrato genuíno e intocado pertencente a outra pessoa também não. O que denuncia esses dois é layout e tipografia, outra classe de verificação, ou um saldo corrente que não fecha, a única aritmética que o motor confere.

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 e tipografia, outra classe de verificação, ou a única aritmética que este motor roda: uma coluna de saldo que para de fechar (running-balance-break).
  • 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.

O desenho no alto da página é esta lista com o alcance da estrutura ao lado de cada linha.

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.

O valor anterior não é apagado: ele continua no arquivo, mais acima, enquanto a revisão anexada decide o que a página exibe.
COMO O EMISSOR ESCREVEU · UMA PASSADA corpo do extrato xref trailer %%EOF 12 0 obj o fluxo de conteúdo com o total impresso DEPOIS DO EDITOR · UMA REVISÃO ANEXADA os mesmos bytes, intocados 12 0 obj (novo) xref trailer /Prev substitui A entrada mais nova vence, então o total exibido é o novo. A versão anterior continua no arquivo: dá para renderizar as duas.
  • 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, pipelines 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 legítimas, 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.

A diferença não é a qualidade da detecção: é quantos passos existem entre "temos esse problema" e a primeira resposta.
PLATAFORMA CORPORATIVA solicitardemonstração ciclo devendas contrato,mínimo anual integração fila de revisãohumana latência medida em minutos SELF-SERVICE crie uma conta pegue uma chave uma chamada HTTP resposta síncrona As plataformas do topo do mercado são genuinamente boas, e genuinamente do tamanho de uma corporação. A troca aqui é honesta e está dita logo abaixo.

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: 50 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.37.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": "medium",
      "title": "PDF editing tool in the production chain (iLovePDF)",
      "detail": "The document's metadata names iLovePDF in its production chain. Unlike a word processor or a design tool, these take an existing PDF as input and write a new one … The file also carries 2 revisions, so it was written more than once.",
      "evidence": {
        "tools": ["iLovePDF"],
        "editorTools": ["iLovePDF"],
        "origin": "pdf-editor",
        "matches": [
          { "field": "Info:Producer", "value": "iLovePDF", "tool": "iLovePDF", "category": "online-editor", "origin": "pdf-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."
}
A faixa alta é reservada, não alcançada por acúmulo: um monte de achados fracos para em 69, e é isso que torna riskBand === "high" citável num parecer.
riskScore acúmulo de achados fracos faixa alta 0 69 70 100 Qualquer sinal de severidade alta força a pontuação a pelo menos 70. Nenhuma soma de achados fracos chega lá.

riskScore é uma agregação ponderada, não uma probabilidade. 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: a referência 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:

Encaminhar é o desenho que funciona: as três faixas viram três filas, e nenhuma delas é uma recusa automática.
riskBand low segue automaticamente elevated revisão manual high revisão manual, com a evidência anexada e um pedido de documento novo Nenhuma das três é uma recusa automática. Recusar com base num sinal estrutural recusa clientes reais que apenas re-salvaram o arquivo.
  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 severidades 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 para entender o conteúdo. Não há OCR nem conferência de nome. A única aritmética que ele faz é a do saldo corrente: desde o motor 1.25.0, running-balance-break aponta uma coluna de saldo que para de fechar, depois que a coluna provou ser um saldo, e não diz qual número está errado nem por quê. Ele não vai dizer que um saldo final diverge de um total impresso em outro lugar, nem que uma transação nunca aconteceu.
  • 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

Abra a amostra "Editado após a criação": o mesmo relatório que a API devolve, sobre um extrato fictício cujo total impresso foi trocado por uma revisão anexada, sem conta e sem cota. Depois passe por ele um extrato que você sabe ser genuíno e 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: o arquivo é enviado por HTTPS, processado em memória e descartado quando a resposta é escrita, num servidor em Helsinque, na Finlândia (privacidade). Depois pegue uma chave: 50 documentos por mês de graça, US$ 29/mês para 1.000, US$ 199/mês para 10.000, US$ 749/mês para 50.000. Os termos completos estão em preços.

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

Leitura relacionada