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 C, C++ or Objective-C, Rust unsafe blocks, Go unsafe or cgo, JNI, Python ctypes/cffi or C extensions, Swift unsafe pointers, C# unsafe or Marshal code, or a native plugin, parser or loader that sees untrusted bytes - bounds, integer overflow before allocation, unit confusion, lifetimes, uninitialized memory, format strings, FFI ownership and library search order
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
설치 방법 보기설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.
The hard exclusion on memory safety covers memory-safe languages. Native code is the opposite case: in C, C++, Objective-C, unsafe Rust, cgo, JNI and ctypes, one wrong length turns a packet, a save file, a mod, an image or a model file into a read or write outside the buffer. These bugs are in scope whenever untrusted bytes reach the code.
Core principle: re-derive every length, index and lifetime from the worst value the attacker can send — not from the value the tests use — and state the effect you can show (read, write, use-after-free, crash) without inflating it.
A finding needs a realistic untrusted source: a network peer, a file the user opens or downloads (save, replay, mod, asset, document, model), an IPC message from a less-trusted process, a plugin from a third party. A buffer bug reachable only from the program's own constant data, or from a developer's local CLI flag, is a bug, not a vulnerability.
// ❌ len comes from the packet; dst holds 64 bytes
uint16_t len = read_u16(pkt);
memcpy(dst, pkt->data, len);
// ✅ check against the destination AND what the source actually holds
if (len > sizeof(dst) || len > pkt->remaining) return ERR_MALFORMED;
memcpy(dst, pkt->data, len);
Check both sides of every copy. Recompute the room left after a header, a prefix, alignment padding or a terminator. strcpy, strcat, sprintf, gets and strncpy (no terminator when it truncates) on input are findings by shape; std::vector::operator[] and std::span do not check, .at() does.
// ❌ both factors come from the wire: the 32-bit product wraps, the allocation is tiny,
// and the loop still writes count records of rec bytes
uint32_t count = r.u32(), rec = r.u32();
uint8_t* buf = (uint8_t*)malloc(count * rec);
for (uint32_t i = 0; i < count; ++i) r.read(buf + (size_t)i * rec, rec);
// ✅ upper bounds, then checked multiplication in size_t
size_t bytes;
if (count > kMaxRecords || rec > kMaxRecordSize ||
__builtin_mul_overflow((size_t)count, (size_t)rec, &bytes)) return Reject();
High-hit shapes: a - b where b > a can happen; a 64-bit length narrowed to int or uint16_t; a signed length that is negative passed as size_t; -1 as a sentinel that becomes SIZE_MAX; an addition near the type's maximum. Rust: checked_mul/checked_add, or try_into() instead of as for narrowing.
Bytes vs elements vs UTF-16 code units vs pages; sizeof(ptr) where sizeof(*ptr) was meant; a length validated in one unit and used in another. A bounds check that uses the same wrong unit as the allocation is still wrong.
push_back/erase on a container while iterating it; a reference into a vector kept across a resize.c_str() or std::string_view of a temporary; a pointer into a buffer that is reallocated.unsafe: slice::from_raw_parts(ptr, len) with len from input, get_unchecked, set_len before initialization, transmute between unrelated types, a hand-written unsafe impl Send/Sync.static_cast<Derived*>(base) after if (msg.kind == …)) where the object's real type was never checked; a union read through the wrong member.printf(user), syslog(LOG_INFO, user), NSLog(user), String(format: user) — a fixed format with the input as an argument is the fix.
unsafe.Slice/unsafe.String over a C buffer with a length from input.GetByteArrayElements/GetStringUTFChars without the matching release; ctypes calls with no argtypes/restype, so 64-bit pointers are truncated to int.extern "C" boundary.A process — especially one that runs elevated or starts automatically — loads a library, plugin or helper by bare name or relative path, from the working directory, a downloads folder or a user-writable plugin directory: LoadLibrary("x.dll"), dlopen("libx.so") with an attacker-influenced LD_LIBRARY_PATH, a plugin folder scanned without a signature check. A user loading their own plugin into their own process is not a boundary.
This review never compiles or runs the code. Settle it from source: write the worst accepted input through the arithmetic, name the allocation and the access with file:line, and say which effect the trace shows — out-of-bounds read, out-of-bounds write, use-after-free, or only a clean rejection or abort. If the decisive fact is a build flag, architecture, allocator or a foreign library you cannot read, it is a needs-validation note (source-visibility-needs-validation), not a block.
An attacker-controlled out-of-bounds write or use-after-free reachable from the network or from an opened file → CRITICAL (HIGH when it needs a rare precondition). An out-of-bounds read that returns memory to the peer → HIGH. A crash of a shared process (a game server, a daemon) from one input → MEDIUM to HIGH as availability with shared impact (security-hard-exclusions-and-precedents §4). A crash of only the attacker's own client → not a finding.
strcpy on a constant or a length-checked buffer.C.CString, a missing free) as a vulnerability — it is a bug.memcpy, malloc, an index or a loop bound with no check against the buffer.count * size or a - b before an allocation or copy, with no overflow check.strcpy, sprintf, gets, or printf(var).from_raw_parts, get_unchecked, set_len, transmute inside a new unsafe block.LoadLibrary/dlopen with a relative name in a privileged or auto-started process.SEI CERT C Coding Standard · SEI CERT C++ · cgo pointer passing rules · The Rustonomicon · CWE-119, 125, 131, 134, 190, 416, 426, 787, 843 · 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
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.