feat: refresh shared skills catalog

This commit is contained in:
vasily committed 2026-10-30 12:40:16 +08:00
1 parent 98bb35e6fb
commit 418792d1ec
49 files changed
+2273 -2390

No files matched your search

+30 -90
View File
@@ -1,98 +1,38 @@
---
name: app-security
description: >
Full-stack application and API security hardening: Four-Pillar upload defense,
SSRF prevention, input boundary clamping, IDOR elimination, and secret masking.
Use when creating or auditing API routes, handling uploads, making outbound requests,
or preparing pre-release security verification.
concerns: [security]
Harden affected application boundaries when implementing or auditing authorization, uploads, user-influenced outbound requests, or sensitive data handling.
scope: global
---
# Application Security Hardening
# Application security
Enforces defensive boundaries across the API membrane, eliminating exploit vectors, path traversals, SSRF risks, IDOR vulnerabilities, and payload exhaustion.
Inspect the affected boundary and existing controls. Apply the protections relevant
to the task; a small fix does not require a full application audit.
```mermaid
flowchart LR
A["Inbound Request"] --> B["1. Membrane Clamping<br/>(Schema & Bound Validation)"]
B --> C["2. Four-Pillar Uploads<br/>(Size, Ext, Magic, Path)"]
C --> D["3. Outbound SSRF Guard<br/>(Loopback/Metadata Block)"]
D --> E["4. Secret Masking<br/>(Zero Token Sediment)"]
```
1. Validate untrusted payloads with runtime schemas and resource bounds derived
from product requirements. Reject invalid data; do not silently truncate credentials.
2. Derive identity from verified server authentication. Enforce tenant/resource
permissions on private reads and writes, preferably within the data operation.
Cover unauthenticated access, cross-tenant access, and relevant races.
3. For uploads, enforce a product-specific extension/type allowlist, stream byte
limits, and appropriate content validation. Magic headers alone do not prove
safety. Use generated storage names and an isolated non-executable root; prevent
traversal and symlink escapes. Serve potentially active content with appropriate
isolation and headers. Bound archive expansion or decoding work when applicable.
4. For user-influenced outbound destinations, allowlist known services where possible.
Parse URLs, restrict schemes, resolve and validate all IPv4/IPv6 addresses, and
prevent DNS changes from bypassing connection checks. Disable redirects or validate
each destination using the same policy. Block private, loopback, link-local,
unspecified, and metadata targets unless a specific trusted internal service is
intentionally allowed. Apply time, response-size, and network egress limits.
5. Redact credentials at logging/telemetry boundaries and keep public errors free
of secrets and internal traces. Apply relevant session, CSRF, rate-limiting, and
browser content controls using existing framework facilities.
6. Verify the changed boundary with meaningful negative cases under
[shared verification](../../protocols/workflow.md#verification). Report actual
protections and gaps; do not claim the whole app is secure from a checklist.
---
## Phase 0: Setup and Protocols
1. Review reference playbooks:
- [references/app-hardening-playbook.md](references/app-hardening-playbook.md) for concrete TypeScript/Python code patterns and boundary clamps.
- [references/review-checklist.md](references/review-checklist.md) for pre-release OWASP verification checks.
2. Invariants:
- Every input payload must be typed and bounded.
- Every state mutation must verify session identity and tenant ownership.
- Outbound HTTP fetches must never touch private/loopback networks.
---
## Phase 1: Ingest and Check
1. **Surface Identification**:
- Inbound API routes (REST, GraphQL, RPC handlers).
- File/document ingestion and attachment endpoints.
- Outbound network calls (webhooks, URL unfurlers, external data scrapers).
- Data persistence operations and logging sinks.
2. **Access Control Check**:
- Confirm identity is derived from verified server sessions/tokens, never trusted client parameters (`userId`, `orgId`).
- Confirm entity queries enforce ownership: verify record exists AND belongs to the authenticated caller before mutating.
---
## Phase 2: Processing (Core Logic)
### Step 1: Input Boundaries & Membrane Clamping
- Never accept arbitrary, unvalidated request dictionaries. Model all payloads using strict schemas (e.g. Pydantic, Zod).
- Enforce hard string limits:
- Text prompts / message content: Max 50,000 characters.
- Titles / Names: Max 100–200 characters.
- Pagination limits: Clamped to `1 <= limit <= 50`.
- Batch arrays: Clamped to max 100–200 items.
- Sanitize entity and path identifiers against path traversal tokens (`../`, `..\\`).
### Step 2: Four-Pillar Upload Defense
When handling file or media uploads:
1. **Size Bounds**: Reject payloads exceeding size thresholds (e.g., 100MB for docs; 5MB for images).
2. **Blocked Extensions**: Reject executable and script formats (`.exe`, `.bat`, `.sh`, `.svg`, `.html`, `.php`).
3. **Magic Byte Inspection**: Inspect file headers to detect disguised binaries (PE `MZ`, ELF, Mach-O).
4. **Path Traversal Defense**:
- Sanitize original filenames (strip path separators and non-printable characters).
- Write files strictly to designated, isolated upload roots with unique IDs (e.g. UUID filenames).
### Step 3: Outbound SSRF Guard
Before executing outbound HTTP requests (scraping, webhooks):
- Validate target URLs against an allowlist or safety filter.
- Block loopback addresses (`127.0.0.1`, `localhost`, `::1`), RFC 1918 private subnets (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), and cloud metadata services (`169.254.169.254`).
- Restrict allowed protocols strictly to `http` and `https`.
### Step 4: Secret Masking & Error Shielding
- Scrub Authorization tokens (`Bearer ***`), provider API keys, and sensitive credentials from logs, database traces, and telemetry.
- In public HTTP error responses, return clean structured error objects with opaque error codes; never leak internal filesystem paths, environment variables, or stack traces.
---
## Phase 3: The System One Balance Pass
- **Augment, Don't Handcuff**:
- Do NOT break local development workflows: allow local mock endpoints and fixture testing in non-production test environments.
- Keep security checks non-intrusive during prototyping; enforce strictly at boundaries and pre-release gates.
- Avoid noisy confirmation warnings for routine safe operations.
---
## Phase 4: Output Execution & Verification
1. Run verification checks from [references/review-checklist.md](references/review-checklist.md).
2. Provide a security verification summary detailing:
- Bound clamps applied to route schemas.
- Upload filters active (size, extension, magic bytes, safe path).
- SSRF protection status on outbound calls.
- Secret scrubbing confirmation.
Use [the playbook](references/app-hardening-playbook.md) for implementation choices
and [the checklist](references/review-checklist.md) for an explicitly requested audit.
Local fixtures need deliberate configuration, not an automatic security bypass.
@@ -1,160 +1,50 @@
# Full-Stack Application Security Hardening Playbook
# Boundary hardening choices
This high-level guide provides a reusable, standardized protocol for auditing and securing full-stack applications (Next.js, Node.js, Express, etc.).
Read the relevant section when implementing that boundary. Values and tools come
from the product's threat model, stack, and resource budgets, not this document.
---
## Identity and authorization
## Phase 1: Endpoint & Access Control (Preventing IDOR)
Authenticate on the server. Bind private reads and writes to the caller's allowed
resources and tenant. Prefer an ownership predicate in the data operation; a
separate read-check-write sequence can race. Verify cookie-authenticated mutations
have appropriate CSRF/origin protections and session expiry behavior.
### 1. The Multi-Tenant Ownership Rule
Every state-changing API request (`POST`, `PUT`, `PATCH`, `DELETE`) and private resource read (`GET`) must establish identity via the server session—never by trusting client parameters.
## Payloads and credentials
#### Never Trust Client User IDs:
```typescript
// ❌ Vulnerable (attacker can pass any userId in body)
const { title, userId } = await req.json();
await db.resource.create({ data: { title, userId } });
Validate runtime shapes and bound request bytes, field lengths, array counts, and
expensive processing. Reject invalid credentials without silent truncation. Hash
passwords with the framework's supported algorithm and settings; bcrypt's 72-byte
input limitation is bytes, not characters. Use the selected algorithm's documented
limits and preserve long-password support when choosing the design.
// ✅ Secure (always bind to verified session)
const session = await getServerSession(authOptions);
if (!session?.user?.id) return unauthorized();
await db.resource.create({ data: { title, userId: session.user.id } });
```
## Uploads
#### Verify Resource Ownership Before Mutation:
```typescript
// Verify target record exists AND belongs to the caller
const item = await db.resource.findUnique({ where: { id } });
if (!item) return notFound();
if (item.userId !== session.user.id) return forbidden();
```
Choose an explicit extension/content allowlist and byte cap per supported format.
Stop streaming at the cap. Inspect content with a suitable parser; signatures alone
cannot validate the whole file. Generate storage IDs; keep the storage root isolated
and non-executable, prevent traversal/symlink escapes, and bound archive expansion.
Serve active content in an appropriate isolated origin or as an attachment. Apply
malware scanning or re-encoding when the threat model warrants it.
#### Lock Down Sensitive Data Endpoints:
* Strip internal data (emails, password hashes, roles, permissions) from public query endpoints.
* Never allow query flags like `?includePrivate=true` unless the caller has verified ownership or administrative authorization for that account.
## User-influenced outbound requests
---
Prefer service allowlists. Resolve all IPv4/IPv6 addresses and validate the actual
connection destination, including DNS changes. Disable redirects or repeat checks
for each hop. Bound time, bytes, and egress. Trusted internal service calls use their
own allowlist rather than a blanket private-network ban.
See [OWASP SSRF guidance](https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html).
## Phase 2: Input Boundaries & Payload Sanitization
## Browser and abuse controls
### 1. Enforce Hard Limits on Every Field
Unbounded input strings can cause database exhaustion, buffer overruns, or CPU denial-of-service (e.g., Bcrypt hashing huge strings).
Use CSP, framing rules, safe content types, CSRF protection, and rate limiting for
the relevant flow. Configure limits by actor, cost, and deployment topology. Apply
HSTS only to intended HTTPS domains; subdomains/preload require deliberate coverage.
Do not disable required browser capabilities through a blanket Permissions-Policy.
| Field Type | Recommended Hard Bound | Rationale |
| :--- | :--- | :--- |
| **Passwords** | Min 8 chars, Max 72–100 chars | Bcrypt truncates or burns excessive CPU beyond 72 bytes |
| **Emails** | Max 254 chars | Standard RFC 5321 length; prevents regex DoS |
| **Titles / Names** | Max 100–200 chars | Prevents UI overflow and DB memory bloat |
| **Descriptions / Content** | Max 2,000–50,000 chars | Prevents payload bombing |
| **Pagination limit** | Clamped to `1 <= limit <= 50` | Prevents querying the entire table at once |
## Verification
### 2. JSON & Batch Array Clamping
When accepting array batches (e.g., bulk updating nodes or items), enforce an explicit upper limit (e.g., max 200–500 items per request).
---
## Phase 3: Safe File & Document Upload Architecture
If an application accepts images, PDFs, or documents, implement the **Four-Pillar Upload Defense**:
```mermaid
flowchart LR
A["File Upload"] --> B["1. Size Check"]
B --> C["2. Extension & MIME Allowlist"]
C --> D["3. Magic Bytes Inspection"]
D --> E["4. Filename Sanitization & Storage"]
```
### 1. Size Caps:
* Check file size before buffering: images (max 2–5MB), documents (max 10MB).
* Terminate stream early if incoming chunks exceed the configured byte threshold.
### 2. Strict MIME & Extension Allowlists:
* **Allowed:** `image/jpeg` (`.jpg`, `.jpeg`), `image/png` (`.png`), `image/webp` (`.webp`), `application/pdf` (`.pdf`), `application/json` (`.json`), `text/markdown` (`.md`).
* **Strictly Blocked:** `.exe`, `.bat`, `.sh`, `.php`, `.js`, `.html`, `.svg` (SVGs can embed `<script>` tags and execute XSS unless explicitly sanitized).
### 3. Magic Bytes (Header Signature) Inspection:
Do not trust the client `Content-Type` header or file extension alone. Inspect the initial bytes of the file buffer:
| Format | Magic Bytes Signature | Hex Representation |
| :--- | :--- | :--- |
| **JPEG** | `\xFF\xD8\xFF` | `FF D8 FF` |
| **PNG** | `\x89PNG\r\n\x1a\n` | `89 50 4E 47` |
| **WebP** | `RIFF....WEBP` | `52 49 46 46` ('RIFF') |
| **PDF** | `%PDF-` | `25 50 44 46` ('%PDF') |
### 4. Filename Sanitization & Non-Executable Storage:
* Strip directory traversal sequences (`../`, `..\\`) and null bytes (`\0`).
* Store files using randomized UUIDs/CUIDs (e.g., `clx987654321.png`) rather than the original user-supplied name.
* Serve uploaded files with `Content-Disposition: attachment` or host from dedicated static object storage (S3/GCS) where server script execution is disabled.
---
## Phase 4: Rate Limiting & Abuse Prevention
### Protect Sensitive Action Gates:
* **Login attempts:** Max 5–10 per 15 minutes per IP.
* **User registrations:** Max 3–5 per hour per IP.
* **Password resets:** Max 3 per hour per email/IP.
* **General API read/write:** 60–120 requests per minute per authenticated user / IP.
### Implementation Strategy:
* **Single Server / Microservice:** Use an in-memory sliding-window bucket with automatic timestamp cleanup.
* **Distributed / Serverless:** Use Redis (e.g., Upstash / Redis token bucket) to share rate limits across multiple instances.
---
## Phase 5: Framework Hardening & HTTP Security Headers
### 1. Disable Fingerprinting
* In `next.config.ts` / `next.config.js`:
```typescript
const nextConfig = {
poweredByHeader: false,
};
```
* In Express:
```typescript
app.disable('x-powered-by');
```
### 2. Standard Security Headers
Inject these headers across all routes (via Next.js `headers()` config, middleware, or reverse proxy):
```http
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Permissions-Policy: camera=(), microphone=(), geolocation=()
```
---
## Phase 6: Continuous Dependency & Build Verification
Establish a 4-step security check before every release:
### 1. Vulnerability Audit:
```bash
npm audit
# Apply automated non-breaking security fixes:
npm audit fix
```
### 2. Static Code & Lint Analysis:
```bash
npm run lint
```
### 3. Automated Security Unit Tests:
Maintain unit tests validating that:
* File upload allowlists reject `.exe`, `.html`, `.svg`, and mismatched magic bytes.
* Rate limiters trigger HTTP 429 when thresholds are exceeded.
* Boundary helpers clamp oversized numbers and truncate/reject excessive payload strings.
* Endpoints reject unauthenticated mutations and IDOR resource manipulation.
### 4. Production Build Verification:
```bash
npm run build
```
Test relevant unauthorized and malformed cases. Audit dependencies when dependency
risk is part of the task; inspect the result before changing versions. Do not run
`npm audit fix` as an automatic audit step or change the user's stack by default.
Follow [shared verification](../../../protocols/workflow.md#verification).
@@ -1,30 +1,18 @@
# Security Review & OWASP Verification Checklist
# Optional security audit checklist
## Input Validation & Boundaries
- [ ] Pydantic schemas enforce hard string bounds (max 50,000 for text, max 200 for titles).
- [ ] Dynamic path/query identifiers validated via `sanitize_identifier()`.
- [ ] Pagination limits clamped to `1 <= limit <= 50`.
- [ ] Batch array inputs clamped to safe upper bounds (max 100–200 items).
Select checks for the requested surface. Record observed controls and evidence;
unchecked items do not automatically become blocking work outside the task.
## Four-Pillar Upload Defense
- [ ] Uploads restricted by `DEFAULT_MAX_FILE_SIZE` (100MB; 5MB for images).
- [ ] Blocked executable extensions rejected (`BLOCKED_EXTENSIONS`).
- [ ] Extension checked against `ALLOWED_EXTENSIONS`.
- [ ] Header magic bytes inspected (`check_magic_bytes`) to block disguised binaries.
- [ ] Filenames sanitized with `sanitize_filename()` (path traversal and CLI injection stripped).
- [ ] Disk writes resolved strictly via `safe_resolve_path()`.
- Runtime input validation and product-specific byte/field/batch limits.
- Verified identity and resource/tenant authorization on private reads and writes.
- Relevant session, CSRF, and rate-limit behavior.
- Upload allowlist, streaming cap, content validation, storage isolation, and safe serving.
- User-influenced URL parsing, all-address DNS checks, connection enforcement,
IPv4/IPv6 policy, redirect controls, time/byte limits, and egress restrictions.
- Credential redaction across logs and telemetry; public errors omit internal traces.
- Parameterized values and separately validated dynamic SQL identifiers.
- Browser content/framing policies appropriate to the application's actual flows.
- Meaningful negative cases for the changed controls, with remaining gaps stated.
## SSRF Defense
- [ ] All outbound requests in research/web-retrieval validated with `validate_safe_url()`.
- [ ] Loopback (`127.0.0.1`), private RFC 1918 subnets, and cloud metadata (`169.254.169.254`) blocked.
- [ ] Scheme restricted strictly to `http` and `https`.
## Secrets & Data Hygiene
- [ ] Zero API keys, bearer tokens, or password hashes written to `error_log` or logs.
- [ ] Authorization headers masked in logging formatters (`Bearer ***`).
- [ ] Production error responses mask internal database paths and raw tracebacks.
## Authorization & State Safety
- [ ] Mutations verify that target records match the active session / conversation scope.
- [ ] SQLite queries use parameterized SQL; no raw string concatenation.
- [ ] Rate limits applied on expensive inference and digestion endpoints.
Helper names and constants follow the existing project. No particular framework,
file cap, pagination limit, or security helper is required by this checklist.