Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
Windows Tipps & SecurityGrafikkarte vor Überhitzung schützen: So geht’s(25.09.2026 um 08:00 Uhr)
••••••••••
Windows Tipps & SecurityGrafikkarte vor Überhitzung schützen: So geht’s(25.09.2026 um 08:00 Uhr)
••••••••••
Intelligence View
⚡ tsecurity.de Intelligence

I built a Chrome extension that catches every dark pattern trick on shopping sites. Here's exactly how.

A few months ago I was about to buy a flight. The page showed "Only 2 seats left at this price" in red letters. I hesitated, then refreshed the page out of curiosity. The counter said "Only 2 seats left" again. Same number. It had been…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

A few months ago I was about to buy a flight. The page showed "Only 2 seats left at this price" in red letters. I hesitated, then refreshed the page out of curiosity.



The counter said "Only 2 seats left" again. Same number. It had been resetting on every page load the whole time.



That's when I started cataloguing every trick I'd seen on shopping sites and built a Chrome extension that flags them automatically, in real time, on any page.






This isn't just my opinion — it's documented research



In 2019, Princeton and University of Chicago researchers scraped 11,000 shopping sites and found dark patterns on more than 1,250 of them. The FTC has since fined several companies specifically for fake countdown timers and pre-checked subscription boxes. This isn't a grey area anymore — it's a known, studied, and increasingly regulated practice.



The extension targets four categories that account for most of what's out there.






The four patterns



Fake urgency. Countdown timers that reset, "X people are viewing this" badges that never change, "only N left in stock" that's been static for a week.



Trap checkboxes. A checkbox for "Yes, sign me up for the newsletter" that's pre-checked and styled to blend into the page so you don't notice it.



Confirmshaming. The decline button reads "No thanks, I don't want to save money" instead of just "No thanks."



Psychological pricing. Prices ending in .99 or .95 designed to register as a lower price bracket than they are.






Why no AI this time



My phishing detector used Claude because language and intent are genuinely ambiguous — you need a model that understands context. Dark patterns are different. They're structural. A countdown timer either resets on reload or it doesn't. A checkbox is either pre-checked or it isn't. That's a DOM query, not a judgment call.



So this one runs entirely on regex and DOM inspection. No API calls, no latency, no cost per scan, works offline. Sometimes the boring solution is the correct one.






Detecting the urgency pattern



The core check looks for known urgency phrases and cross-references them against actual page state:



const URGENCY_PHRASES = [

/only \d+ left/i,

/\d+ people (are )?(viewing|watching)/i,

/offer ends in/i,

/flash sale/i,

/limited time/i

];



function isLikelyFake(element) {

const text = element.textContent;

const matchesPattern = URGENCY_PHRASES.some(p => p.test(text));

if (!matchesPattern) return false;



// Countdown timers that are actually fake almost always

// reset to the same value across page loads — checked via

// localStorage comparison against the previous visit

const stored = localStorage.getItem('dpd_seen_' + location.pathname);

const isStatic = stored === text;

localStorage.setItem('dpd_seen_' + location.pathname, text);



return matchesPattern && isStatic;

}



The trick isn't the regex — it's storing what you saw on the last visit and comparing. A genuine "3 left in stock" notice changes over time. A fake one doesn't.






Detecting trap checkboxes



This one's simpler — just check if a checkbox tied to subscription/marketing language defaults to checked:



const TRAP_KEYWORDS = /newsletter|subscribe|offers|insurance|protection plan/i;



function findTrapCheckboxes() {

return [...document.querySelectorAll('input[type="checkbox"]')]

.filter(cb => cb.checked && TRAP_KEYWORDS.test(getLabelText(cb)));

}



The hard part isn't the logic, it's getLabelText() — checkbox labels are wrapped, nested, or associated via for= attributes in about six different inconsistent ways depending on the site. That function ended up being three times longer than the detection logic itself.






Marking it on the page



Detection is half the work. The other half is surfacing it without breaking the page layout:



function markElement(el, label) {

const badge = document.createElement('span');

badge.textContent = '⚠ ' + label;

badge.style.cssText =

position: absolute; background: #ef4444; color: white;

font-size: 11px; padding: 2px 8px; border-radius: 10px;

z-index: 999999; pointer-events: none;

;

el.style.position = 'relative';

el.appendChild(badge);

}






Catching dynamically injected patterns



Plenty of these patterns get injected after the initial page load — countdown widgets, exit-intent popups with fake scarcity. A one-time scan on page load misses them.



const observer = new MutationObserver(() => scanPage());

observer.observe(document.body, { childList: true, subtree: true });



This runs the same detection logic on every DOM mutation, debounced to avoid hammering the page on sites with constant re-renders (looking at you, infinite scroll feeds).






Results



I ran it against 30 ecommerce sites I had open in old tabs — a mix of fast fashion, flight booking, and a few subscription services. It flagged something on 19 of them. Two false positives: a genuinely real "low stock" indicator on a small print-on-demand shop, and a checkbox for "remember me" that the keyword filter misread as marketing consent.



Everything else held up. The fake countdown timers in particular were depressingly consistent — same number, every single reload.






FAQ



Is this legal to build and use?

Yes. You're reading and analyzing the public DOM of a page you're voluntarily visiting in your own browser. No data leaves your machine.



Does it slow down the pages I visit?

Not noticeably. The regex checks are cheap and the MutationObserver is debounced.



Can I use this in a commercial product?

The source is MIT licensed in the free version. Build on it.



Why not just block the patterns instead of flagging them?

Some checkboxes are legitimately useful (extended warranty you actually want). The goal is informed choice, not removing functionality you might want.






Full source code: https://carlosdevlop.gumroad.com/l/dark-patterns-detector

1. Sofort-Triage & Abwehrmaßnahmen

SOC Incident Playbook: Remote Code Execution (RCE) Defense
1 Warnungen
title: Detect Exploitation - I built a Chrome extension that catches every dark pattern trick on shopping sites. Here's exactly how.
id: 11dda41f-057a-4d80-9ae9-560214d7fc6b
status: experimental
description: Automatisch generierte SIEM-Erkennungsregel basierend auf CTI Intelligence
references:
  - https://tsecurity.de/
author: iShareStuff CTI Automated Detection Engine
date: 2026-09-26
logsource:
  category: network_connection
  product: any
detection:
  selection:
      CommandLine|contains:
        - 'exploit'
  condition: selection
falsepositives:
  - Legitime administrative Zugriffe oder Penetrationstests
level: high
tags:
  - attack.initial_access
  - attack.t1566
Syntax validiert (0 Fehler)
rule CTI_Threat_Indicator {
    meta:
        author = "iShareStuff CTI Automated Detection Engine"
        date = "2026-09-26"
        description = "YARA Signature for "
    strings:
        $str = "I built a Chrome extension tha" ascii wide
    condition:
        any of them
}
Syntax validiert (0 Fehler)
index=security sourcetype IN ("cisco:asa", "pan:traffic", "zeek_conn", "suricata", "WinEventLog:Security")
("I built a Chrome extension that catches ")
| stats count earliest(_time) as first_seen latest(_time) as last_seen by src_ip, dest_ip, dest_host, signature
| eval first_seen=strftime(first_seen, "%Y-%m-%d %H:%M:%S"), last_seen=strftime(last_seen, "%Y-%m-%d %H:%M:%S")
| sort - count
Syntax validiert (0 Fehler)
message: "*I built a Chrome extension that catches *"
Syntax validiert (0 Fehler)
CommonSecurityLog
| where Message has "I built a Chrome extension that catches "
| summarize EventCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceIP, DestinationIP, DestinationPort, Activity
| extend DetectionRule = "iShareStuff-CTI-Compiled"
| sort by EventCount desc

2. Cyber Threat Intelligence & Forensik

CTI Threat Relationship Graph3 Knoten / 2 Relationen
CVE / Incident Software MITRE ATT&CK CWE Weakness IoC
🎯
MITRE ATT&CK Matrix Navigator 14 Taktiken
Reconnaissance
-
Resource Development
-
Initial Access
Execution
Persistence
-
Privilege Escalation
Defense Evasion
Credential Access
-
Discovery
-
Lateral Movement
-
Collection
-
Command and Control
Exfiltration
-
Impact
tsecurity.de Cognitive Threat RAG
Fokus-Vektor:

Kognitive Analyse für identifizierte Bedrohung: Erhöhte Bedrohungslage im Bereich I built a Chrome extension that catches .... Basierend auf 368k Vektor-Korrelationen werden sofortige Isolationsmaßnahmen für betroffene Endpunkte empfohlen.

🛡️ Angriffsfläche & Exposure

Netzwerk/Remote-Zugriff ohne Vorauthentifizierung möglich.

⚡ Empfohlene Sofortmaßnahmen
  • 1. Perimeter-Inspektion: Relevante Portfreigaben und exponierte Endpunkte unverzüglich scannen.
  • 2. Patch-Applikation: Hersteller-Hotfix einspielen oder betroffene Daemons in isolierte DMZ-Segmente überführen.
  • 3. Telemetrie & EDR-Alerts: Prozessaufrufe und Child-Processes auf anomale Shell-Spawns überwachen.
🔗 Semantisch verwandte Zero-Days MariaDB 11.7 VEC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten I built a Chrome extension that catches every dark pattern trick on shopping sites. Here's exactly how.

Thematisch verwandte Begriffe: built, Chrome, extension, that · 6 Treffer

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-100503 | Ghidra versions through 12.1.4 contain a heap use-after-free vulnerabil…
Advisory →
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag