身份验证与安全的人工智能编码规则
AGENTS.md 中关于身份验证和安全的规则,可防止智能体使用自定义加密、泄露秘密或绕过授权检查。
CursorClaude CodeCodexWindsurf Next.jsTypeScriptPostgreSQL
将此文件放入项目根目录,命名为 AGENTS.md。安全规则必须设置为 strict——智能体虽然能编写功能正确的代码,但也很容易引入关键的身份验证或授权漏洞。
AGENTS.md
# Project Rules — Auth and Security
## Authentication — hard rules- NEVER implement custom password hashing. Use `bcrypt`, `argon2`, or the auth library's built-in hashing (Better Auth, Auth.js, Clerk, Supabase Auth). Custom hashing is almost always wrong and may be cryptographically broken.- NEVER store plaintext passwords, plaintext tokens, or plaintext secrets in the database. Hash passwords; hash or encrypt tokens before persistence.- NEVER roll custom JWT signing or verification. Use a well-audited library (`jose`, `jsonwebtoken`). Never use `alg: "none"` — reject tokens with no algorithm.- Session tokens must be at least 128 bits of cryptographic randomness. Use `crypto.getRandomValues()` (Web) or `crypto.randomBytes(32)` (Node.js). Do NOT use `Math.random()` for any security-relevant value.- NEVER store session tokens or JWTs in `localStorage`. Use `HttpOnly`, `Secure`, `SameSite=Lax` cookies. `localStorage` is readable by any XSS payload on the page.
## Authorization — hard rules- Every API route and server action MUST check the current user's session before accessing data. Do not assume that reaching a route implies authorization.- Authorization checks must verify ownership or role, not just authentication. "Is logged in" is authentication. "Is allowed to read this resource" is authorization. Both are required.- Never pass a user-controlled ID directly into a database query without first verifying that the authenticated user has permission to access that record. This is an IDOR (Insecure Direct Object Reference) vulnerability.- In Next.js App Router: run auth checks in middleware OR at the top of every Server Component and Server Action that touches user data. Do not rely on client-side redirects for access control.
## Secrets management- All secrets (API keys, database URLs, OAuth client secrets) live in environment variables. Validate them with Zod at startup via `src/lib/env.ts`.- NEVER commit secrets to the repository. If a secret is accidentally committed, treat it as compromised immediately — rotate it before doing anything else.- NEVER log secrets, tokens, or full request bodies that may contain credentials. Scrub sensitive fields before logging.- Client-side code must never contain secrets. In Next.js, only variables prefixed with `NEXT_PUBLIC_` are exposed to the client — and only non-sensitive values should use that prefix.
## Input validation and output encoding- Validate all user input at the server boundary with Zod before use. Never trust client-provided data, including data in headers, cookies, or URL parameters.- Sanitize any HTML rendered from user input. Use a library (`DOMPurify`, `sanitize-html`) — do NOT write a custom HTML sanitizer.- When constructing URLs from user input, use the `URL` constructor to parse and validate. Never concatenate user input into a URL string that will be fetched server-side — this is an SSRF vector.
## CSRF and clickjacking- All state-mutating endpoints (POST, PUT, PATCH, DELETE) must be protected against CSRF. In Next.js App Router, Server Actions are CSRF-protected by default; do not disable this. For custom API routes, verify the `Origin` header or use a CSRF token.- Add `X-Frame-Options: DENY` or `Content-Security-Policy: frame-ancestors 'none'` to pages that should not be embedded in iframes.
## Definition of done- No `Math.random()` calls in authentication or token generation paths.- No `localStorage` for session/token storage (grep the codebase).- Every API route handler has an auth check at the top.- `NEXT_PUBLIC_` env vars contain no secrets (audit the list before shipping).- Zod validation runs on all form inputs before they touch the database.为什么需要这些规则
- 不要在
localStorage中存储令牌 消除了 React/Next.js 应用中最常见的安全错误。那些从旧版教程(2020 年之前)复制身份验证模式的智能体,常常会将 JWT 存储在localStorage中,而页面上的任何第三方脚本都可以轻易读取它。HttpOnlycookie 根本无法通过 JavaScript 访问——这才是正确的存储机制。 - 授权检查要验证所有权,而不仅仅是身份验证 能堵住智能体最容易忽略的 IDOR 漏洞。当要求智能体“添加一个获取用户订单的端点”时,它通常会检查
if (!session),但不会检查if (order.userId !== session.user.id)——因为第二个检查需要理解数据模型的所有权语义,而这与具体项目相关,并非任务描述所暗示。
适用场景
- 任何包含用户账户、受保护资源或支付数据的应用——实际上就是任何生产级 Web 应用。
不适用场景
- 位于企业 VPN 或网络级访问控制之后的内网工具,其威胁模型不同,部分控制措施可能由基础设施层处理。