EXERCISE 3 — A JSON + custom-header fetch forgery, and why it fails =================================================================== THE ATTEMPT: fetch("https://target.com/api/transfer", { method: "POST", credentials: "include", headers: { "Content-Type": "application/json", "X-Requested-With": "XMLHttpRequest" }, body: JSON.stringify({ to: "attacker", amount: 5000 }) }); WHAT THE BROWSER DOES, STEP BY STEP: 1. This is NOT a "simple request": it has a custom header (X-Requested-With) AND a non-simple content type (application/json). Either one alone already makes it non-simple. 2. So before sending the real POST, the browser sends a CORS PREFLIGHT -- an OPTIONS request to target.com asking: may origin evil.com send a POST with Content-Type application/json and an X-Requested-With header? 3. target.com is NOT configured to allow evil.com (no Access-Control-Allow-Origin: evil.com, and it won't allow those headers/ methods for a foreign origin). 4. The preflight FAILS. The browser therefore NEVER sends the real POST. The transfer request never reaches the server. The forgery fails. WHY IT FAILS (root cause): - The attacker cannot get the browser to send a cross-origin request that uses JSON or custom headers WITHOUT passing a preflight, and they can't pass the preflight because they don't control target.com's CORS policy. - A plain HTML