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

@@ -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.