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 reviewing Node.js or TypeScript server code - Express/Fastify/Nest handlers, Next.js server actions and route handlers, child_process, ORM raw queries, prototype pollution, template engines, JWT and outbound HTTP clients
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
설치 방법 보기설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.
TypeScript types vanish at runtime: req.query.id: string can arrive as an array or an object. Most Node findings come from that gap, from exec with a template string, from raw-query escape hatches in otherwise safe ORMs, and — in Next.js — from forgetting that a server action is a public endpoint.
// ❌ ?id[$ne]=x or ?id[]=a&id[]=b gives an object or array, not a string
const doc = await Orders.findOne({ id: req.query.id as string, owner: user.id });
// ✅ validate at the boundary (zod/valibot/class-validator) and coerce
const { id } = z.object({ id: z.string().uuid() }).parse(req.query);
Length, includes and equality checks on an unvalidated query value can be bypassed the same way.
// ❌ shell
exec(`convert ${file} out.png`);
spawn("git", ["clone", url], { shell: true });
// ✅ no shell, end of options
execFile("git", ["clone", "--", url, dir]);
Also check the env option for request-controlled keys (NODE_OPTIONS=--require …).
| Library | Unsafe | Safe |
|---|---|---|
| Prisma | $queryRawUnsafe, $executeRawUnsafe, Prisma.raw() | $queryRaw tagged template, model methods |
| TypeORM | query("… " + x), .where(\id = ${id}`)` | .where("id = :id", { id }) |
| Sequelize | sequelize.query(\… ${x}`), literal(x)` | replacements / bind |
| Knex | knex.raw(\… ${x}`)` | knex.raw("… ?", [x]) |
| Drizzle | sql.raw(x) | sql\… ${x}`` |
Mongo/Mongoose: operator injection from JSON bodies (section 1), $where.
"use server" file is a callable POST endpoint, whether or not a page renders a form for it. Each must authenticate and authorize inside the action.// ❌ the page is admin-only, the action is not
"use server";
export async function deleteUser(id: string) { await db.user.delete({ where: { id } }); }
// ✅
export async function deleteUser(id: string) {
const session = await auth();
if (session?.user.role !== "admin") throw new Error("forbidden");
await db.user.delete({ where: { id } });
}
middleware.ts: middleware matchers miss paths, and Next.js < 15.2.3 / 14.2.25 / 13.5.9 / 12.3.5 let an x-middleware-subrequest header skip middleware entirely (CVE-2025-29927). Check in the handler or data layer too.NEXT_PUBLIC_* variables are shipped to the browser.Report only with a gadget: a recursive merge/set of user JSON (lodash.merge, _.set with user paths, hand-written deep merge) where __proto__ or constructor.prototype reaches a property later read for an auth decision, a child_process option (shell, env), or a template option.
// ❌ deepMerge(defaults, req.body) with {"__proto__": {"isAdmin": true}}
// ✅ validate the body against a schema first; build lookups with Object.create(null) or Map
<%- user %>, Handlebars {{{ user }}}, Pug != user → XSS.res.render(view, req.query) or { ...req.body } as locals: template options ride along (EJS outputFunctionName/escapeFunction, CVE-2022-29078 class) → RCE.Handlebars.compile, pug.compile, ejs.render.vm/vm.runInNewContext is not a security boundary; vm2 is discontinued after sandbox escapes. Running user code in either is CRITICAL when reachable.eval, new Function, require(userPath), dynamic import(userPath).js-yaml 3.x load() instantiates JavaScript types (!!js/function) — safeLoad or js-yaml 4's load.node-serialize unserialize on input.baseURL and sends the configured auth headers to that host (CVE-2025-27152 class) — validate that user-supplied paths are relative.jsonwebtoken: jwt.decode does not verify; jwt.verify without algorithms.crypto.timingSafeEqual for MACs (throws on length mismatch — compare lengths first); Math.random for tokens.app.set("trust proxy", true) trusts every hop's X-Forwarded-For.express.static(".") or express.static(__dirname) serves source and .env.res.sendFile(path.join(dir, name)) instead of res.sendFile(name, { root: dir }).file.originalname used as the stored path.app.use(authMiddleware) runs without it.$queryRaw tagged templates, TypeORM parameters or execFile arrays as injection.JSON.parse as unsafe deserialization.exec(, query(, raw(, $queryRawUnsafe(.shell: true."use server" files with exported mutations and no auth() call inside them.as string on req.query / req.params values used in a query.merge(, defaultsDeep(, set( fed with req.body.Node.js security best practices · Next.js data security · CVE-2025-29927, CVE-2025-27152, CVE-2022-29078 · CWE-78, 89, 1321 · OWASP Top 10:2025
아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.
로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.
아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.
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
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.