2025 Holiday Bot Attack Trends
What we noticed during Cyber 5
Every season, holiday bot attacks surge – no surprise there.
What stood out this year was the shift in bot activity throughout the shopping period.
Apple appears set to begin iPhone 18 (test) production soon
What we noticed during Cyber 5
Every season, holiday bot attacks surge – no surprise there.
What stood out this year was the shift in bot activity throughout the shopping period. Adversaries are well-versed in the tools at their disposal and when to deploy them to gain an advantage.
Scraping helps identify promos and inventory, automated checkout swoops in to get sale items first, fake accounts assist in buying hype items, and account takeover (ATO) allows them to cash out on holiday shopping.
Across Kasada-protected retail traffic globally, here are a few stats that stood out to us:
.chart-card {
width: 100%;
max-width: 1200px;
margin: 20px auto;
background: #ffffff;
border-radius: 18px;
padding: 18px 18px 14px;
box-shadow:
0 10px 30px rgba(17, 24, 39, 0.08),
0 2px 10px rgba(17, 24, 39, 0.05);
border: 1px solid #eef2f7;
}
.chart-section {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
}
.canvas-wrap {
width: 100%;
border-radius: 14px;
overflow: hidden;
}
.chart-legend {
display: flex;
justify-content: center;
gap: 12px;
margin-top: 14px;
flex-wrap: wrap;
}
.legend-item {
display: inline-flex;
align-items: center;
gap: 10px;
font-size: 14px;
color: #374151;
cursor: pointer;
user-select: none;
padding: 6px 12px;
border-radius: 999px;
border: 1px solid #e5e7eb;
background: #fff;
transition: all 0.2s ease;
appearance: none;
}
.legend-item:hover { background: #f9fafb; }
.legend-item[aria-pressed=”false”] { opacity: 0.45; text-decoration: line-through; }
.legend-circle {
width: 10px;
height: 10px;
border-radius: 999px;
display: inline-block;
}
]]>
Bad Bot Requests by Attack Intent (Holiday Traffic)
// Tooltip title add-ons for key dates
const dateNotes = {
“Nov 28″: ” — Black Friday”,
“Dec 1″: ” — Cyber Monday”
};
// Data mapped to renamed intents (SmsTollFraud intentionally omitted)
const dataBySeries = {
“Scraping”: [11433600, 10557364, 13802974, 22839421, 28181187],
“API Attack”: [ 3905714, 4332697, 7019796, 7504381, 8556648],
“Account Takeover”: [ 414790, 397705, 352684, 549019, 11159529],
“Automated Checkout”: [ 1827905, 2310562, 860966, 4688496, 859700],
“Gift Card Abuse”: [ 25975, 10167, 6201, 30203, 27660],
“Fake Account Creation”: [ 4545, 3103, 12620, 7454, 2758],
“Payment Fraud”: [ 1334, 1010, 636, 1182, 1099],
“Vulnerability Scanning”: [ 266, 129, 863, 208, 68]
};
// Colors
const colorMap = {
“Scraping”: “#005FFF”,
“API Attack”: “#001f70”,
“Account Takeover”: “#24C96B”,
“Automated Checkout”: “#E4572E”,
“Gift Card Abuse”: “#6B7280”,
“Fake Account Creation”: “#FF4D6D”,
“Payment Fraud”: “#F5B700”,
“Vulnerability Scanning”: “#19C3D6”
};
// Format ticks like 10M / 50K
function formatCompact(n) {
const abs = Math.abs(n);
if (abs >= 1e9) return (n / 1e9).toFixed(1).replace(/.0$/, “”) + “B”;
if (abs >= 1e6) return (n / 1e6).toFixed(1).replace(/.0$/, “”) + “M”;
if (abs >= 1e3) return (n / 1e3).toFixed(0) + “K”;
return String(n);
}
// Build datasets
const datasets = Object.entries(dataBySeries).map(([label, data]) => ({
label,
data,
borderColor: colorMap[label],
backgroundColor: colorMap[label] + “1F”,
fill: true,
tension: 0.35,
borderWidth: 2,
pointRadius: 0,
pointHoverRadius: 0
}));
// Superset-style guide line + hover marker
const kasadaHoverGuidePlugin = {
id: “kasadaHoverGuide”,
afterDraw(chart) {
const active = chart.getActiveElements();
if (!active || !active.length) return;
const ctx = chart.ctx;
const { chartArea } = chart;
const el = active[0].element;
const x = el.x;
const y = el.y;
ctx.save();
// vertical guide line
ctx.setLineDash([5, 5]);
ctx.lineWidth = 1;
ctx.strokeStyle = “rgba(17, 24, 39, 0.28)”;
ctx.beginPath();
ctx.moveTo(x, chartArea.top);
ctx.lineTo(x, chartArea.bottom);
ctx.stroke();
ctx.setLineDash([]);
// hover marker (small filled circle)
const dsIndex = active[0].datasetIndex;
const ds = chart.data.datasets[dsIndex];
ctx.fillStyle = ds.borderColor;
ctx.strokeStyle = “#ffffff”;
ctx.lineWidth = 2;
ctx.beginPath();
ctx.arc(x, y, 5, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.restore();
}
};
// Create chart
const ctx = document.getElementById(“holidayAttackIntentLine”).getContext(“2d”);
const chart = new Chart(ctx, {
type: “line”,
data: { labels, datasets },
plugins: [kasadaHoverGuidePlugin],
options: {
responsive: true,
maintainAspectRatio: true,
// We’ll manage hover ourselves based on filled regions
interaction: { mode: “nearest”, intersect: false },
plugins: {
legend: { display: false },
tooltip: {
enabled: true,
// IMPORTANT: we will set active elements manually, so keep this permissive
mode: “nearest”,
intersect: false,
// Tooltip styling
displayColors: true,
usePointStyle: true,
boxWidth: 10,
boxHeight: 10,
boxPadding: 12, // extra spacing between dot and text
caretSize: 0,
backgroundColor: “rgba(17, 24, 39, 0.92)”,
padding: 12,
cornerRadius: 10,
titleColor: “#ffffff”,
bodyColor: “#ffffff”,
titleFont: { size: 12, weight: “700” },
bodyFont: { size: 13, weight: “600” },
callbacks: {
// Date title + optional note for key days
title: (items) => {
const i = items?.[0]?.dataIndex ?? 0;
const base = labels[i] || “”;
return base + (dateNotes[base] || “”);
},
// Only show intent label (no numbers)
label: (item) => item.dataset.label,
// filled circle
labelPointStyle: () => ({ pointStyle: “circle”, rotation: 0 }),
// Make tooltip dot match the bottom legend color exactly
labelColor: (ctx) => {
const c = ctx.dataset.borderColor;
return {
borderColor: c,
backgroundColor: c,
borderWidth: 0,
borderRadius: 999
};
}
}
}
},
scales: {
x: {
grid: { display: false },
ticks: { color: “#6b7280”, font: { size: 12 } }
},
y: {
beginAtZero: true,
grid: {
color: “rgba(17, 24, 39, 0.06)”,
drawBorder: false
},
ticks: {
color: “#9ca3af”,
font: { size: 11 },
padding: 8,
callback: (value, index) => (index % 2 === 0 ? formatCompact(value) : “”)
}
}
}
}
});
// — Key behavior: hover ANYWHERE in a filled region shows ONLY that series —
const canvas = chart.canvas;
function pickDatasetAtCursor(evt) {
const rect = canvas.getBoundingClientRect();
const xPix = evt.clientX – rect.left;
const yPix = evt.clientY – rect.top;
const xScale = chart.scales.x;
const yScale = chart.scales.y;
const area = chart.chartArea;
// ignore if outside plot area
if (xPix area.right || yPix area.bottom) {
chart.setActiveElements([]);
chart.tooltip.setActiveElements([], { x: 0, y: 0 });
chart.update();
return;
}
// Convert x pixel to nearest index
const xValue = xScale.getValueForPixel(xPix);
const index = Math.round(xValue);
if (index = chart.data.labels.length) {
chart.setActiveElements([]);
chart.tooltip.setActiveElements([], { x: 0, y: 0 });
chart.update();
return;
}
// Find which filled area the cursor is in:
// area is under the line down to chartArea.bottom.
// For each visible dataset, compute line Y at this index.
// Cursor is “inside” dataset area if yPix >= yLine (below the line).
// If multiple match, choose the one whose line is closest above the cursor
// => largest yLine {
if (!chart.isDatasetVisible(dsIndex)) return;
const v = ds.data[index];
if (v === null || v === undefined || Number.isNaN(v)) return;
const yLine = yScale.getPixelForValue(v);
if (yPix >= yLine && yPix chosen.yLine) {
chosen = { dsIndex, index, yLine };
}
}
});
if (!chosen) {
// If not in any filled area, clear
chart.setActiveElements([]);
chart.tooltip.setActiveElements([], { x: 0, y: 0 });
chart.update();
return;
}
// Activate ONLY that dataset+index (so tooltip shows only that intent)
chart.setActiveElements([{ datasetIndex: chosen.dsIndex, index: chosen.index }]);
// Position tooltip nicely at the actual point on the line
const meta = chart.getDatasetMeta(chosen.dsIndex);
const pt = meta?.data?.[chosen.index];
const pos = pt ? { x: pt.x, y: pt.y } : { x: xPix, y: chosen.yLine };
chart.tooltip.setActiveElements([{ datasetIndex: chosen.dsIndex, index: chosen.index }], pos);
chart.update();
}
// Pointer move + leave handling
canvas.addEventListener(“mousemove”, pickDatasetAtCursor);
canvas.addEventListener(“mouseleave”, () => {
chart.setActiveElements([]);
chart.tooltip.setActiveElements([], { x: 0, y: 0 });
chart.update();
});
// Custom clickable legend
const legendEl = document.getElementById(“holidayAttackIntentLegend”);
chart.data.datasets.forEach((ds, i) => {
const button = document.createElement(“button”);
button.type = “button”;
button.className = “legend-item”;
button.setAttribute(“aria-pressed”, “true”);
button.innerHTML = `
${ds.label}
`;
button.addEventListener(“click”, () => {
const visible = chart.isDatasetVisible(i);
chart.setDatasetVisibility(i, !visible);
button.setAttribute(“aria-pressed”, String(!visible));
// Clear hover state when toggling so tooltip doesn’t get stuck
chart.setActiveElements([]);
chart.tooltip.setActiveElements([], { x: 0, y: 0 });
chart.update();
});
legendEl.appendChild(button);
});
});
Automation attacks more than doubled from Black Friday to Travel Tuesday. Both scale and sophistication increased as the sales period progressed.
Unauthorized scraping was the most prevalent attack typeScraping increased steadily across Cyber 5, surging around the most profitable promotions.
API-based automation followed the same patternAPI bot activity grew roughly 1.6× from Black Friday to Travel Tuesday, suggesting a deliberate approach.
Automated checkout attempts peaked on Cyber MondayRequests spiked 2.8× compared to Black Friday, aligning closely with the highest-impact sales moments.
Account takeover attempts rose after sales began to taperRather than peaking during promotions, ATO activity continued to climb and nearly tripled by Travel Tuesday.
More than anything, this data shows how adaptable automated attacks have become. They don’t just show up for a single sale and disappear; they shift as the season progresses.
The shopping season isn’t over yet, though, and we continue to see bot activity grow as we get closer to the end of the year.
To understand how attackers were preparing and monetizing these campaigns beyond live retail traffic, we turn to insights from our Threat Intelligence team, KasadaIQ. 👇
What we saw beyond our own traffic (KasadaIQ)
KasadaIQ’s 2025 holiday fraud predictions were confirmed by the data from November 1st to Travel Tuesday 2025. Adversaries executed campaigns with unprecedented scale, timing, and strategic focus. From massive account takeover (ATO) stock increases to a calculated “just-in-time” deployment of malicious configurations, this period was defined by an escalated and automated threat landscape.
Malicious Configurations (Configs)
Config patterns from November 1st to Travel Tuesday confirm KasadaIQ’s holiday predictions for configs in 2025.
We predicted that surges in available configs during this period would be more significant than 2024. Between November 1st and Travel Tuesday, there was 11.8% year-on-year growth of available configs on online forums.
Consistent with our prediction of adversaries getting ahead of the major sales events, available configs surged in the week prior to Thanksgiving and Black Friday (see below). This “just-in-time” deployment pattern indicates a more strategic approach in 2025, shortening the defensive window for security teams. This is consistent with the trend observed by KasadaIQ in 2025: configs spiking prior to, and in the first few days, of major sales events.
In 2025, we saw a clear pattern of config increases in the lead-up to peak sales periods. In 2024, configs continually surged throughout November, with the highest peak in the first week of the month.
ATO
The predicted significant, elevated surge in Account Takeover (ATO) was validated by the volume of compromised data on criminal marketplaces, particularly the monetization of high-value retail accounts.
KasadaIQ saw significant surges of ATO sales through November 2025, as shown below. The peak periods for both account stock and sales on criminal marketplaces were higher and earlier than predicted by KasadaIQ.
As predicted, stock for stolen accounts on criminal marketplaces surged in the week prior to Black Friday. This indicates strategically-timed credential stuffing activity from adversaries.
Across all criminal marketplaces, adversaries made at least USD $17,220,521.65 off stolen account sales from November to Travel Tuesday 2025. This is the floor, not the ceiling.
As shown below, retail accounts represented more than a quarter (30%) of all account sales from November 1st through to Travel Tuesday. Webmail accounts represented around 16% of all account sales from November 1st through to Travel Tuesday, followed by QSRs (10%), social media (10%), and airlines (5%).
As shown below, homeware stores were the most frequently sold accounts within the retail industry (59% of sales), whereas department stores were the highest source of revenue for criminal marketplaces (28% of revenue). There were a handful of specific retailers that were aggressively targeted throughout this period, which influenced these rankings.
The other most frequently targeted sub-industries included department stores (11%), apparel (10%), footwear (6%), cosmetics (4%), gaming (3%), consumer electronics (3%), grocery (2%), pets & agriculture (1%), and appliances (0.5%).
Points were the most common attachments to accounts sold on criminal marketplaces (~30%), followed by credit cards (~26%) and subscriptions (~16%).
Gift cards
Gift card sales on criminal marketplaces from November 1st to Travel Tuesday 2025 validate KasadaIQ’s holiday fraud predictions for gift card fraud.
As shown below, the QSR industry was a major target for gift card sales on criminal marketplaces. QSR gift card sales peaked throughout November, most significantly in the first week of November and the 10 days preceding Black Friday.
For the QSR industry, gift cards represented a higher portion of sales on criminal marketplaces from November 1st to Travel Tuesday 2025 when compared with the same period in 2024. Gift cards accounted for 11% of all criminal marketplace sales, compared to 7% the prior year.
Despite accounting for more sales, criminal marketplace revenue attributed to revenue from QSR gift card sales decreased by ~21% year-on-year. The data indicates that QSR gift cards have become a more frequent but less valuable commodity on criminal marketplaces.
For the retail industry, gift cards represented a lower portion of sales on criminal marketplaces from November 1st to Travel Tuesday 2025, when compared with the same period in 2024. Gift cards accounted for 0.25% of all criminal marketplace sales, compared to 2.4% the prior year.
Contrary to QSRs, criminal marketplace revenue attributed to retail gift cards increased by 10% year-on-year. The data could indicate that a range of factors, including successful defense against low-level fraud, is reducing the availability of gift cards to adversaries targeting the retail sector. It could indicate that adversaries are focusing on more high-value accounts to maximise revenue returns, instead of investing in high volume but low return accounts.
For the accommodation industry, gift cards represented a marginally higher portion of sales on criminal marketplaces from November 1st to Travel Tuesday 2025, when compared with the same period in 2024. Gift cards accounted for 0.03% of criminal marketplace sales, compared to 0% the prior year. Criminal marketplace revenue attributed to accommodation gift cards was 2.15%.
Retail bots
Retail bot activity from November 1st to Travel Tuesday 2025 confirms KasadaIQ’s predictions for retail bots.
We predicted that agentic AI would drive an unprecedented scale of traffic. Adobe Analytics reported that AI traffic to retailers grew around 758% year-on-year from November 1st to December 1st, 2025.
We predicted that peak bot activity would occur during the week prior to Thanksgiving and Black Friday, and will continue at scale during major sales events. As shown below, retail bot activity peaked the week prior to Black Friday and continued to surge to a smaller extent over major sales days.
Cyber Monday was responsible for around 4% of all bot checkouts, with Black Friday responsible for around 3.5%. The most significant day for bot checkouts was November 18th (~11%), followed by November 20th (~7.5%).
KasadaIQ observed over a million bot checkouts from 1 November to Travel Tuesday 2025.
Products targeted by bots align with Kasada’s Black Friday Bot Warning. The products identified in this blog are likely to remain high-value targets into 2026.
Footwear was the major focus of bot checkouts, constituting ~95% of Black Friday checkouts, ~61% of Cyber Monday checkouts, and ~93% of checkouts from November 1st to Travel Tuesday (see below).
As shown below, collectibles were the second top focus for bot checkouts, with the biggest day being Cyber Monday, where they constituted ~39% of all checkouts.
Almost a quarter (23.5%) of bot checkouts on Black Friday targeted Shopify stores. This was only 9.8% in 2024.
Intelligence-informed recommendations:
Start Early – Initiate high-alert monitoring and preparatory activities weeks ahead of major sales events.
Pre-peak Defense – Prioritize real-time monitoring and rapid countermeasures for new config surges in the week leading up to major sales.
Prioritize Value – Focus ATO defense on accounts holding significant, easily exploitable value.
Industry Hardening – Implement enhanced authentication and fraud checks for Homeware (sales volume) and Department Stores (revenue impact).
Secure Attachments – Deploy stronger security measures and user alerts for accounts containing these high-value components (e.g. points and credit cards).
QSR Alert – Immediately increase fraud controls for QSR gift card systems due to material growth in fraud.
High-Denomination Defense – Assume a shift to targeted, high-value attacks. Implement stronger checks on higher-denomination gift card purchases/redemptions.
Prepare for your next seasonal promotion – get bot visibility without impacting conversion.
The post 2025 Holiday Bot Attack Trends appeared first on Kasada.
*** This is a Security Bloggers Network syndicated blog from Kasada authored by KasadaIQ. Read the original post at: https://www.kasada.io/2025-holiday-bot-attack-trends/
