Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
中文简介正在准备中。当前显示原文说明。
Use when the diff changes a workflow with states, money, credits, quotas, approvals, invites, coupons, counters or expiry - skipped or replayed steps, check-then-act races with real impact, negative or overflowing quantities, partial-failure rollback, fail-open defaults, and legitimate features (export, import, search, preview, invite) used against their own rules
中文简介正在准备中。当前显示原文说明。
安装前可以查看交给 AI 代理的指令内容。
Logic flaws have no dangerous-looking line: no exec, no string-built query, nothing a scanner matches. Every request in the attack is valid on its own; the vulnerability is the sequence, the timing or the number. They are also where the money is — free credits, double refunds, skipped approvals, a role nobody granted.
Core principle: name the invariant the workflow promises ("an order ships only after it is paid", "a coupon is redeemed once", "an invite cannot grant more than the inviter has"), then look for a sequence of individually valid requests that breaks it.
// ❌ the transition never checks the current state: ship an unpaid order, refund a refunded one
func (s *Service) Ship(ctx context.Context, id string) error {
return s.repo.SetStatus(ctx, id, StatusShipped)
}
// ✅ the precondition is part of the write; zero rows means the transition is not allowed
res, err := s.db.ExecContext(ctx,
`UPDATE orders SET status = 'shipped' WHERE id = $1 AND org_id = $2 AND status = 'paid'`, id, orgID)
if n, _ := res.RowsAffected(); n == 0 { return ErrInvalidTransition }
Look for: a status taken from the request body; a step endpoint that does not check the previous step completed (verify-email, MFA, payment, approval, KYC); a completed flow that can be replayed (redeem, claim, confirm, accept-invite); a "cancel" that leaves the side effect (credits granted, access given) in place.
Not a "theoretical race": here the attacker sends both requests. A finding when the window is one read-then-write in a handler and the impact is money, quota, a unique claim or a privilege.
// ❌ two parallel requests both read balance=100 and both withdraw 100
const acct = await db.account.findUnique({ where: { id } });
if (acct.balance < amount) throw new Error("insufficient");
await db.account.update({ where: { id }, data: { balance: acct.balance - amount } });
// ✅ one atomic conditional write
const n = await db.$executeRaw`UPDATE account SET balance = balance - ${amount}
WHERE id = ${id} AND balance >= ${amount}`;
if (n === 0) throw new Error("insufficient");
Fixes that work: a conditional UPDATE … WHERE, SELECT … FOR UPDATE inside a transaction, a unique constraint (one redemption row per coupon and user), an idempotency key stored with the result. Fixes that do not: an in-process mutex in a horizontally scaled service, a check in the client, "the UI disables the button".
quantity: -5 turns a purchase into a refund; a negative transfer moves money the other way; a negative duration extends a trial.limit=0 meaning "unlimited".price * qty in 32-bit ints; a total stored in a narrower column than it is computed in; JavaScript numbers above 2^53."1e9", " 5 ", "0x10", true reaching a numeric field through a loose parser.Step 1 commits and step 2 fails: credits granted but the charge declined, a seat allocated but the invite email errored and the retry allocates another, a file stored but the scan that should gate it timed out and the record says clean. Look for multi-step side effects outside one transaction, an external call between two writes, and a catch that logs and continues past a security-relevant step. Compensation must run with the same authorization as the original action.
< where <= is meant at a boundary that matters (a token valid one extra window).What does the code do when the config key is missing, the feature flag is off, the policy service times out, or the record predates the migration?
# ❌ a missing plan means "no limits"
limit = PLAN_LIMITS.get(org.plan)
if limit is not None and usage >= limit: raise QuotaExceeded()
# ✅ unknown plans get the most restrictive limit
limit = PLAN_LIMITS.get(org.plan, PLAN_LIMITS["free"])
Fail-open authorization is access-control-and-idor §5; here the same question applies to entitlements, quotas, approval requirements and review gates.
?filter=salary>100000), sorting by a hidden field and watching the order, a count that reveals existence.Individually harmless outputs can be the prerequisite of a later trust decision: a self-service rename that produces a name another component treats as an admin group, an "unverified" email that a later SSO link trusts, a draft visible to its author that a preview token then exposes to everyone. Write each step's output and the later decision that relies on it; report only when every link is shown in source.
Unpaid goods, free credits, double refunds or a role nobody granted → HIGH; CRITICAL when unauthenticated or unbounded. Bypass of a paid entitlement or quota → MEDIUM to HIGH by value. An oracle that reveals a protected value or record → MEDIUM. A user doing something the product allows them to do → not a finding.
find then update of a balance, counter or stock level with no lock, condition or constraint.default: branch, ?? true, getOrDefault(…, true) or if err != nil { return nil } on an entitlement or approval check.catch that continues past it.OWASP Top 10:2025 A06 Insecure Design · OWASP API Security Top 10 2023 API6 Unrestricted Access to Sensitive Business Flows · CWE-20, 190, 362, 367, 681, 841 · Cloudflare security-audit-skill
还没有评价。欢迎分享你的使用感受。
无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。
还没有评论。来写第一条吧。
Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
中文简介正在准备中。当前显示原文说明。
Use when the diff adds or changes an endpoint, resolver, RPC, job or query that takes an object id, a role check, a request binding or a tenant filter - BOLA/IDOR, function-level authorization, mass assignment and tenant scoping
中文简介正在准备中。当前显示原文说明。
Use on every UI change - semantic HTML, labels for controls, keyboard-navigable dialogs/menus, visible focus, and never color as the only signal
中文简介正在准备中。当前显示原文说明。
Use when a task changes any screen, form, dialog, menu or control - Lighthouse/axe scan of the changed screens, a keyboard walk, and the thresholds that fail a task
中文简介正在准备中。当前显示原文说明。
How to work a task returned with review, QA or UAT findings. Use when a task is in need_revision or PR review comments are in your context.
中文简介正在准备中。当前显示原文说明。
Use when the repository keeps its alerting in code, or a person asks for alerts outside TaskTrooper - PrometheusRule YAML, a Cloud Monitoring alert policy in Terraform, a Datadog monitor, each routed to TaskTrooper's alert ingest URL so it opens an incident here
中文简介正在准备中。当前显示原文说明。