Ecommerce Bypass - Early Checkout
Analyse eines versteckten API-Endpoints zur Umgehung von Coming-Soon Restriktionen
Die Mission
Jeder kennt es. Ein neues Produkt wird released, der Hype ist groß, jeder möchte es haben. Die Produktseite existiert bereits und es ist zum greifen nah, aber der Release ist erst Morgen. Wird man schnell genug sein eins zu ergattern? Man wird es erst erfahren wenn es zu spät ist. Oder doch nicht? Gibt es vielleicht einen Weg, das Produkt jetzt schon vor allen anderen zu kaufen?
In diesem Write-up zeige ich, wie man durch umfassende API-Analyse und ein wenig Kreativität, schwachstellen in einem E-Commerce System ausnutzen kann, um ein Produkt vor allen anderen, ja sogar vor Release zu erwerben. Natürlich alles rein Theoretisch.
Als Beispiel nehmen wir einmal an, dass ein bestimmter Schuh bald auf der offiziellen Onlineshop X Website erscheint
Product ID: 211396
Target Size: 211396-0Z3-M9W11
Status: Coming Soon (nicht kaufbar über UI)
Überblick verschaffen
Die Produktseite existiert bereits, zeigte aber nur "Coming Soon" an und gibt keine option zum Kauf: Klar, das Produkt ist ja noch nicht released.
Es fällt auf, dass die Größen-Auswahl jedoch bereits geladen ist. Gucken wir uns die Seite im Developer Tools genauer an, kann man sehen, dass auch die zugehörigen Size IDs bereits im HTML vorhanden sind.

Analyse: Der Standard-Flow
Zuerst müssen wir verstehen, was bei einem "In den Warenkorb" normalerweise passeirt. Wir suchen uns ein Produkt was bereits verfügbar ist, z.B. den Other Example Shoe. Nun öffnen wir die Developer Tools und analysieren die Netzwerk-Requests beim Hinzufügen zum Warenkorb.
Product ID: 10001
Target Size: 10001-308-M7W9
Status: Verfügbar
Request #1: Add to Cart
Der Request war simpel: Ein POST zu einem Cart-API endpoint. Der Body enthielt die PID, Menge und Aktion die ausgeführt werden soll, in diesem Fall "add".
Der endpoint selber gibt keinen Rückschluss auf die Aktion, diese steht in dem Body. Wir können daraus schließen, dass es einen zentralen Cart-API gibt, der verschiedene Aktionen über den "action" Parameter steuert.
Perfekt! Das Produkt wurde dem Cart hinzugefügt. Die Response enthielt alle Cart-Daten, inklusive Shipping-Informationen und verfügbarem Stock. Das ist spannend, üblicherweise sind Stock informationen meist nur intern verfügbar und in der API nicht einsehbar.
Erster Versuch: Direkte PID Substitution
Was passiert, wenn wir einfach die PID austauschen? Statt 10001-308-M7W9 verwende wir einfach die Target-PID 211396-0Z3-M9W11. Mal sehen, ob wir so das Produkt in den Warenkorb legen können.
Mist. Leerer Warenkorb. Die API erkannte, dass das Produkt noch nicht verfügbar war und lehnte den Request stillschweigend ab. Kein Error, nur ein leerer Cart. Vorhersehbar aber einen Versuch war es wert.
Weitere Versuche: Alternative Endpoints
Vielleicht gab es andere Wege, Produkte in den Cart zu legen?
Versuch 2: Upsell Endpoint
Die Website hatte einen "Product Carousel" mit Upsell-Produkten. Vielleicht wird hier ein anderer Endpoint verwendet? Wir analysieren auch diesen Request.
Der endpoint scheint derselbe zu sein, nur der Body ist etwas anders. Die Methode ist hier "Product Carousel" statt "PDP". Was solls, ein versuch ist es wert.
Selbes Ergebnis. Leerer Cart bei unreleased PID.
Versuch 3: Cart Update Manipulation
So schnell geben wir uns nicht geschlagen. Die API wird sicher einen Weg haben um Artikel im Warenkorb zu aktualisieren. Z.B. die Menge ändern. Vielleicht können wir das ausnutzen?
Gehen wir zum Warenkorb, wo bereits unser existierendes Produkt liegt, und ändern die Menge. Dabei natürlich wieder die Netzwerk-Requests analysieren.
Spannend. Es ist wieder wie erwartet der selbe Cart-API Endpoint, aber mit update als Aktion. UUID wird sicherlich das Item im Warenkorb identifizieren. Aber es wird tatsächlich auch die PID mitgeschickt. Können wir diese vielleicht zu unserem Target ändern und so das Produkt austauschen?
POST /Cart-API HTTP/3
action=update&pid=211396-0Z3-M9W11&qty=1&uuid=c30a498fef1434b1e22789efccWir probieren es mit einem anderen verfügbaren Produkt aus. Und siehe her: Es hat funktioniert. Das existierende Item im Warenkorb wurde durch das neue ersetzt.
Jetzt der eigentliche Test: Wir tauschen die PID zu unserer Target PID. Mal sehen was passiert.
Ergebnis: Nope. Das bestehende Item blieb unverändert. Die PID wurde ignoriert. Auch hier wird anscheinend überprüft, ob das Produkt verfügbar ist, bevor es ein anderes austauschen kann. Schade, aber wir geben nicht auf.
Interessante Ansatz
Alle direkten API-Versuche scheitern, scheint wohl doch nicht so einfach wie erhofft. Nun müssen wir richtig kreativ werden. Viele E-Commerce-Shops senden "Abandoned Cart" E-Mails. Wenn ein Nutzer etwas in den Warenkorb legt, aber nicht kauft, bekommt er nach einer Weile eine Erinnerung per E-Mail mit einem Link zurück zu seinem Warenkorb. Jeder kennt diese E-mails, nervig aber vielleicht steckt hier eine unerwartete Möglichkeit.
Der entscheidende Punkt: Diese Links müssen geräteunabhängig funktionieren. Du kannst sie auf dem Handy öffnen, auch wenn du den Cart am Desktop erstellt hast. Das bedeutet: Die Session-Information muss im Link selbst enthalten sein, nicht in Cookies.
Der Email-Link
Wir durchsuchen alte Emails und finden tatsächlich einen Cart-Reminder. Der link sieht wie folgt aus:
https://refer.onlineshop-x-email.com/?qs=37329e0a5343228e17d0ce9f5f3bb13ed6597f4dd911a0c6527f87b162fe16...Ein verschleierter Tracking-Link. Der qs Parameter schien ein verschlüsselter Token zu sein. Interessant, wohin führt der Link?
Redirect: Email Click Tracking
Senden wir doch einfach ein Request und gucken direkt nach
Ein 302 Redirect. Die Response zeigte den Ziel-Link. Und wann man sich mal anguckt wohin, dann sieht es tatsächlich hochinteressant für uns aus
Der Cart-EmailLink Endpoint
Der Link zeigte auf einen speziellen Endpoint:
https://onlineshop-x.com/Cart-EmailLink?product=210829-90H-M7W9~Cart-EmailLink Das ist spannend. Nicht die übliche Cart-API, sondern ein komplett eigener Endpoint. Und noch interessanter: Die PID wurde direkt als product Parameter übergeben. Kein verschlüsselter Token, keine Session-Validierung, nur die PID. Könnte das der Weg sein?
Test mit bekannter PID
Bevor wir uns an die Target-PID wagen, testen wir den Endpoint erstmal mit einem verfügbaren Produkt:
Ein weiterer Redirect, diesmal zu /Cart-Show. Der Endpoint setzte dabei neue Session-Cookies. Wir folgen dem Redirect:
Perfekt! Das Produkt aus dem Link war im Warenkorb. Der Endpoint funktionierte also, und das ohne jegliche vorherige Session und ohne Login. Die PID im Link wurde einfach dem neuen Cart hinzugefügt.
Exploitation
Der Moment der Wahrheit
Kann es sein das dieser Endpoint eventuell nicht den release status prüft? Jetzt ist der Moment der Wahrheit. Wir testen den Endpoint mit unserer Target-PID:
Soweit so gut. Keine Errors und ein Redirect zu /Cart-Show, wie schon beim verfügbaren Produkt. Aber ist es auch wirklich im Warenkorb?
UNFASSBAR. Das unreleased Produkt ist tatsächlich in unserem Warenkorb! Keine Validierung, kein Error, einfach hinzugefügt. Der Endpoint hat den Release Status komplett ignoriert.

Final Test: Der Checkout
Das Produkt war im Cart, aber würde der Checkout funktionieren? Wir probieren es einfach mal aus.
- ✅ Versandadresse eingeben - funktioniert
- ✅ Zahlungsmethode auswählen - funktioniert
- ✅ Bestellung aufgeben - funktioniert
Keine Errors. Keine Validierungen, die das Coming-Soon-Produkt blockierten. Die Bestellung wurde durchgeführt. Wir stonieren die Bestellung natürlich sofort danach.
Root Cause Analysis
Warum funktionierte dieser Bypass? Ohne Zugriff auf den Backend-Code können wir nur Vermutungen anstellen, aber das Verhalten lässt klare Rückschlüsse zu:
1. Inkonsistente Validierung zwischen Endpoints
Die Standard Cart-Add Endpoints (action=add) prüften offensichtlich den Release-Status. Eine Implementierung könnte wie folgt aussehen:
// Standard Cart-Add Endpoint (Vermutung)
function addToCart(pid) {
const product = getProduct(pid);
// ✅ Validierung vorhanden
if (!product.isAvailable() || product.status === 'COMING_SOON') {
// Fehler wird nicht zurückgegeben, sondern silent fail
return { cartItems: [] };
}
return cart.add(product);
}Der Cart-EmailLink Endpoint hingegen scheint diese Validierung zu überspringen - vermutlich in der Annahme, dass E-Mail-Links nur für bereits verfügbare Produkte generiert werden:
// Email-Link Endpoint (Vermutung)
function cartEmailLink(pid) {
const product = getProduct(pid);
// ❌ KEINE Release-Status Validierung!
// Legacy-Code oder bewusst weggelassen für Abandoned-Cart-Mails
return cart.add(product);
}2. Selektive Backend-Validierung
Die Standard-Endpoints hatten definitiv serverseitige Validierung - das zeigte sich durch den leeren Cart bei meinen ersten Versuchen. Das Frontend blockierte zusätzlich den "Add to Cart" Button:
// Frontend (React/Vue/etc.)
<button
disabled={product.status === 'coming_soon'}
onClick={addToCart}
>
{product.status === 'coming_soon' ? 'Coming Soon' : 'Add to Cart'}
</button>Die Validierung existierte also sowohl im Frontend als auch im Backend - aber nur für die Standard-Endpoints. Der Email-Link Endpoint war davon ausgenommen, vermutlich weil er als "vertrauenswürdig" galt.
3. Mögliche Inventory-Logik
Interessant ist, dass das Produkt in der Response den Status"IN_STOCK" hatte. Er ist zwar noch nicht released, intern wird er jedoch als verfügbarer Lagerbestand geführt. Zudem lassen sich auch bereits die Stock-Levels einsehen.
Der Checkout Prozess prüft anscheinend nur diesen Status und Lagerbestand, und verlässt sich drauf das alle Produkte im Warenkorb bereits verfügbar sind. Folgend kann man das Produkt kaufen, obwohl es offiziell noch nicht released ist.
4. Legacy-Endpoint Problem
Der Cart-EmailLink Endpoint ist vermutlich älter als die Coming-Soon Feature-Implementierung. Als die Plattform das Coming-Soon System einführte, wurden die Standard-Endpoints aktualisiert, aber dieser spezielle Email-Link blieb unberührt.
Ein klassisches Beispiel für Security durch Obscurity - der Endpoint war nicht dokumentiert und wurde vergessen.
Detection & Mitigation
Wie können E-Commerce Plattformen sich davor schützen?
1. Konsistente Validierung
// Zentrale Validierungs-Funktion
function validateProductAvailability(product) {
const now = new Date();
// Release Date Check
if (product.releaseDate && product.releaseDate > now) {
throw new Error('Product not yet released');
}
// Stock Check
if (product.availableToSell <= 0) {
throw new Error('Product out of stock');
}
// Status Check
if (product.status === 'COMING_SOON') {
throw new Error('Product coming soon');
}
return true;
}
// In ALLEN Cart-Add Endpoints verwenden
function addToCart(pid) {
const product = getProduct(pid);
validateProductAvailability(product); // ✅
return cart.add(product);
}
function cartEmailLink(pid) {
const product = getProduct(pid);
validateProductAvailability(product); // ✅
return cart.add(product);
}2. Email Link Tokens
// Generiere signierte Tokens für Email-Links
function generateEmailCartToken(pid, userId) {
const payload = {
pid,
userId,
generatedAt: Date.now(),
expiresAt: Date.now() + (7 * 24 * 60 * 60 * 1000) // 7 days
};
return jwt.sign(payload, process.env.SECRET_KEY);
}
// Validiere Token im Endpoint
function cartEmailLink(token) {
const decoded = jwt.verify(token, process.env.SECRET_KEY);
if (decoded.expiresAt < Date.now()) {
throw new Error('Token expired');
}
const product = getProduct(decoded.pid);
validateProductAvailability(product);
return cart.add(product);
}3. Monitoring & Alerts
// Überwache verdächtige Patterns
function detectEarlyCheckoutAttempts(pid, userId) {
const product = getProduct(pid);
if (product.status === 'COMING_SOON') {
// Log Attempt
logger.warn('Early checkout attempt detected', {
userId,
pid,
ip: request.ip,
userAgent: request.headers['user-agent']
});
// Alert Security Team
if (getAttemptCount(userId, pid) > 3) {
alertSecurityTeam({
type: 'REPEATED_EARLY_CHECKOUT',
userId,
pid
});
}
}
}Ethical Considerations
Bei dieser Art von Research ist es wichtig, ethische Grenzen zu beachten:
- Responsible Disclosure: Schwachstellen wie diese müssen verantwortungsvoll gemeldet werden. Es ist zwar spannend sie zu entdecken, aber der Betreiber sollte die Möglichkeit haben, sie zu patchen bevor sie öffentlich bekannt werden.
- Keine Massenexploitation: Solche Funde sollten nicht für eigene Vorteile ausgenutzt werden.
- Educational Purpose: Analyse und Forschungen wie diese dienen der Bildung und Verbesserung der E-Commerce-Sicherheit. Solche Fehler sind absolut vermeidbar und sollten als Lernbeispiel dienen.
Fazit
Dieser Case zeigt, wie wichtig Defense in Depth ist. Ein einzelner ungeschützter Endpoint kann die gesamte Release-Strategie umgehen.
Key Takeaways:
- Frontend-Validierungen sind kein Security-Feature - immer auch Backend-Checks implementieren
- Alle API-Endpoints müssen die gleichen Validierungen durchlaufen
- Legacy-Endpoints (wie Email-Links) werden oft übersehen
- Proper Monitoring kann solche Exploits frühzeitig erkennen
E-Commerce Security ist komplex, aber mit systematischer Analyse und konsistenter Implementierung können solche Bypasses verhindert werden.