Skip to content

Scripting Chaos

Scripting Chaos progressively increases the complexity of the HTTP tokens required on the checkout journey, to train students in the scripting skills of load testing tools (JMeter, k6, Locust, Gatling): token correlation, double correlation, rotating CSRF, strict sequencing, HMAC signature, and dynamic key derivation.

The goal is not to block the business journey — an order with the right headers always completes regardless of the active level. The goal is to force the tester to progressively enrich their script to keep up with the growing protocol complexity.

Service and endpoint

Class: ChaosScriptingService.java Controller: ChaosScriptingController.java Admin endpoint: POST /api/admin/chaos/scripting body {"level": 0-4}

Levels

Level Label Tokens to manage
0 Disabled No token required
1 Junior 1 token (X-Session-Token) to correlate from login
2 Intermediate 2 tokens (Session + Action) — double correlation
3 Expert 5 tokens — rotating CSRF + sequential step + HMAC signature
4 Maestro Same as Expert + HMAC key derived from sessionToken

Level 4 uses Maestro instead of Master — it is the only chaos family that deviates from the standard nomenclature, to emphasize the "expert art" nature of the level.

Golden rule

The cart remains fully open. Only the login and the 4 checkout steps are protected. The /api/products and /api/cart/* endpoints are never validated by ChaosScriptingService regardless of the active level.

Protected journey

sequenceDiagram
    participant C as Client (script)
    participant L as "POST /api/auth/login"
    participant A as "POST /api/checkout/address"
    participant S as "POST /api/checkout/shipping"
    participant P as "POST /api/checkout/payment"
    participant O as "POST /api/orders"
    C->>L: step1 — credentials
    L-->>C: tokens (Session, Action, CSRF, Step=step2, Sig)
    C->>A: step2 — address + tokens
    A-->>C: rotated tokens (CSRF, Step=step3, Sig)
    C->>S: step3 — shipping + rotated tokens
    S-->>C: rotated tokens (CSRF, Step=step4, Sig)
    C->>P: step4 — payment + rotated tokens
    P-->>C: rotated tokens (CSRF, Step=step5, Sig)
    C->>O: step5 — order + rotated tokens
    O-->>C: 200 OK

On every Expert/Maestro step, the CSRF, Step, and Signature tokens are regenerated and returned to the client. The tester must capture them in the response and reuse them in the next request — this is the heart of the advanced scripting exercise.

Token bundles

ChaosScriptingService stores a TokenBundle per HTTP session in a ConcurrentHashMap<String, TokenBundle> (key = session.getId()). Each bundle holds:

Field Mutability Description
sessionToken final UUID generated at login, never modified
actionToken final UUID generated at login, never modified
email final Email of the logged-in account
csrfToken volatile Rotated at every step (24 bytes base64)
stepToken volatile step1 → step2 → … → step5
signature volatile HMAC recomputed after rotation
hmacKey volatile (Maestro) Key derived from sessionToken

Level 1 — Junior

Targeted skill: basic correlation of a token from an HTTP response.

Step Endpoint Required headers
Login POST /api/auth/login (generates tokens in the response)
Address POST /api/checkout/address X-Session-Token, X-Request-ID
Shipping POST /api/checkout/shipping X-Session-Token, X-Request-ID
Payment POST /api/checkout/payment X-Session-Token, X-Request-ID
Order POST /api/orders X-Session-Token, X-Request-ID

The X-Request-ID is generated on the client side (a different UUID per request), the X-Session-Token must be extracted from the /api/auth/login response and reused as-is in all subsequent steps.

Level 2 — Intermediate

Targeted skill: double correlation, relogin handling under load.

Login generates three headers instead of two: X-Session-Token, X-Action-Token, X-Request-ID. The first two must be propagated across the 4 checkout steps. The tester must also handle periodic relogin to refresh tokens during long sessions.

Level 3 — Expert

Targeted skill: rotating multi-token correlation, strict sequencing, HMAC-SHA256 signature.

At this level, five additional headers appear and three of them rotate at every step:

  • X-Session-Token — fixed (login)
  • X-Action-Token — fixed (login)
  • X-CSRF-Tokenrotated at every checkout step (new 24-byte base64)
  • X-Step-Tokensequential: step2step3step4step5
  • X-Signaturerecomputed on every rotation (HMAC-SHA256)

Signature calculation

The HMAC signature is computed using the formula:

signature = base64url(HMAC-SHA256(payload, key))
payload   = sessionToken + ":" + csrfToken + ":" + stepToken
key       = HMAC_SECRET (Expert) | hmacKey (Maestro)

At Expert level, the key is static:

HMAC_SECRET = "perfshop-chaos-expert-secret-2025"

The tester must recompute the signature at every step with the new csrfToken and stepToken values extracted from the previous response.

Level 4 — Maestro

Targeted skill: dynamic HMAC key derivation, partial reverse engineering.

Identical to Expert, but the HMAC key is no longer static: it is derived from the sessionToken at login time:

hmacKey = base64url(HMAC-SHA256(sessionToken, HMAC_SECRET))

Every session therefore has its own HMAC key, and the tester must recompute this key after every login. To help verify the derivation, login returns an X-Key-Hint header containing the first 8 characters of the derived key — the tester compares their local computation to this hint before signing the first step.

Error codes

HTTP code Error code Cause
400 400 Missing mandatory header (Session, Request-ID, Action)
401 401 X-Session-Token does not match any bundle
401 E-TKN-99 No active bundle — relogin required
401 E-SIG-07 Missing or invalid signature (Expert)
401 E-HMAC-03 Invalid signature (Maestro)
403 E-CSRF-01 Missing or invalid X-CSRF-Token
409 E-STEP-04 Missing or out-of-sequence X-Step-Token
422 422 X-Action-Token does not match the bundle

The E-* codes are PerfShop-specific — they let the tester quickly diagnose which element of the protocol failed without ambiguity.

Prometheus metrics

Metric Type Description
chaos_scripting_level Gauge Current level (0–4)
chaos_scripting_bundles_active Gauge Number of active bundles (logged-in sessions)

The bundles_active counter is useful for observing session memory pressure under load testing — each login creates a bundle that is only cleaned up on HTTP session expiration.

API — admin endpoints

# Enable Expert level
curl -X POST https://perfshop-api.perfshop.io/api/admin/chaos/scripting \
  -H "X-Admin-Token: $TOKEN" -H "Content-Type: application/json" \
  -d '{"level": 3}'

# Current status
curl https://perfshop-api.perfshop.io/api/admin/chaos/scripting/status \
  -H "X-Admin-Token: $TOKEN"

# Reset (level 0 + all bundles cleared)
curl -X POST https://perfshop-api.perfshop.io/api/admin/chaos/scripting/reset \
  -H "X-Admin-Token: $TOKEN"

API — admin logs

# Retrieve the last 100 events (login, OK validations, rejects)
curl https://perfshop-api.perfshop.io/api/admin/chaos/scripting/logs \
  -H "X-Admin-Token: $TOKEN"

# Clear the logs
curl -X DELETE https://perfshop-api.perfshop.io/api/admin/chaos/scripting/logs \
  -H "X-Admin-Token: $TOKEN"

The activity log keeps the last 100 events, newest first. Each entry contains: ts, type (LOGIN/OK/REJECT/RESET/LEVEL), session (first 8 characters of the session ID), email, token (full token for the admin), detail, ok (boolean).

Public endpoints

curl https://perfshop-api.perfshop.io/api/chaos/public/scripting/status
curl https://perfshop-api.perfshop.io/api/chaos/public/scripting/logs

These endpoints are delegated to ChaosScriptingPublicController and expose the state + logs without authentication, to feed real-time monitoring.

Student activation

POST /api/chaos/student/scripting body {"level": N} — requires student mode. The level is capped at 1 without a license (freemium), at 4 with a valid license.

Pedagogical relevance

Level JMeter / k6 skill demonstrated
Junior Regular Expression Extractor on the login response
Intermediate Double extractor, periodic relogin handling
Expert Multi-token extractor, HMAC computation through JSR-223 / crypto.hmac
Maestro Key derivation in a pre-processor, X-Key-Hint verification