Muhammad Faqih · Web & API penetration tester · Remote, UTC+7

I test what happens between the check and the write.

Web and API pentesting with the proof attached: 45 lab cases, 130 screenshots, 123 raw records.

Explore all 45 cases Open this case

Illustration of the recorded run: 10 transfers of 900 all passed the same balance check of 900; the balance ended at -8100.0.

45 cases · 32 FAIL · 13 PASS · 130 screenshots · 123 records · 5 PDF reports

Evidence

45 cases. 32 broke, 13 held. Open any one: the requests, responses and screenshots are inside.

45
Test cases 1
32
FAIL cases 2
13
PASS cases 3
130
screenshots 4
123
HTTP & process records 5
5
PDF reports 6
What these numbers count
Test cases
A test case is one focused check: one behaviour, varied once, with the result recorded.
FAIL cases
Cases where the check found a vulnerability.
PASS cases
Cases where the check passed.
screenshots
Screenshots captured as evidence.
HTTP & process records
Every captured request/response pair and every process record behind the test cases.
PDF reports
The original lab reports, in English and Indonesian.

One bug, taken apart.

  1. Claim

    The /transfer endpoint reads the sender's balance, checks that funds are sufficient, then writes the new balance as a separate operation with no atomic database transaction and no row locking. Ten concurrently sent transfer requests all pass the balance check using the same stale value before any write completes (TOCTOU).

  2. Parallel requests

    (Screenshot 4) EXPLOITATION: ten transfers of 900 are sent concurrently -> all are reported successful.

    POST /transfer HTTP/1.1
    User-Agent: python-requests/2.33.1
    Accept-Encoding: gzip, deflate, br, zstd
    Accept: */*
    Connection: keep-alive
    Authorization: Bearer [REDACTED-LAB-TOKEN]
    Content-Length: 43
    Content-Type: application/json
    
    {"to_account": "9159912486", "amount": 900}
  3. Result

    -8100.0

    (Screenshot 5) CIA IMPACT: the attacker's balance becomes -8100.0, negative and beyond the funds ever held.

  4. Why it worked

    Ten concurrently sent transfer requests all pass the balance check using the same stale value before any write completes (TOCTOU).

    CWE-362: Concurrent Execution using Shared Resource with Improper Synchronization · OWASP A04:2021 - Insecure Design

  5. Fix

    What the fix changes.

    • Perform the balance check and the debit in a single atomic database transaction.
    • Lock the sender's account row (SELECT ... FOR UPDATE) or use a conditional update UPDATE ... SET balance = balance - x WHERE balance >= x.
    • Add a CHECK (balance >= 0) constraint on the balance column as a safety net.
    • Apply an idempotency key and rate limiting to the transfer endpoint.

All 45 cases

Showing 45 of 45

crAPI

VulnBank

Table view

The full lab record behind the summaries above: every test case, screenshot, HTTP capture and original PDF report, browsable case by case.

Test resultsTest casesCategoryCWEscreenshots
LAB PASS Broken Access Control - Login - CSRF Token Cookie Binding Broken Access Control — 5
LAB FAIL Broken Function Level Authorization - Workshop - Management Users Endpoint Broken Function Level Authorization CWE-285 2
LAB PASS Broken Object Level Authorization - Shop - Return Order Broken Object Level Authorization CWE-639 1
LAB FAIL Broken Object Level Authorization - Vehicle - Location Tracking Broken Object Level Authorization CWE-639 2
LAB PASS Broken Object Level Authorization - Vehicle - Location Tracking (Unauthenticated) Broken Object Level Authorization CWE-306 2
LAB FAIL Broken Object Level Authorization - Workshop - Mechanic Report Broken Object Level Authorization CWE-639 2
LAB PASS Broken Object Level Authorization - Workshop - Mechanic Report (Unauthenticated) Broken Object Level Authorization CWE-306 2
LAB FAIL Improper Inventory Management - Authentication - OTP Endpoint Versions Improper Inventory Management CWE-1059 2
LAB FAIL JWT Signature Not Verified - Authentication - JWT Validation JWT Signature Not Verified CWE-347 5
LAB PASS Mass Assignment - Authentication - User Registration Mass Assignment CWE-915 3
LAB FAIL NoSQL Injection - Community - Coupon Validation NoSQL Injection CWE-943 3
LAB PASS NoSQL Injection - Community - Coupon Validation (Normal Input) NoSQL Injection CWE-943 2
LAB PASS OTP Bruteforce Protection - Authentication - Password Reset (Per-Session Lockout) OTP Bruteforce Protection CWE-307 2
LAB FAIL OTP Bruteforce Protection Bypass - Authentication - Password Reset OTP Bruteforce Protection Bypass CWE-307 3
LAB FAIL Server-Side Request Forgery - Workshop - Contact Mechanic Server-Side Request Forgery CWE-918 5
LAB FAIL Unauthenticated Order Access - Shop - Order Details Unauthenticated Order Access CWE-306 2
LAB PASS Unrestricted Access to Sensitive Business Flow - Shop - Coupon Claim Unrestricted Access to Sensitive Business Flow CWE-837 2
LAB FAIL Unrestricted Resource Consumption - Authentication - Login Rate Limiting Unrestricted Resource Consumption CWE-307 2
LAB FAIL Unsafe Consumption of APIs - Workshop - Contact Mechanic Upstream Unsafe Consumption of APIs CWE-20 2
LAB FAIL Account Takeover - Password Reset - Reset PIN Disclosure Account Takeover CWE-640 4
LAB FAIL Active Debug Code - Application Server - Werkzeug Debugger Active Debug Code CWE-489 2
LAB PASS Broken Function Level Authorization - Admin - Administrative Endpoints Broken Function Level Authorization CWE-285 3
LAB FAIL Broken Object Level Authorization - Accounts - Balance Lookup Broken Object Level Authorization CWE-639 3
LAB PASS Broken Object Level Authorization - GraphQL - Transaction Summary Broken Object Level Authorization CWE-639 3
LAB PASS Broken Object Level Authorization - Merchant Payments - Payment By ID Broken Object Level Authorization CWE-639 2
LAB FAIL Broken Object Level Authorization - Merchant Payments - Payments By Merchant Broken Object Level Authorization CWE-639 2
LAB FAIL Broken Object Level Authorization - Users - User Detail API Broken Object Level Authorization CWE-639 3
LAB FAIL Broken Object Level Authorization - Virtual Cards - Card Operations Broken Object Level Authorization CWE-639 4
LAB FAIL Excessive Data Exposure - GraphQL - Schema Introspection Excessive Data Exposure CWE-200 1
LAB FAIL Insufficient Session Expiration - Authentication - JWT Lifetime Insufficient Session Expiration CWE-613 3
LAB PASS JWT Algorithm Confusion - Authentication - alg none JWT Algorithm Confusion CWE-347 3
LAB FAIL JWT Signature Not Verified - Authentication - Token Validation JWT Signature Not Verified CWE-347 4
LAB FAIL Mass Assignment - Registration - Privilege Fields Mass Assignment CWE-915 3
LAB PASS Path Traversal - Profile Picture - Upload Filename Path Traversal CWE-22 2
LAB FAIL Race Condition - Transfer - Balance Check Race Condition CWE-362 5
LAB FAIL Security Misconfiguration - CORS - Wildcard Origin Security Misconfiguration CWE-942 1
LAB FAIL Sensitive Data Exposure - Debug Endpoint - User Credentials Sensitive Data Exposure CWE-200 3
LAB FAIL Sensitive Data Exposure - Web Root - Environment Files Sensitive Data Exposure CWE-538 2
LAB FAIL Server-Side Request Forgery - Profile Picture - Import By URL Server-Side Request Forgery CWE-918 6
LAB FAIL SQL Injection - Authentication - Login Bypass SQL Injection CWE-89 3
LAB FAIL SQL Injection - GraphQL - Transaction Summary Resolver SQL Injection CWE-89 3
LAB FAIL Stored Cross-Site Scripting - User Profile - Bio Field Stored Cross-Site Scripting CWE-79 5
LAB FAIL Unrestricted File Upload - Profile Picture - File Type Validation Unrestricted File Upload CWE-434 3
LAB FAIL Unrestricted Resource Consumption - Authentication - Login Rate Limiting Unrestricted Resource Consumption CWE-307 3
LAB FAIL Unrestricted Resource Consumption - Password Reset - PIN Rate Limiting Unrestricted Resource Consumption CWE-307 5

Burp-TCP

LAB Open-source tool

A Rust SOCKS5 relay and a Java Burp extension, carrying Burp traffic over TCP (WebSocket + Protobuf).

Source on GitHub

Can

  • SOCKS5 CONNECT relay bound only to loopback
  • TCP capture in both directions, with timestamps and offsets
  • Optional manual interception in either direction
  • Traffic history, hex and text views, and a repeater
  • WebSocket and Protobuf for communication between components
  • Windows CI builds and automated tests

Can’t

  • Does not decrypt TLS
  • Does not support UDP
  • Captures TCP chunks; does not reassemble complete protocol messages
  • Holding a stream can cause application heartbeat timeouts

Reports

crAPI — English

English · 57 pages · 21 MB · 19 cases

19 Cases in this report

Read the PDF

crAPI — Bahasa Indonesia

Bahasa Indonesia · 57 pages · 21 MB · 19 cases

19 Cases in this report

Read the PDF

VulnBank — English

English · 82 pages · 20 MB · 26 cases

26 Cases in this report

Read the PDF

VulnBank — Bahasa Indonesia

Bahasa Indonesia · 83 pages · 20 MB · 26 cases

26 Cases in this report

Read the PDF

Cross-project BOLA

English · 100 pages · 5.99 MB

5 Medium, 1 Low, 7 clean passes

LAB — REDACTED SAMPLE

Read the PDF

Experience

Security Analyst

PT Systech Global Informasi (SGI Asia) · Sep 2025 — Present

Application Security Engineer

PT Korelasi Persada Indonesia, assigned to BRI · Aug 2023 — Aug 2025

Individual contribution: Handled approximately 1,200–1,500 DAST-related tickets per year in this role.

OSCP+ / OSCP · 2025 eWPTX · 2024 eMAPT · 2025 PT1 · 2025 Remote · Indonesia · UTC+7

Got a web app or API to test? Write to me.

faqih@siberfaqih.com

Email me

LAB

Use the arrow keys to move between cases.

Open this case