Skip to main content
ZombieMutex

30 results · ↑ ↓ navigate · Enter open · Esc close

← Rust & Go security tooling

Security implementation / Go

AuthRace

Authorization and concurrent-write abuse testing

I built a loopback-only Go HTTP regression harness that demonstrates broken object-level authorization and concurrent replay, then proves the corresponding enforcement paths reject cross-tenant writes and apply a logical mutation once.

What I was trying to prove

In an API review, successful authentication is not evidence of object authorization. Concurrent retries also expose bugs that one-at-a-time tests never trigger. I wanted a reproducible attack-and-fix comparison, not a screenshot of a scanner report.

AuthRace: a caller's identity must constrain the target and the side effect

Synthetic verified principal → tenant authorization → atomic operation ledger → local mutation.

  1. 01 · Untrusted request

    Caller + HTTP request

    Fixture principal + tenant and operation

  2. 02 · Authorization

    Tenant scope gate

    Request tenant must equal principal

  3. 03 · Concurrency boundary

    Atomic idempotency

    Principal-bound operation + fingerprint

  4. 04 · Commit

    Local side effect

    Once per logical operation

Failure path: Cross-tenant request → 403. Replayed operation → no second mutation. Same operation ID, different payload → 409.

Enforcement: The reference uses an in-process mutex. A distributed payment system would need transactional storage and reconciliation.

Architecture of the implemented reference system, not a production deployment diagram.

Implementation decisions

  • Built an in-process HTTP service with deliberately vulnerable and hardened implementations sharing a typed request contract.
  • Reproduced a tenant-scope violation caused by trusting request-body ownership rather than a verified principal.
  • Applied a tenant-bound operation key and payload fingerprint under an atomic mutex-protected decision and mutation.
  • Drove 24 concurrent identical HTTP mutations against both implementations to show duplicate side effects versus single-application behavior.
  • Covered malformed requests, authorization rejection, cross-tenant paths, concurrent replay, idempotency key reuse and conflicting payloads with Go tests.

Adversarial paths and trust boundaries

  • An authenticated caller supplies a target tenant they do not own. The vulnerable fixture accepts it; the protected handler rejects before mutation.
  • Simultaneous identical operations arrive after a timeout or request duplication. The vulnerable fixture commits repeatedly, while the repaired handler records a single logical operation.
  • An attacker changes the payload while reusing a valid operation ID. The protected handler raises a fingerprint conflict rather than reinterpreting the ID.

Test evidence

  • go test -race ./... and go vet ./...: passed on Apple Silicon.
  • go run ./cmd/auth-race: 24 concurrent requests produced 120 units of side effects in the vulnerable fixture and 5 in the hardened fixture.
  • All requests target a temporary local httptest server. No external scanning or live payment operations.

Same 24 concurrent requests. Different outcome.

The local fixture sends 24 copies of one logical 5-unit operation. The intentionally vulnerable version applies all 24; the patched version applies it once.

Vulnerable: repeated mutation120 units
Hardened: atomic deduplication5 units

Synthetic local test values, not financial transactions or production service measurements.

Implementation and test method →
Captured execution evidenceRead raw terminal output
Rendered capture of Go test and AuthRace replay results showing 120 vulnerable units versus 5 protected units
Go race tests, vet and the controlled 24-request replay captured from the local test run; image rendered from stdout.

Reproduce locally

cd examples/auth-race-lab
go test -race ./...
go vet ./...
go run ./cmd/auth-race

Run against fixtures or binaries you own or are authorized to inspect. The complete working project remains in my private site repository; the published downloads provide reviewable source and tests, not a public GitHub repository.

What I am not claiming

  • Identity is a synthetic verified-principal fixture, not a real OAuth/JWT verifier.
  • Atomicity is process-local; production requires durable transactional storage, unique constraints and outbox reconciliation.
  • It tests modeled API behavior, not authorization for arbitrary third-party systems.