back

THM - Fool's Mate

Executive Summary

  • Room: Fool’s Mate
  • Platform: TryHackMe
  • Difficulty: Easy
  • Category: Web Security / Client-Side Validation

The Fool’s Mate challenge demonstrates the dangers of relying solely on client-side validation for business logic and access controls. The target application is a chess-themed Node.js web application that uses JavaScript in the browser to prevent users from making winning moves. By bypassing the browser validation entirely and sending a direct API request to the backend, we can trigger the checkmate condition and retrieve the flag.

1. Enumeration

Port Scanning

We begin by scanning the target host using nmap to identify open ports and running services:

nmap -Pn -sC -sV -p- <TARGET_IP>

Findings:

  • Web Server: Node.js / Express application serving the web interface.
  • No additional sensitive services (FTP, SMB, exposed database ports) were detected.

nmap

Web Application Reconnaissance

Running whatweb against the web service confirms the backend stack:

whatweb http://<TARGET_IP>

Key Stack Info:

  • Framework: Express (Node.js)
  • Application Title: Endgame Trainer

whatweb

2. Vulnerability Analysis

Upon interacting with the web interface and playing chess moves, attempting a winning move triggers a client-side warning dialog (“I’ll shut down your PC if you play that.”) and blocks the action.

checkmate

Inspecting the client-side JavaScript source code reveals the following check:

if (probe.isCheckmate()) {
    showSystemNotice("I'll shut down your PC if you play that.");
    return false;
}

viewsource

Root Cause Analysis

  • Client-Side Enforcer: The application relies on client-side JavaScript running in the user’s browser to evaluate whether a move leads to a checkmate and blocks the UI from sending the request if it does.

  • Lack of Server-Side Validation/Enforcement: The backend application relies on the browser to perform validation instead of enforcing security and game rules on the server side.

3. Exploitation

Since client-side controls can be easily bypassed by crafting raw HTTP requests, we bypass the browser environment completely using curl.

We send a raw POST request directly to the move endpoint (/api/move) containing the winning move payload:

curl -X POST http://<TARGET_IP>/api/move \
  -H "Content-Type: application/json" \
  -d '{"from":"a1","to":"a8"}'

Server Response

The backend server processes the move without evaluating the client-side restriction and returns the checkmate status along with the flag:

curl

Copyright © 2026 Mahidul Haque. This post is licensed under a CC BY-NC-ND 4.0 license. You may read, learn, and share links to this post for non‑commercial, educational purposes, as long as you give appropriate attribution. You may not copy, reproduce, adapt, distribute, or use this work commercially without explicit permission.