Tip #4

The "Poisoned Payload" (Response Fuzzing)

Why your frontend crashes even when the API returns 200 OK.

The Problem: The "Perfect Contract" Assumption

The Contract (Swagger)

user.ageInteger
itemsArray[]
Status200 OK
Expected Behavior: ✅ Valid Render

Reality (Production)

user.age"30" or null
itemsundefined
Status200 OK
Result: 💥 Cannot read properties of undefined

We are obsessed with HTTP Status codes. But the most dangerous bugs often come from successful requests (200 OK) that contain unexpected data structures (missing keys, nulls, or wrong types).

The Solution: Response Mutation (Fuzzing)

Don't just verify the API works

Checking that GET /user returns a 200 status is a "Happy Path" test.

We've already discussed how to handle Network Latency and Database Failures. Now let's talk about the most insidious killer: Bad Data.

RECOMMENDED

Do use Response Mutation

Intercept a valid real response from your backend, but "poison" it before it reaches the browser.

  • Type Swapping: id: 123 → id: "123"
  • Huge Payload: [10 items] → [10k items]
  • Null Injection: name: "John" → name: null

The Anatomy of a Poisoned Request

Server
200 OK
{ "id": 1 }
Chaos Proxy
Injects "null"
App
CRASH 💥
{ "id": null }

The Code (Python + Playwright)

Here is a chaos test that acts as a Man-in-the-Middle. It allows the real API call to go through, captures the valid response, and then deliberately deletes the avatar_url from the JSON.

tests/chaos_fuzzing.py
def test_chaos_missing_keys(page):
    # 1. Define the Poison Logic
    def poison_payload(route):
        # Fetch the REAL response from the server
        response = route.fetch()
        original_data = response.json()
        
        # 💉 INJECT CHAOS: Delete a critical key
        # Simulates a backend migration error or legacy data
        if "avatar_url" in original_data:
            del original_data["avatar_url"]
            
        # Fulfill the request with the poisoned data
        route.fulfill(
            response=response,
            json=original_data
        )

    # 2. Activate the Chaos Interceptor
    # Intercept only the user profile endpoint
    page.route("**/api/v1/user/profile", poison_payload)

    # 3. Run the User Flow
    page.goto("/dashboard")
    
    # 4. Verify Resilience
    # The test passes if the default placeholder image appears
    # instead of the app crashing or showing a broken image icon.
    expect(page.locator(".user-avatar-placeholder")).to_be_visible()

Note: To perform this on a real Android device, ensure you have your SSL Certificates configured correctly.

Test Data Resilience with Chaos Proxy

Chaos Proxy allows you to modify response bodies on the fly without writing code. Rule-based fuzzing for your entire team. Start Fuzzing in the Cloud.

Try Response Fuzzing

No credit card required

Why this matters

This is the number one cause of the "White Screen of Death" in Single Page Applications. If your code does user.avatar_url.toString() and the API returns null, your entire application blows up. Chaos Engineering isn't just about servers crashing; it's about Data Integrity.