Skip to main content
Animated LureBench research atlas moving from corpus construction through adversarial stress, calibration, and reporting.

The adversarial benchmark for AI-generated fraud

One schema. Three evaluation regimes. Honest answers about what survives deployment.

CI PyPI install PyPI Version License Python Generators Status Code of Conduct Security policy DOI

See the finding · Run the benchmark · Open the LureScope browser lab ↗


Fraud detectors that score well on classic spam corpora fall apart on lures written by modern language models. LureBench measures that gap on a common footing: one schema, one harness, one leaderboard, across fraud typologies and generator families. It runs out of the box with no model downloads or API keys, and it ships baseline detectors from a keyword heuristic up to a trained classifier.

More than a corpus, it is a method for building the corpus honestly. Getting a credible answer to "can you detect AI-generated fraud?" turned out to require finding, and removing, a dataset confound that makes the problem look far easier than it is. That story is below.

New — thresholds with evidence, not just point estimates. LureBench can now export a policy only when exact finite-sample tests support a requested population false-positive rate. A 1% target at 95% confidence fails closed with fewer than 299 benign validation examples even after zero false alarms. See risk-controlled deployment policies.

New — evaluate private detectors and private deployments. The isolated container contract benchmarks any language or proprietary detector without exposing labels or corpus metadata. LureEval receipts carry signed, privacy-minimized aggregate operational evidence across organizations. Neither requires messages or row-level scores to leave their owner.

Who it's for

You are… Use LureBench to…
A security engineer / vendor Benchmark your fraud detector on a common footing, then stress-test it against attacks a real fraudster would run (robustness) before you trust its clean-data score.
A researcher Reproduce the provenance confound and its removal, add a detector in ~30 lines (docs/adding-a-detector.md), or extend the corpus with new generators and typologies.
A policy / threat-intel analyst Ground claims about "AI-generated fraud detection" in measured numbers — including where it works, and where it is close to a coin flip.
A procurement or assurance team Evaluate a proprietary image against a private held-out set, preserve an immutable report, and pool compatible signed field evidence without collecting messages.

Everything runs out of the box with no model downloads or API keys; provider keys are only needed to generate new lures or run LLM-based attacks, and never touch api.openai.com or api.anthropic.com.

The finding

Train a classifier to tell AI-written fraud from human-written fraud on a naively assembled corpus, and it looks almost perfect: near-100% recall, a 0.1% false-alarm rate, and it even generalizes to generators it never trained on. That result is a trap.

Bar chart: cross-generator AI-fraud detection AUC drops from a perfect 1.00 on the naive corpus to 0.58 (DeepSeek), 0.57 (GLM) and 0.83 (Mistral) once the corpus is distribution-matched, with two of three near the 0.50 chance line.

Inspecting the model showed it was separating corpus-of-origin, not authorship: the human phishing was older, longer, pre-tokenized, and defanged differently than the fresh LLM text. Once the two classes are distribution-matched (each human lure paired with an AI rewrite of the same lure, matched on length and defanged the same way), the separation falls apart. Cross-generator AUC drops from a perfect 1.00 to 0.58 and 0.57 for two of the three generators, barely above the 0.50 chance line. Only one model's output (Mistral) keeps a detectable signature at 0.83, and it does not transfer to the others. Distinguishing AI-authored fraud from human-authored fraud, across generators, turns out to be close to a coin flip. Full write-up in docs/provenance_results.md.

Two tasks, and why the distinction matters

A fraud lure raises two separate questions, and most tools answer only one:

  • Is this a fraud lure? (the fraud task, lure vs. benign)
  • Was this written by an LLM? (the provenance task, AI vs. human)

The first is largely a solved classical problem. A trained bag-of-words baseline near-solves it, while a keyword heuristic fails on exactly the AI lures a keyword heuristic should fail on:

Bar chart: detection rate by typology. heuristic-v0 scores 20% phishing, 83% BEC, 15% romance, 9% pig-butchering; tfidf-logreg scores 95-100% across all four.

The second question, provenance, is where the real difficulty lives, and where the confound above had to be removed before the number meant anything.

Clean accuracy is not deployment accuracy

A detector's score on clean test data is not the number that survives contact with a real fraudster. The adversary does not send the lure your model was trained on: they type vеrifу with a Cyrillic е, split a trigger word, or paraphrase the whole message. The robustness command measures what happens next. It takes the lures a detector catches, applies an attack, and reports the attack success rate — the fraction that now evade.

Bar chart: attack success rate by attack. heuristic-v0 collapses under every character attack (99% homoglyph, 99% leet, 100% zero-width, 52% whitespace); tfidf-logreg holds far better (38% homoglyph, 16% leet, 3% zero-width, 0% whitespace).

Robustness is a different axis from clean accuracy and it ranks detectors differently. The keyword baseline looks cheap and interpretable until an attacker types one homoglyph and 99% of its catches walk through. The trained model degrades gracefully instead of collapsing. That gap — not the clean-data score — is what a buyer needs to see before deploying either. Attacks come in two tiers: free deterministic character tricks (homoglyph, leet, zero-width, whitespace) and stronger LLM rewrites (llm-paraphrase, llm-keyword-evasion, which targets a detector's own most-predictive words). Full write-up in docs/adversarial-robustness.md.

Try it interactivelylive demo, no install: LureScope is the deployable companion — a small API and browser demo where you paste a message, score it, then watch an attack evade the detector live. It reuses these same detectors and attacks. Its robustness scorecard writeup reports detector-by-attack evasion rates over this corpus and shows where a normalization defense recovers the catch (and where it cannot).

How it works

flowchart LR
    S["Public corpora<br/>+ provider LLMs"] --> ING["Ingest<br/>defang · detokenize"]
    S --> GEN["Generate<br/>hard-mode · paired rewrite"]
    ING --> REV{{"Human review<br/>gate"}}
    GEN --> REV
    REV --> ASM["Assemble<br/>frozen train / test"]
    ASM --> EVAL["Evaluate<br/>leaderboard · cross-generator · robustness"]
    style REV fill:#fff3cd,stroke:#eda100,color:#0b0b0b
    style EVAL fill:#cde2fb,stroke:#2a78d6,color:#0b0b0b
    style GEN fill:#d6f2e6,stroke:#1baf7a,color:#0b0b0b

Every generated lure is defanged, provenance-logged, and held in a review: pending state until a human approves it. Nothing reaches a shard automatically. Train and test are split by a stable hash of each record id, so adding a new generator never reshuffles what was already in the test set.

What's inside

The lurebench-core corpus (20,388 records):

Class Count Detail
Human phishing + benign 19,798 David-Egea/phishing-texts (MIT), de-tokenized and defanged
AI-generated lures 590 across four typologies, three generators
— DeepSeek deepseek-v4-pro 190
— GLM glm-4.6 200
— Mistral mistral-large-latest 200

Typologies: phishing, BEC, romance, pig-butchering. The AI lures are hard-mode: written to persuade through plausibility and context rather than stock urgency and payment-demand markers.

Quickstart

python -m pip install lurebench
lurebench --help

Clone the repository when you want the bundled sample data, research artifacts, and reproducibility commands:

git clone https://github.com/immu4989/lurebench && cd lurebench
python -m pip install -e .

# score the dependency-free heuristic on the sample shard (ships in the repo)
lurebench eval --dataset data/samples/lures.jsonl --detector heuristic-v0

The full lurebench-core corpus lives on the Hugging Face Hub. Load it in one call, no manual file placement (v0.2):

from lurebench import load_core, run
from lurebench.detectors import HeuristicDetector

test = load_core("test")                       # downloads + caches from the Hub
print(run(HeuristicDetector(), test).metrics.mcc)

Reproduce the headline finding — the leave-one-generator-out provenance collapse — with one command. Point it at a naive corpus and AUC stays near 1.00 (the confound); point it at the distribution-matched set and it falls to the 0.50 chance line:

python -m pip install -e ".[train]"
lurebench cross-generator -d data/full/paired/human.jsonl -d data/full/paired/deepseek-v4-pro.jsonl \
  -d data/full/paired/glm-4.6.jsonl -d data/full/paired/mistral-large-latest.jsonl

Stress-test a detector the way a real fraudster would — perturb the lures it catches and measure how many now evade (the attack success rate). Clean accuracy is not deployment accuracy:

lurebench robustness -d data/full/core/test.jsonl -m tfidf-logreg \
  -a homoglyph -a leet -a zero-width -a whitespace

The keyword baseline looks interpretable until an attacker types vеrifу once (ASR 0.99); the trained model degrades gracefully (homoglyph ASR 0.38). See docs/adversarial-robustness.md.

Generation uses any OpenAI-compatible provider by name, with your own key:

export DEEPSEEK_API_KEY=...
lurebench generate --typology bec --n 50 --engine deepseek --hard --out staging/bec.jsonl

Export a dataset (or just the taxonomy) as a STIX 2.1 bundle for threat-intel sharing — validated against the official OASIS validator, with curated crosswalks to MITRE ATT&CK, FBI/IC3, and FinCEN:

lurebench stix -d data/full/core/test.jsonl -o lures.stix.json
lurebench stix --taxonomy-only -o taxonomy.stix.json

Benchmark a proprietary or non-Python detector through a hardened local OCI boundary. Only text, declared language/channel, task, and an opaque sequential request ID enter the container—never labels, source, typology, generator, corpus IDs, or metadata:

lurebench container-eval \
  --dataset private-heldout.jsonl \
  --image vendor-detector@sha256:<digest> \
  --out immutable-evaluation.json

The image is never pulled implicitly and runs with no network, host mounts, capabilities, privileges, or writable root. See the protocol, threat boundary, reference image, and non-guarantees.

Build a leakage-resistant v2 release candidate by clustering declared families and near duplicates before deterministic stratification. Held-out labels must be written separately from the public directory:

lurebench assemble-core-v2 \
  -s approved-a.jsonl -s approved-b.jsonl \
  -o release-candidate/public \
  --heldout-out private-evaluator/core-v2-heldout.jsonl

This is release infrastructure, not a claim that a corrected v2 corpus has already been collected or published. See benchmark validity.

Measure the cross-lingual gap — how detectors hold up when the language shifts. Across eight languages the trained baseline posts a near-perfect ~1.00 recall, which looks like flawless multilingual detection; strip the defang placeholder and it splits along script lines — Latin-script survives, but every non-Latin script collapses (Chinese 1.00→0.09, Russian 0.94→0.06, Arabic 0.98→0.04), exposing the recall as a <<link>> artifact rather than detection (see docs/multilingual.md):

lurebench multilingual -d data/full/multilingual/eval.jsonl -m tfidf-logreg -m heuristic-v0

The fix for that gap is a detector that reads meaning, not tokens: llm-judge asks an LLM over the same provider plumbing as generation (your key, never OpenAI/Anthropic) and is the strongest detector you can run without a GPU or OpenAI credits. It closes the cross-lingual gap (non-Latin artifact-controlled recall ~0.06 → ~0.94) and shrugs off the character attacks that break the baselines (homoglyph attack-success 1.00 → 0.08), with a semantic paraphrase its one real weakness. Full write-up and honest limits in docs/llm-detector.md:

export DEEPSEEK_API_KEY=...   # or MISTRAL_API_KEY / ZHIPUAI_API_KEY
lurebench eval -d data/full/core/test.jsonl -m llm-judge

Six models, four questions

With an aggregator key (openrouter) one run scores a whole panel, so the LLM rows are no longer a single provider's word. Measured across gpt-5-nano, gemini-2.5-flash-lite, deepseek-v4-flash, qwen-2.5-7b, llama-3.1-8b and mistral-nemo:

  • Leaderboard — every judge lands below the trained baseline on clean data (AUC 0.82–0.94 against tfidf's 0.99), and the scored column shows how many records each was willing to answer.
  • Multilingual — the practical win. Artifact-controlled, deepseek-v4-flash reads Arabic 0.93 / Russian 0.78 / Chinese 0.75 at a 1% false-positive rate, where the trained baseline collapses to 0.04 / 0.06 / 0.09. Every row carries an FPR, because on an all-fraud shard a detector that flags everything scores a perfect 1.00 in nine languages.
  • Provenance — the null result. Asked to tell AI-written fraud from human-written fraud on distribution-matched data, four of six models sit at or below chance (AUC 0.46–0.53), and three simply answer "AI" every time. The confound finding above is not something a bigger model reads its way out of.
  • Adaptive robustness — the inversion. Let the attacker rewrite up to five times instead of once and the ordering flips: the trained baseline holds at 9% evasion while the judges reach 35–40%. Character attacks break token models and semantic attacks break LLM judges, which is an argument for running both. Rates are the mean of three replicates with the range reported, because a single run of this experiment moves by up to 17 points — hosted providers are not deterministic even at temperature 0.
export OPENROUTER_API_KEY=...
lurebench leaderboard -d data/full/core/test.jsonl \
  -m tfidf-logreg -m 'llm-judge@openrouter/deepseek/deepseek-v4-flash' \
  --cache-dir .cache/lb --workers 12

The CLI covers the pipeline, including audit-splits for cross-split near-duplicate detection and calibrate for validation-only policy export. assemble-core-v2 produces clustered train/validation/test plus a separately held private split, and eval --bootstrap 2000 adds uncertainty intervals. See benchmark validity, the finite-sample FPR control method, the changelog, the taxonomy & STIX guide, and docs/adding-a-detector.md to contribute a detector.

Why it matters

U.S. regulators and law enforcement have named this threat directly. FinCEN's Nov 2024 alert lists GenAI-generated text among its red-flag indicators and names BEC, spear phishing, elder exploitation, romance scams and virtual-currency investment ("pig-butchering") scams as active GenAI vectors. The FBI's Dec 2024 IC3 PSA warns that criminals use generative AI to produce fraudulent content at greater scale and believability. FS-ISAC cites a Deloitte projection of $40B in U.S. AI-enabled fraud losses by 2027.

LureBench maps its typologies onto exactly those frameworks. The taxonomy carries curated crosswalks to MITRE ATT&CK, the FBI/IC3 crime categories, and FinCEN advisories, and the stix command emits standards-compliant STIX 2.1 — so a detection can travel from a detector to a fusion center, an ISAC, or a SAR narrative without being re-described.

Responsible use

This is a defensive research project. The corpus exists to train and evaluate detectors. Controlled generation produces defanged, clearly-synthetic, review-gated text. It does not personalize lures to real targets, embed working links or payment rails, or deliver anything. See DATA.md, docs/SHARD_SPEC.md and CONTRIBUTING.md.

Honest limitations

LureBench is an early pilot, and the writeups say so plainly:

  • The distribution-matched provenance result covers three generators and phishing only (the human data is phishing-only), with a few hundred paired rewrites per generator.
  • The human corpus is older-era phishing. De-tokenization and rewriting remove the largest tells; the residual signal is register and style, which is arguably legitimate authorship signal, but a contemporary human-fraud source would be stronger.
  • Audio and video deepfake fraud are out of scope. They are well served by existing benchmarks (ASVspoof 5, Deepfake-Eval-2024, VishGPT); LureBench covers text.

Contributing

Detectors, data shards, attacks, and corrections to published numbers are all welcome. Start with CONTRIBUTING.md and docs/adding-a-detector.md; a detector is about thirty lines. Community expectations are in CODE_OF_CONDUCT.md.

SECURITY.md covers both conventional vulnerabilities and what is not one here: the corpus containing fraud lures, the attacks succeeding, and detectors scoring badly are all intended. It also describes how to report a measurement error, which for a benchmark matters as much as a memory-safety bug.

Release history is in CHANGELOG.md.

Citation

See CITATION.cff. Archived releases carry a DOI: cite the concept DOI 10.5281/zenodo.21631777, which always resolves to the latest version. Licensed under Apache-2.0.

paper.md is an unsubmitted draft of a software paper, kept in the repo so the framing evolves with the code. It has not been peer reviewed and should not be cited as a publication.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lurebench-0.10.0.tar.gz (2.4 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lurebench-0.10.0-py3-none-any.whl (129.8 kB view details)

Uploaded Python 3

File details

Details for the file lurebench-0.10.0.tar.gz.

File metadata

  • Download URL: lurebench-0.10.0.tar.gz
  • Upload date:
  • Size: 2.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for lurebench-0.10.0.tar.gz
Algorithm Hash digest
SHA256 ff7037d15632c831464b6f91beb9ab2d592efdea52d539e8f8e5f13d281983a8
MD5 cd4fd7b269f7a070e1b366bb68ede08d
BLAKE2b-256 c5a26ed5db104b7812f8a23ea6581a941a958cbacb8ca09c5a01449900fd3a08

See more details on using hashes here.

Provenance

The following attestation bundles were made for lurebench-0.10.0.tar.gz:

Publisher: release.yml on immu4989/lurebench

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file lurebench-0.10.0-py3-none-any.whl.

File metadata

  • Download URL: lurebench-0.10.0-py3-none-any.whl
  • Upload date:
  • Size: 129.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for lurebench-0.10.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0ddd6c208249a418b06aa5717818ed3c0697d0a8a9fff1b705ce557a26d36fe5
MD5 bd61415e5edfcae6fd03df7a1f23ed7c
BLAKE2b-256 16bfa27798f19c91df65a1d97000600691da2c1689d1368a6116f1fca81c187d

See more details on using hashes here.

Provenance

The following attestation bundles were made for lurebench-0.10.0-py3-none-any.whl:

Publisher: release.yml on immu4989/lurebench

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.11.0

2 files

This release

0.10.0 This release

2 files

0.9.1

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page