@csrf-armor/core
v1.2.0
Published
Framework-agnostic CSRF protection core functionality
Maintainers
Readme
@csrf-armor/core
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
npm install @csrf-armor/coreimport { 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 with React hooks and simplified setup.
Next.js
💡 Complete Next.js solution: @csrf-armor/nextjs with React hooks and simplified setup.
🔌 More framework examples and adapters: Advanced Configuration Guide →
⚙️ Configuration
Basic Setup
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
// 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 →
🔍 Common Issues
❓ Getting "Token mismatch" errors?
// 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?
const config = {
cookie: {
domain: '.yourdomain.com', // Note the leading dot
sameSite: 'lax' // 'strict' blocks cross-subdomain
}
};❓ CSRF blocking legitimate requests?
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:
// 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
// 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 charactersProtection Class
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
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 →
📚 Documentation
- Advanced Configuration Guide - Complex setups, custom strategies, all config options
- Security Analysis - Security model deep-dive and best practices
- Migration Guide - 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:
- Fork the repository
- Create a feature branch:
git checkout -b feature/express-adapter - Make your changes with tests
- Submit a PR with clear description
💬 Get Help:
📦 Related Packages
- @csrf-armor/nextjs - Next.js App Router middleware and React hooks
- @csrf-armor/express - Express.js middleware adapter
More framework packages coming based on community demand and contributions!
📄 License
MIT © Muneeb Samuels
Questions? Open an issue or start a discussion!
