@csrf-armor/core
Version:
Framework-agnostic CSRF protection core functionality
254 lines (177 loc) • 7.57 kB
Markdown
# @csrf-armor/core
<img src="https://cdn.nebz.dev/csrf-armor/logo.jpeg" alt="CSRF Armor" />
[](https://github.com/muneebs/csrf-armor/actions/workflows/codeql-analysis.yml)
[](https://github.com/muneebs/csrf-armor/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/@csrf-armor/core)
[](https://www.typescriptlang.org/)
[](https://opensource.org/licenses/MIT)
**Framework-agnostic CSRF protection with multiple security strategies and zero dependencies.**
Built for modern web applications that need flexible, high-performance CSRF protection without vendor lock-in.
## 🚀 Quick Start
```bash
npm install @csrf-armor/core
```
```typescript
import { generateSignedToken, parseSignedToken } from '@csrf-armor/core';
// Generate a secure token
const token = await generateSignedToken('your-32-char-secret', 3600);
// Validate the token later
const payload = await parseSignedToken(submittedToken, 'your-32-char-secret');
console.log('Token valid until:', new Date(payload.exp * 1000));
```
> **⚠️ SECURITY WARNING**: Use a strong secret in production! Generate with `crypto.getRandomValues(new Uint8Array(32))`.
## 🛡️ Choose Your Strategy
| Strategy | Security | Performance | Best For | Setup Complexity |
|----------|----------|-------------|----------|------------------|
| **Signed Double Submit** ⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | E-commerce, finance | Medium |
| **Double Submit** | ⭐ | ⭐⭐⭐⭐⭐ | Local development | Easy |
| **Signed Token** | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | APIs, microservices | Medium |
| **Origin Check** | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | Mobile backends | Easy |
| **Hybrid** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | Maximum security | Hard |
## 🔧 Framework Integration
### Express.js
> **💡 Complete Express.js solution**: [@csrf-armor/express](../express) with React hooks and simplified setup.
### Next.js
> **💡 Complete Next.js solution**: [@csrf-armor/nextjs](../nextjs) with React hooks and simplified setup.
**🔌 More framework examples and adapters**: [Advanced Configuration Guide →](./docs/ADVANCED.md)
## ⚙️ Configuration
### Basic Setup
```typescript
import { createCsrfProtection } from '@csrf-armor/core';
// Recommended for most applications
const csrfProtection = createCsrfProtection(adapter, {
strategy: 'signed-double-submit',
secret: process.env.CSRF_SECRET!, // ⚠️ Required in production
cookie: {
secure: true, // HTTPS only
sameSite: 'strict' // Strict same-site policy
}
});
```
### Strategy-Specific Configuration
```typescript
// High Security (Financial, Healthcare)
{ strategy: 'hybrid', secret: process.env.CSRF_SECRET!, allowedOrigins: ['https://app.com'] }
// High Performance (Public APIs)
{ strategy: 'origin-check', allowedOrigins: ['https://mobile.app'] }
// Balanced (Most Web Apps)
{ strategy: 'signed-double-submit', secret: process.env.CSRF_SECRET! }
// Development
{ strategy: 'double-submit', cookie: { secure: false } }
```
**📚 Complete configuration options**: [Advanced Configuration Guide →](./docs/ADVANCED.md)
## 🔍 Common Issues
### ❓ Getting "Token mismatch" errors?
```typescript
// Ensure your adapter extracts tokens from all sources
async getTokenFromRequest(request: CsrfRequest, config: RequiredCsrfConfig) {
const headers = request.headers instanceof Map
? request.headers
: new Map(Object.entries(request.headers));
// Try header first
const headerValue = headers.get(config.token.headerName.toLowerCase());
if (headerValue) return headerValue;
// Try form data
if (request.body && typeof request.body === 'object') {
const body = request.body as Record<string, unknown>;
const formValue = body[config.token.fieldName];
if (typeof formValue === 'string') return formValue;
}
return undefined;
}
```
### ❓ Tokens not working across subdomains?
```typescript
const config = {
cookie: {
domain: '.yourdomain.com', // Note the leading dot
sameSite: 'lax' // 'strict' blocks cross-subdomain
}
};
```
### ❓ CSRF blocking legitimate requests?
```typescript
const config = {
excludePaths: ['/api/webhooks', '/api/public', '/health'],
skipContentTypes: ['application/json'] // For JSON-only APIs
};
```
### ❓ Performance issues?
Choose a faster strategy or exclude read-only endpoints:
```typescript
// Option 1: Faster strategy
{ strategy: 'double-submit' } // No crypto overhead
// Option 2: Exclude read-only paths
{ excludePaths: ['/api/read', '/api/search'] }
```
## 🧠 Core API
### Token Functions
```typescript
// Generate signed tokens
const token = await generateSignedToken('secret', 3600);
// Parse and validate
const payload = await parseSignedToken(token, 'secret');
console.log('Expires:', new Date(payload.exp * 1000));
// Generate random nonces
const nonce = generateNonce(32); // 64 hex characters
```
### Protection Class
```typescript
const protection = createCsrfProtection(adapter, config);
const result = await protection.protect(request, response);
if (result.success) {
console.log('CSRF token:', result.token);
} else {
console.error('Validation failed:', result.reason);
}
```
### Error Handling
```typescript
import { TokenExpiredError, TokenInvalidError, OriginMismatchError } from '@csrf-armor/core';
try {
await parseSignedToken(token, secret);
} catch (error) {
if (error instanceof TokenExpiredError) {
// Handle expired token
} else if (error instanceof TokenInvalidError) {
// Handle invalid signature
}
}
```
**📖 Complete API documentation**: [Advanced Configuration Guide →](./docs/ADVANCED.md)
## 📚 Documentation
- **[Advanced Configuration Guide](./docs/ADVANCED.md)** - Complex setups, custom strategies, all config options
- **[Security Analysis](./docs/SECURITY.md)** - Security model deep-dive and best practices
- **[Migration Guide](./docs/MIGRATION.md)** - How to migrate from existing CSRF libraries
## 🤝 Contributing
**Community contributions welcome!** This project would benefit from:
**🎯 High-Impact Contributions:**
- **Framework adapters**: Express, Fastify, Koa, SvelteKit, Remix
- **Performance optimizations**: Benchmark improvements, edge cases
- **Security enhancements**: Vulnerability reports, new strategies
- **Developer experience**: Better examples, TypeScript improvements
**🚀 Getting Started:**
1. Fork the repository
2. Create a feature branch: `git checkout -b feature/express-adapter`
3. Make your changes with tests
4. Submit a PR with clear description
**💬 Get Help:**
- 🐛 [Report bugs](https://github.com/muneebs/csrf-armor/issues/new)
- 💡 [Request features](https://github.com/muneebs/csrf-armor/issues/new)
- 💬 [Ask questions](https://github.com/muneebs/csrf-armor/discussions)
## 📦 Related Packages
- **[@csrf-armor/nextjs](../nextjs)** - Next.js App Router middleware and React hooks
- **[@csrf-armor/express](../express)** - Express.js middleware adapter
*More framework packages coming based on community demand and contributions!*
## 📄 License
MIT © [Muneeb Samuels](https://github.com/muneebs)
**Questions?** Open an issue or start a discussion!