AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Detecting Race Conditions

skill-unboundcompute-security-agent-skills-detecting-race-conditions · by UnboundCompute

>-

No reviews yet
0 installs
15 views
0.0% view→install

Install

$ agentstack add skill-unboundcompute-security-agent-skills-detecting-race-conditions

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access Used
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-unboundcompute-security-agent-skills-detecting-race-conditions)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
17d ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Detecting Race Conditions? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Detecting race conditions

Race bugs don't live in one line - they live in the gap between two operations that another actor can slip through. There's no tainted value to trace and no single sink to grep; you find them by asking what state is shared, what runs concurrently, and where a window opens between deciding something and acting on it. This skill covers the recurring shapes and how to confirm a real window.

When to use

  • Multithreaded / async / multiprocess code, or a shared resource (DB row, cache,

counter, file, in-memory map) touched by concurrent requests.

  • A "check then act" sequence where the check's truth can expire before the act:

balance/quota checks, auth-then-use, uniqueness/dedup guards, file existence checks, one-time tokens.

Scope check

Authorized source only. If you can't name the authorization, stop.

The shapes and how to confirm each

Confirmation of a race is an interleaving witness: two concrete operation orders where one is safe and the other, achievable by an attacker, is not.

  1. TOCTOU (time-of-check to time-of-use). State is validated, then used, and

it can change in between. Classic filesystem form: access(path) / stat(path) then open(path) - a symlink swap in the window redirects the open. General form: any check(x); … ; use(x) where x (or what it names) is mutable by another actor in the gap. Confirm: identify the shared thing, show a writer that can change it between check and use.

  1. Check-then-act on shared state without atomicity. "If not exists, create";

"if balance ≥ n, deduct n"; "if not already redeemed, redeem." Two requests both pass the check before either acts → double-spend, duplicate creation, coupon reuse. Confirm: two concurrent runs both read the pre-act value; neither the read+act is atomic (no transaction, lock, SELECT … FOR UPDATE, compare- and-swap, or unique constraint).

  1. Unsynchronized shared mutable state. A field/map/counter read and written

by multiple threads with no lock/atomic. Confirm: two threads reach the same memory, at least one writes, no happens-before relationship (no shared lock, no atomic, no ownership handoff) orders them.

  1. Atomicity violation across a compound update. Several fields that must move

together are updated without a single critical section, so a concurrent reader sees a torn, inconsistent state. Confirm: a reader path observes the fields mid-update.

  1. Lock misuse. Right idea, wrong execution: the lock is taken after the

shared access, a different lock guards read vs write, the lock is released early, or the critical section doesn't cover the whole check-then-act. Confirm: the guarded region doesn't actually span both the decision and the action.

Where to look

Shared sinks are the anchors: process-global/static mutable state, singleton caches, ORM objects reused across requests, filesystem paths derived from a check, and any DB write preceded by an application-level read that decides it. For each, ask: who else touches this concurrently, and is the decision+action atomic?

Worked example

> Double-spend via check-then-act. redeem(code): > row = db.get(code); if row.used: reject; … ; row.used = True; db.save(row). > Two requests with the same code both read used == False before either saves. > Witness: interleave R1.read, R2.read, R1.save, R2.save → both succeed. > No transaction, no SELECT … FOR UPDATE, no unique/CAS on used. Confirmed > atomicity/check-then-act race, severity high, impact = coupon/token reused N > times. Remediation: atomic conditional update (UPDATE … SET used=true WHERE > code=? AND used=false) and act on affected-row-count.

Rationalizations to reject

  • "It's guarded by a check right above." → A check above the act is exactly the

TOCTOU shape unless the check+act is atomic. The gap is the bug.

  • "There's a lock in the function." → Does the critical section span both the

decision and the action, on every path, with the same lock as the writer?

  • "Requests are basically serial in practice." → "Basically" is the window.

Assume concurrent unless the runtime guarantees otherwise.

  • "The DB will sort it out." → Only with a transaction at the right isolation,

a constraint, or a conditional update. A plain read-then-write won't.

Executing this in practice

You need to identify shared state and the concurrent entry points that reach it, then read the ordering around each access. A code property graph helps you find every reader/writer of a shared object and every path into a check-then-act; a concurrency-aware analyzer or a targeted stress/PoC harness corroborates a real window. State each finding as an interleaving witness and emit per the [finding schema](../../FINDING-SCHEMA.md), with the two operation orders in evidence and reachable = conditional on the interleaving.

Related

  • auditing-guard-gaps - when only some paths take the lock/transaction.
  • hunting-bugs-with-a-code-graph - the master loop that routes these here.
  • [FINDING-SCHEMA.md](../../FINDING-SCHEMA.md).

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.