npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@csrf-armor/core

v1.2.0

Published

Framework-agnostic CSRF protection core functionality

Readme

@csrf-armor/core

CodeQL CI npm version TypeScript License: 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

npm install @csrf-armor/core
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 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 characters

Protection 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


🤝 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:


📦 Related Packages

More framework packages coming based on community demand and contributions!


📄 License

MIT © Muneeb Samuels

Questions? Open an issue or start a discussion!