API reference — PerfShop
This document lists all REST endpoints exposed by the PerfShop Spring Boot backend.
Base URL (prod): https://perfshop-api.perfshop.io
Base URL (local): http://localhost:9080
Conventions
| Symbol |
Meaning |
| 🔓 |
Public — no authentication required |
| 🔑 |
User session required (LOGGED_IN_USER in session) |
| 🔐 |
Admin required — session cookie or X-Admin-Token header |
| 👑 |
SuperAdmin only |
| 🚨 |
Intentionally vulnerable endpoint (security chaos) — active depending on level |
Admin authentication accepts two paths:
- Session cookie: after
POST /api/admin/login
X-Admin-Token: <uuid> header: token generated at login, usable cross-origin
User authentication — /api/auth
| Method |
Endpoint |
Auth |
Description |
POST |
/api/auth/login |
🔓 |
User login. Returns securityToken, id, email, first/last name. At level 3+, adds the X-Debug-Token header (fault S7). |
POST |
/api/auth/logout |
🔑 |
Logout. At chaos level 3 (A11), the session remains exploitable during the grace period. |
GET |
/api/auth/status |
🔓 |
Current session status (authenticated, hasToken, userId, graceActive). |
GET |
/api/auth/me |
🔑 |
Full profile of the logged-in user. At level 1+, includes the BCrypt password hash (fault S3). |
PUT |
/api/auth/me |
🔑 |
Profile update (civility, firstName, lastName, birthDate, phone, street, postalCode, city, region, country). At level 3+, the email and password body fields are applied without whitelist (fault S9). |
Body — POST /api/auth/login
{ "email": "user@example.com", "password": "myPassword" }
Body — PUT /api/auth/me
{
"civility": "M",
"firstName": "Jean",
"lastName": "Dupont",
"birthDate": "1990-05-15",
"phone": "+33612345678",
"street": "12 rue de la Paix",
"postalCode": "75001",
"city": "Paris",
"region": "Île-de-France",
"country": "FR"
}
Product catalog — /api/products
| Method |
Endpoint |
Auth |
Description |
GET |
/api/products |
🔓 |
Paginated product list. Parameters: page, size, sort (id, name, price, category, createdAt, stock). |
GET |
/api/products/{id} |
🔓 |
Product detail by ID. |
GET |
/api/products/search |
🔓 |
Product search. Parameters: q, category, minPrice, maxPrice, page, size. At level 1+, uses a non-parameterized native query (fault S1). |
GET |
/api/products/categories |
🔓 |
List of all available categories. |
Cart — /api/cart
The cart is free of access: available whether logged in or not (guest).
| Method |
Endpoint |
Auth |
Description |
GET |
/api/cart |
🔓 |
Current cart contents (items, total, itemCount). |
POST |
/api/cart/add |
🔓 |
Adds an item to the cart. Body: { "productId": 1, "quantity": 2 }. |
PUT |
/api/cart/item/{id} |
🔓 |
Updates the quantity of an item. Parameter: ?quantity=N. |
DELETE |
/api/cart/item/{id} |
🔓 |
Removes an item from the cart. |
DELETE |
/api/cart |
🔓 |
Empties the cart entirely. |
Checkout — /api/checkout
A 4-step journey. Steps 1–3 are handled here; step 4 (final validation) is in /api/orders.
Depending on Scripting chaos level (0–4), additional headers are required at each step (X-Session-Token, X-Request-ID, X-Action-Token, X-CSRF-Token, X-Step-Token, X-Signature).
| Method |
Endpoint |
Auth |
Description |
GET |
/api/checkout/session |
🔑 |
Summary of the current checkout session (address, shipping, payment). |
GET |
/api/orders/checkout/verify |
🔑 |
Verifies that access to checkout is authorized (canCheckout, authenticated, hasToken). |
POST |
/api/checkout/address |
🔑 |
Step 1 — Shipping address. Body: street, postalCode, city, region?, country, phone. |
POST |
/api/checkout/shipping |
🔑 |
Step 2 — Shipping method. Body: { "shippingMethod": "standard" \| "express" \| "premium" }. |
POST |
/api/checkout/payment |
🔑 |
Step 3 — Payment. Body: cardHolder, cardNumber, expiryMonth, expiryYear, cvv. The CVV is never stored or logged. |
POST |
/api/checkout/promo |
🔑 |
Promo code validation. Body: { "code": "PROMO10" }. At level 2+ (A6), an invalid code is accepted with 0% discount. |
Orders — /api/orders
| Method |
Endpoint |
Auth |
Description |
GET |
/api/orders |
🔑 |
List of orders of the logged-in user + historyTotal. |
POST |
/api/orders |
🔑 |
Step 4 — Final order validation. Body: items, securityToken, and optionally shippingAddress, shippingMethod, paymentMethod. At level 2+, accepts unitPrice from the body (fault S5) and stores the address without sanitization (fault S4). |
GET |
/api/orders/{id} |
🔑 |
Order detail. At level 1+, the ownership check is disabled (fault S2 — IDOR). |
GET |
/api/orders/{id}/details |
🔑 |
Full detail with items (names, quantities, prices). Same IDOR logic (S2) as above. |
GET |
/api/orders/{id}/invoice |
🔑 |
Simulated invoice. Parameter: ?format=pdf\|csv. At level 3+, the format parameter is not validated (fault S8 — Path Traversal). |
POST |
/api/orders/{id}/cancel |
🔑 |
Cancels an order in PENDING or CONFIRMED status. |
Body — POST /api/orders
{
"securityToken": "uuid-token",
"items": [
{ "productId": 1, "quantity": 2, "unitPrice": 9.99 }
]
}
Countries — /api/countries
| Method |
Endpoint |
Auth |
Description |
GET |
/api/countries |
🔓 |
List of supported countries for forms, sorted with FR first. Returns [{ "code": "FR", "label": "France" }, ...]. |
Administration — /api/admin
Auth: session cookie or X-Admin-Token header.
Admin auth
| Method |
Endpoint |
Auth |
Description |
POST |
/api/admin/login |
🔓 |
Admin login (admin_users table, BCrypt). Returns adminToken, email, isSuperAdmin, canAccessChaos, canAccessMonitoring, canAccessAdmin. |
POST |
/api/admin/logout |
🔐 |
Admin logout (invalidates session + token). |
GET |
/api/admin/status |
🔓 |
Admin authentication status (authenticated). |
Admin account management
| Method |
Endpoint |
Auth |
Description |
GET |
/api/admin/accounts |
👑 |
Lists all admin accounts (without passwordHash). Restricted to superAdmin. |
POST |
/api/admin/accounts |
👑 |
Creates an admin account. Body: email, password, canAccessChaos, canAccessMonitoring, canAccessAdmin. |
DELETE |
/api/admin/accounts/{id} |
👑 |
Deletes an admin account (forbidden on superAdmin). |
PUT |
/api/admin/accounts/{id}/password |
👑 |
Changes the password of an account. Body: { "password": "newPass" }. |
PUT |
/api/admin/accounts/{id}/rights |
👑 |
Modifies the rights of an account. Body: canAccessChaos, canAccessMonitoring, canAccessAdmin. |
User management
| Method |
Endpoint |
Auth |
Description |
GET |
/api/admin/users |
🔐 |
Lists all users with their order count. |
POST |
/api/admin/users |
🔐 |
Creates a user. Body: { "email": "...", "password": "..." }. |
DELETE |
/api/admin/users/{id} |
🔐 |
Deletes a user and all their orders. |
Order management
| Method |
Endpoint |
Auth |
Description |
GET |
/api/admin/orders |
🔐 |
Lists all orders (all users). |
DELETE |
/api/admin/orders/{id} |
🔐 |
Deletes an order. |
Product management
| Method |
Endpoint |
Auth |
Description |
GET |
/api/admin/products |
🔐 |
Lists all products (sorted by category then name). |
POST |
/api/admin/products |
🔐 |
Creates a product. Body: name, description, price, stock, category, imageUrl. |
PUT |
/api/admin/products/{id} |
🔐 |
Updates a product (partial fields accepted). |
DELETE |
/api/admin/products/{id} |
🔐 |
Deletes a product. |
POST |
/api/admin/products/{id}/image |
🔐 |
Uploads a product image (multipart/form-data, file field). Formats: jpg, png, webp, gif. |
Backend chaos — /api/admin/chaos
All these endpoints require admin auth.
| Method |
Endpoint |
Auth |
Description |
GET |
/api/admin/chaos/status |
🔐 |
Full backend + frontend status ({ backend: {...}, frontend: {...} }). |
POST |
/api/admin/chaos/reset |
🔐 |
Resets all chaos to 0 (backend, frontend, scripting, business, security, functional). |
POST |
/api/admin/chaos/memory |
🔐 |
Memory leak. Body: { "intensity": 0-100, "heapCap": 80 }. |
POST |
/api/admin/chaos/db-pool |
🔐 |
DB pool saturation. Body: { "intensity": 0-100 }. |
POST |
/api/admin/chaos/thread-pool |
🔐 |
Thread pool saturation. Body: { "intensity": 0-100 }. |
POST |
/api/admin/chaos/cpu |
🔐 |
CPU load. Body: { "intensity": 0-100, "ratio": 4.0 }. |
POST |
/api/admin/chaos/slow-queries |
🔐 |
SQL query slowdown. Body: { "intensity": 0-100 }. |
POST |
/api/admin/chaos/deadlock |
🔐 |
Deadlock probability. Body: { "intensity": 0-100 }. |
POST |
/api/admin/chaos/network |
🔐 |
Simulated network timeout. Body: { "intensity": 0-100 }. |
Frontend chaos — /api/chaos/frontend
| Method |
Endpoint |
Auth |
Description |
GET |
/api/chaos/frontend/state |
🔓 |
Current frontend chaos state (cpuBurn, memoryLeak, domFlood, fetchFlood). Polled every 5s by the React frontend. |
POST |
/api/chaos/frontend/state |
🔐 |
Modifies frontend intensities. Body: { "cpuBurn": 50, "domFlood": 30, ... }. |
Security chaos — /api/admin/chaos/security and /api/chaos/public/security
| Method |
Endpoint |
Auth |
Description |
POST |
/api/admin/chaos/security |
🔐 |
Sets the security level. Body: { "level": 0-4 }. 0=Disabled, 1=Junior, 2=Intermediate, 3=Expert, 4=Master. |
GET |
/api/admin/chaos/security/status |
🔐 |
Detailed status + counters per fault (S1…S12). |
POST |
/api/admin/chaos/security/reset |
🔐 |
Resets the level to 0 and clears the counters. |
POST |
/api/admin/chaos/security/logs/clear |
🔐 |
Clears the security activity log. |
GET |
/api/chaos/public/security/status |
🔓 |
Status + counters (read-only, for monitoring). |
GET |
/api/chaos/public/security/logs |
🔓 |
Security activity log stream (for monitoring). |
GET |
/api/chaos/public/security/faults |
🔓 |
Pedagogical catalog of faults for a level. Parameter: ?level=N. |
Business chaos — /api/admin/chaos/business and /api/chaos/public/business
| Method |
Endpoint |
Auth |
Description |
POST |
/api/admin/chaos/business |
🔐 |
Sets the business level. Body: { "level": 0-3 }. 0=Disabled, 1=Junior, 2=Intermediate, 3=Expert. |
GET |
/api/admin/chaos/business/status |
🔐 |
Status + counters per anomaly (A1…A11). |
POST |
/api/admin/chaos/business/reset |
🔐 |
Resets the level to 0 and clears the counters. |
POST |
/api/admin/chaos/business/logs/clear |
🔐 |
Clears the business activity log. |
GET |
/api/chaos/public/business/status |
🔓 |
Status + counters (read-only). |
GET |
/api/chaos/public/business/logs |
🔓 |
Business activity log stream. |
GET |
/api/chaos/public/business/anomalies |
🔓 |
Pedagogical catalog of anomalies for a level. Parameter: ?level=N. |
Functional chaos — /api/admin/chaos/functional and /api/chaos/public/functional
| Method |
Endpoint |
Auth |
Description |
POST |
/api/admin/chaos/functional |
🔐 |
Sets the functional level. Body: { "level": 0-3 }. |
GET |
/api/admin/chaos/functional/status |
🔐 |
Status + counters per anomaly. |
POST |
/api/admin/chaos/functional/reset |
🔐 |
Resets the level to 0. |
POST |
/api/admin/chaos/functional/logs/clear |
🔐 |
Clears the functional log. |
GET |
/api/chaos/public/functional/status |
🔓 |
Status (read-only). |
GET |
/api/chaos/public/functional/logs |
🔓 |
Functional log stream. |
GET |
/api/chaos/public/functional/anomalies |
🔓 |
Pedagogical catalog. Parameter: ?level=N. |
Scripting chaos — /api/admin/chaos/scripting
| Method |
Endpoint |
Auth |
Description |
POST |
/api/admin/chaos/scripting |
🔐 |
Sets the scripting level. Body: { "level": 0-4 }. |
GET |
/api/admin/chaos/scripting/status |
🔐 |
Status + active bundles. |
POST |
/api/admin/chaos/scripting/reset |
🔐 |
Clears all bundles and resets the level to 0. |
GET |
/api/admin/chaos/scripting/logs |
🔐 |
Scripting activity log (admin). |
DELETE |
/api/admin/chaos/scripting/logs |
🔐 |
Clears the scripting logs. |
GET |
/api/admin/chaos/scripting/public/status |
🔓 |
Status (read-only, for monitoring). |
GET |
/api/admin/chaos/scripting/public/logs |
🔓 |
Scripting log stream (monitoring). |
Global public chaos status — /api/chaos/public
| Method |
Endpoint |
Auth |
Description |
GET |
/api/admin/chaos/public/status |
🔓 |
Consolidated backend + frontend + business + functional status. Used by monitoring without session. |
Hidden admin portal (Security chaos level 4 — Master) — /api/admin/portal
Intentionally vulnerable endpoints
These endpoints are only active when the Security chaos level equals 4 (Master).
Below level 4, all of these endpoints return 404 with no body.
| Method |
Endpoint |
Auth |
Fault |
Description |
GET |
/api/admin/portal/stats |
🔓 🚨 |
S10 |
Exposes without auth: userCount, orderCount, productCount, adminContact (superAdmin email). |
POST |
/api/admin/portal/login |
🔓 🚨 |
S11 |
SQLi login — concatenated native query. Payload: admin' OR '1'='1' --. Generates a valid adminToken on bypass. |
PUT |
/api/admin/portal/accounts/{id}/promote |
X-Admin-Token 🚨 |
S12 |
Promotes an account to superAdmin without checking whether the requester is already superAdmin. |
GET |
/api/admin/portal/accounts |
X-Admin-Token (superAdmin required in DB) 🚨 |
S12 |
Lists all admin accounts with passwordHash exposed. Returns 403 with pedagogical hint if not superAdmin. |
Chained exploitation scenario (Master level)
1. Fuzzing → discovers /admin (React page)
2. GET /api/admin/portal/stats [S10] → retrieves the superAdmin email
3. POST /api/admin/portal/login [S11] → SQLi bypass → obtains adminToken
4. Access to chaos-admin and monitoring via X-Admin-Token
5. PUT /api/admin/portal/accounts/1/promote [S12] → self-promotes to superAdmin
6. GET /api/admin/portal/accounts [S12] → lists accounts + passwordHash
Security faults summary per endpoint
| Fault |
Endpoint |
Activation level |
| S1 SQLi search |
GET /api/products/search?q= |
≥ 1 (Junior) |
| S2 Order IDOR |
GET /api/orders/{id}, GET /api/orders/{id}/details |
≥ 1 (Junior) |
| S3 Exposed hash |
GET /api/auth/me |
≥ 1 (Junior) |
| S4 Stored XSS |
POST /api/orders (shippingAddress field) |
≥ 2 (Intermediate) |
| S5 Price tampering |
POST /api/orders (unitPrice field) |
≥ 2 (Intermediate) |
| S6 Timing attack |
POST /api/auth/login |
≥ 2 (Intermediate) |
| S7 Weak HMAC token |
POST /api/auth/login → X-Debug-Token header |
≥ 3 (Expert) |
| S8 Path Traversal |
GET /api/orders/{id}/invoice?format= |
≥ 3 (Expert) |
| S9 Mass Assignment |
PUT /api/auth/me (email, password fields) |
≥ 3 (Expert) |
| S10 Stats without auth |
GET /api/admin/portal/stats |
= 4 (Master) |
| S11 Portal SQLi |
POST /api/admin/portal/login |
= 4 (Master) |
| S12 IDOR privesc |
PUT /api/admin/portal/accounts/{id}/promote, GET /api/admin/portal/accounts |
= 4 (Master) |