Case study 02 · Risk analytics · Tableau

Catching a card-testing attack inside 90 days of transactions.

Roughly half a million card transactions over one quarter, with a fraud team asking a simple question: is today normal? For nine days in June it was not. The monitoring view below found the attack, sized it, and showed exactly when the attackers clock in.

RoleMonitoring design, anomaly analysis
ToolsTableau · SQL · LOD expressions
Dataset90 days · ~493k transactions
Live · recomputes in your browser

The monitoring view.

Switch to the attack window and watch the flagged count jump while legitimate volume barely moves. That gap is the whole detection story.

Window
Transactions
Flagged
Fraud rate
basis points of volume
Volume monitored
across the window
Flagged transactions per day
The June card-testing attack stands nine sigma above the baseline
Fraud by category
Full quarter · attack traffic hit Online Retail
When fraud happens · hour by weekday
Full quarter · the overnight block is the attack signature
Daily transaction volume
Legitimate traffic stays flat straight through the attack
Highest-risk flagged transactions
Top 12 by model risk score in the selected window
What the data says

Three findings, one recommendation.

01

The attack announced itself in the rate, not the volume.

Daily transaction counts looked healthy for all 90 days. The fraud rate is what moved: from a baseline near 25 basis points to over 100 at the peak. Monitoring totals without monitoring rates is how a quarter like this gets signed off as normal.

02

Card testing has a bedtime signature.

Flagged transactions during the attack cluster between midnight and 6am, when review staffing is thinnest and cardholders are asleep. Small authorization amounts, high velocity, one merchant category. The heatmap makes the pattern legible in one glance.

03

One category absorbed the hit.

Online Retail carried the large majority of attack-window flags while in-person categories held their baseline. That points at a specific gateway integration rather than a broad compromise, which changes who gets the incident ticket.

Recommendation

Alert on fraud rate per hour, not daily totals, with a threshold set from the trailing 30-day baseline. Add velocity rules for sub-dollar authorizations overnight, and route Online Retail gateway anomalies to a named owner. In this dataset those rules would have surfaced the attack on its first night instead of day three.

The Tableau build

Same monitoring, production tooling.

In Tableau this ships as one workbook: the daily extract on a live connection, LOD expressions for the baseline math, and dashboard actions so clicking the spike filters the flagged-transaction detail.

Key calculated fields
// trailing baseline, fixed across the view
Baseline Fraud Rate :=
{ FIXED : AVG([Fraud Flagged] / [Transactions]) }

// how unusual is today?
Rate vs Baseline :=
([Fraud Flagged] / [Transactions])
    / [Baseline Fraud Rate]

// drives the alert color on the time series
Alert Level :=
IF [Rate vs Baseline] >= 3 THEN 'Critical'
ELSEIF [Rate vs Baseline] >= 1.8 THEN 'Watch'
ELSE 'Normal' END
The SQL feeding the extract
-- hour-of-week fraud density for the heatmap
SELECT
    EXTRACT(dow  FROM tx_time) AS weekday,
    EXTRACT(hour FROM tx_time) AS hour,
    COUNT(*) FILTER (WHERE is_flagged) AS flagged,
    COUNT(*)                             AS transactions
FROM card_transactions
WHERE tx_time >= now() - INTERVAL '90 days'
GROUP BY 1, 2
ORDER BY 1, 2;
← Prev · Bank churn Next · Marketing ROI