← Back to Writeups
CUSTOMMediumWeb

Lab 75 — StayNest — Stored XSS in Hotel Booking Form

XESXOR9/2/20263 min read
#web#custom#medium#admin_panel_exploitation#httponly_cookie_bypass#internal_api_exfiltration#stored_xss_injection

Lab 75 — StayNest — Stored XSS in Hotel Booking Form

Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: admin_panel_exploitation, httponly_cookie_bypass, internal_api_exfiltration, stored_xss_injection

Summary

Walkthrough of the CUSTOM Web Lab 75 — StayNest — Stored XSS in Hotel Booking Form. Task: hotel booking platform where admin reviews bookings, HttpOnly cookie blocks external exfiltration. Solution: stored XSS in special_requests field exploits unescaped EJS in admin panel, uses inte

Description

StayNest is a hotel booking platform where travelers can search for hotels, view details, and make reservations. Users create accounts, browse available properties across destinations worldwide, and submit booking requests with their personal details and special requests.

An admin team reviews incoming bookings through an internal management panel. Your goal is to find a way to compromise the admin's session and retrieve the flag.

Credentials provided: user@test.com / password123 ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

English summary: A hotel booking platform where users submit reservations that are reviewed by an admin bot. The goal is to exploit the admin review process to retrieve a flag.

Analysis

  1. Initial reconnaissance:

    • Logged in with provided credentials
    • Found booking form at /hotel/{id}/book with fields: guest_name, phone, address, check_in, check_out, guests, special_requests
    • Bookings show "Pending Review" status — admin bot reviews them periodically
    • Cookie is HttpOnly (connect.sid) — cannot steal via external exfiltration (webhook.site)
    • /robots.txt reveals /admin/ and /api/ endpoints
    • Admin panel at /admin/bookings returns 403 for regular users ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍
  2. Identifying the vulnerability:

    • The admin panel uses EJS templating with unescaped output tags (<%- %>) for guest_name, phone, address, and special_requests fields
    • User input in special_requests is HTML-escaped on user's /my-bookings page but NOT on admin panel
    • Discovered unauthenticated API endpoint at /api/bookings/notes that accepts POST requests to add notes to bookings
  3. Key vulnerability: Stored XSS in the special_requests field. The admin panel renders this field without escaping, allowing JavaScript execution when admin bot reviews bookings. Combined with an unauthenticated internal API, this enables exfiltration despite HttpOnly cookies. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Solution

Since HttpOnly cookie prevents external exfiltration (webhook.site won't receive cookies), the attack uses the internal notes API to store stolen data:

Step 1: Submit booking with XSS payload

html
<img src=x onerror="fetch('/api/bookings/notes',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({booking_id:20,note:document.cookie})})">

This payload:

  • Uses <img src=x onerror=...> to trigger JavaScript (more reliable than <script> tags which may be filtered)
  • Calls the internal /api/bookings/notes API
  • POSTs document.cookie as a note to the booking ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Step 2: Wait for admin bot

The admin bot reviews bookings on the admin panel approximately every 20 seconds. When it loads the page, the XSS executes in the admin's browser context.

Step 3: Retrieve the flag

Check /my-bookings — the flag appears in the booking notes section, exfiltrated from the admin's session.

What didn't work

  • External webhook exfiltration: Cookie is HttpOnly, so document.cookie sent to external domains is empty
  • XSS in profile name field: HTML tags are stripped server-side
  • Script tags: May be filtered; <img onerror> is more reliable ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Key Takeaways / Lessons

  • Mastering admin_panel_exploitation, httponly_cookie_bypass, internal_api_exfiltration, stored_xss_injection was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-04-27 • CUSTOM • Lab 75 — StayNest — Stored XSS in Hotel Booking Form • Difficulty: Medium