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
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
설치 방법 보기설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.
Broken access control is the most common serious finding in real diffs, and it rarely looks dangerous: there is no exec, no string-built query — just a lookup by id with nothing after it. You find it by asking one question of every entry point the diff touches:
"If user A sends user B's id, what stops it?"
If the answer is not a line of code you can point at, it is a finding.
Enumerate every id the new code accepts: path, query, body, header, nested in a JSON object, inside a batch array, in a GraphQL argument, in a WebSocket message. Follow each to the data layer.
// ❌ any authenticated user reads any invoice
inv, err := h.repo.Get(ctx, r.PathValue("id"))
// ✅ scoped to the caller's organisation in the query itself
inv, err := h.repo.GetForOrg(ctx, r.PathValue("id"), auth.OrgID(ctx))
// ❌ Spring: findById alone, the principal is never consulted
@GetMapping("/orders/{id}") fun get(@PathVariable id: UUID) = repo.findById(id)
// ✅ ownership is part of the lookup
@GetMapping("/orders/{id}") fun get(@PathVariable id: UUID, @AuthenticationPrincipal u: User) =
repo.findByIdAndCustomerId(id, u.customerId) ?: throw NotFound()
Check the second id too: an endpoint that verifies the project in the path, then updates the task whose id is in the body, without checking the task belongs to that project.
// ❌ project ownership checked, task id from the body never tied to it
await assertProjectOwner(req.params.projectId, user.id);
await db.task.update({ where: { id: req.body.taskId }, data: { title } });
// ✅ the task is looked up inside the checked project
await db.task.update({ where: { id: req.body.taskId, projectId: req.params.projectId }, data: { title } });
A privileged action needs a role check, not just "logged in".
requestMatchers(...).permitAll() or .authenticated() on an admin path; a @PreAuthorize removed from a method; a check on the URL that a second mapping of the same handler bypasses.@RolesAllowed where its class's siblings have one; @PermitAll added.permission_classes = [AllowAny], a view missing @login_required beside decorated siblings.# ❌ DRF: a staff-only action reachable by any authenticated user
@action(detail=True, methods=["post"])
def refund(self, request, pk=None): ...
# ✅ the action carries the same permission as the admin viewset
@action(detail=True, methods=["post"], permission_classes=[IsAdminUser])
def refund(self, request, pk=None): ...
Binding a request straight onto an entity lets the client set fields it should not: role, isAdmin, ownerId, orgId, price, emailVerified.
// ❌ Mongoose: whatever the client sends becomes the document
const user = await User.create(req.body);
// ✅ an explicit allowlist of client-settable fields
const { name, email } = req.body;
const user = await User.create({ name, email });
Equivalents: Django ModelForm / DRF serializer with fields = "__all__"; Spring @ModelAttribute or @RequestBody on a JPA entity; Rails params.permit!; Pydantic/request DTO that includes role; Go json.Decode into the domain struct. The response side is the mirror: returning the entity serialises passwordHash, internal flags or other users' rows in a list.
In multi-tenant code, every read and write needs the tenant predicate — including the ones people forget:
ids: [...] — each id must be checked, not the first.// ❌ a lookup error is treated as "no restriction"
perms, err := h.authz.For(ctx, userID)
if err == nil && !perms.CanDelete { return ErrForbidden }
return h.repo.Delete(ctx, id)
// ✅ any error denies
perms, err := h.authz.For(ctx, userID)
if err != nil || !perms.CanDelete { return ErrForbidden }
Also: a switch on role with a permissive default; a feature flag that disables the check when unset; an inverted comparison.
The check on the route the diff adds may be right while the same state change stays reachable another way with a weaker one. For each protected effect the diff touches, list every door: the REST route and its GraphQL mutation, the v1 and v2 handlers, the single-item and the bulk endpoint, the import file, the admin tool, the background job, the WebSocket message, the agent tool. Each needs the same permission on the same resource — not authentication alone, and not a permission on a different object. Also ask whether a field in the body can override what the permission system restricts ("orgId", "ownerId", "role" in an update body) and whether bulk, export and import enforce the check per item. Tenant scoping across copies and lifecycle — caches, search, exports, soft-delete, revocation — is data-isolation-and-lifecycle.
GetForOwner may already scope the query.WHERE id = $1 with no second predicate on a caller-scoped resource.findById, get_object_or_404(Model, pk=pk), Model.findByPk(id) returning straight to the response.nil, true or falls through.OWASP API Security Top 10 2023 — API1 BOLA, API3 BOPLA, API5 BFLA · OWASP Top 10:2025 A01 Broken Access Control · ASVS 5.0 V8 Authorization
아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.
로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.
아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.
Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
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
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use when deciding whether a request needs an analiz task before implementation - the conditions that require the architect's analysis versus going straight to implementation
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.