Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions instructions/langchain-python.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ Models have a finite context window measured in tokens. When designing conversat
- Exact-input caching for conversations is often ineffective. Consider semantic caching (embedding-based) for repeated meaning-level queries.
- Semantic caching introduces dependency on embeddings and is not universally suitable.
- Cache only where it reduces cost and meets correctness requirements (e.g., FAQ bots).
- Configure caches through `set_llm_cache(...)` from `langchain_core.globals`; exact-match backends include `InMemoryCache`, `SQLiteCache`, `RedisCache`, and `UpstashRedisCache` (serverless Redis over HTTP, with optional `ttl`), and `RedisSemanticCache` is an embedding-based option.

## Best practices

Expand Down
31 changes: 31 additions & 0 deletions instructions/security-and-owasp.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,15 @@ app.post('/api/auth/login', loginHandler);
import rateLimit from 'express-rate-limit';
const authLimiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 5 });
app.post('/api/auth/login', authLimiter, loginHandler);

// GOOD β€” serverless / multi-instance: the default in-memory store is per process,
// so back the counter with shared storage (e.g. rate-limit-redis for Express,
// or a Redis-backed limiter such as @upstash/ratelimit in edge/serverless handlers)
import { Ratelimit } from '@upstash/ratelimit';
import { Redis } from '@upstash/redis';
const loginLimiter = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(5, '15 m'), prefix: 'auth:login' });
const { success } = await loginLimiter.limit(`login:${clientIp}`);
if (!success) return new Response('Too Many Requests', { status: 429 });
```

### AU6: Missing Session Regeneration on Login (Session Fixation)
Expand Down Expand Up @@ -673,6 +682,28 @@ ALWAYS validate on server too. Use zod, joi, or class-validator.
- **Severity**: IMPORTANT
- **OWASP**: A05

```typescript
// BAD β€” new endpoint shipped without a limiter
app.post('/api/export', exportHandler);

// GOOD β€” Express: per-route limiter sized to the endpoint's cost
import rateLimit from 'express-rate-limit';
const exportLimiter = rateLimit({ windowMs: 60 * 1000, max: 10 });
app.post('/api/export', exportLimiter, exportHandler);

// GOOD β€” Next.js route handler / serverless or edge: use a store shared across instances
// (e.g. rate-limit-redis with Express, or @upstash/ratelimit as shown)
import { Ratelimit } from '@upstash/ratelimit';
import { Redis } from '@upstash/redis';
const limiter = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(10, '1 m') });
export async function POST(req: Request) {
const ip = req.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ?? 'anonymous';
const { success } = await limiter.limit(ip);
if (!success) return new Response('Too Many Requests', { status: 429 });
// ...
}
```

### AP2: GraphQL Without Depth Limiting

- **Severity**: IMPORTANT
Expand Down
Loading