Skip to content

Security: kamiazya/web-csv-toolbox

SECURITY.md

Security Policy

Reporting Security Vulnerabilities

If you discover a security vulnerability in web-csv-toolbox, please report it privately through GitHub Security Advisories:

πŸ‘‰ Report a Vulnerability

Please include:

  • Description of the vulnerability
  • Steps to reproduce
  • Potential impact
  • Suggested fix (if any)

Response:

  • Security reports will be reviewed and addressed on a best-effort basis
  • Critical vulnerabilities will be prioritized

Supported Versions

Version Supported
0.x.x βœ… (latest only)

We provide security updates for the latest minor version only.

Supply Chain Attack Protection

This project implements a multi-layered defense approach to protect against npm supply chain attacks (such as Shai-Hulud 2.0 and similar threats).

Defense Layers

Layer 1: New Package Release Delay

Configuration: pnpm-workspace.yaml

minimumReleaseAge: 2880  # 48 hours

Blocks installation of packages published within 48 hours. This time buffer allows the community to detect and report malicious package updates before they reach our dependencies.

Trade-offs:

  • βœ… Prevents zero-day supply chain attacks
  • ⚠️ Delays access to legitimate bug fixes and security patches

When to adjust: If you need to install a newly published package immediately, temporarily comment out this setting, then re-enable it after installation.

Layer 2: Install Script Prevention

Configuration: .npmrc

ignore-scripts=true

Prevents execution of preinstall, postinstall, and install scripts from all packages. Even if a compromised package is installed, its malicious code cannot execute during installation.

Whitelist for native modules (if needed):

only-built-dependencies[]=package-name

Current status: This project requires no install scripts. WASM builds use wasm-pack which runs manually via pnpm build:wasm.

Layer 3: Continuous Vulnerability Scanning

Configuration: .github/workflows/.security-scan.yaml

Uses Google's OSV-Scanner to continuously scan dependencies for known vulnerabilities, aggregating data from multiple sources (GitHub Advisory Database, NVD, etc.).

The CI pipeline fails if vulnerabilities are detected, preventing vulnerable code from being merged or deployed.

Checking for Compromise

If you suspect your local environment may be compromised by supply chain attacks, check for these indicators:

1. Search for malicious GitHub repositories:

gh search repos "Shai-Hulud: The Second Coming"

2. Check for malicious workflow files:

find . -name "discussion.yaml" -path "*/.github/workflows/*"

3. Search for known payload files:

find . -name "setup_bun.js" -o -name "bun_environment.js" -o -name "cloud.json"

Additional Resources

Secure Usage Guidelines

⚠️ Critical for Production Applications

When processing user-uploaded CSV files, always implement resource limits to prevent Denial of Service (DoS) attacks.

Quick Security Checklist

Before deploying to production:

  • WorkerPool configured with maxWorkers limit (2-4 for web apps)
  • Early rejection implemented with pool.isFull()
  • Content-Type validation (text/csv only)
  • Content-Length check before reading body
  • Timeout protection with AbortSignal.timeout()
  • Built-in limits configured (maxBufferSize, maxFieldCount)
  • Schema validation with Zod or similar (e.g., email, age ranges)
  • Error logging for security monitoring
  • Rate limiting at application/infrastructure level

Minimal Secure Configuration

import { Hono } from 'hono';
import { stream } from 'hono/streaming';
import { WorkerPool, EnginePresets, parseStringStream } from 'web-csv-toolbox';

const app = new Hono();

// 1. Limit concurrent workers
const pool = new WorkerPool({ maxWorkers: 4 });

app.onShutdown(() => {
  pool.terminate();
});

app.post('/validate-csv', async (c) => {
  // 2. Early rejection if pool is saturated
  if (pool.isFull()) {
    return c.json({ error: 'Service busy, try again later' }, 503);
  }

  // 3. Verify Content-Type
  const contentType = c.req.header('Content-Type');
  if (!contentType?.startsWith('text/csv')) {
    return c.json({ error: 'Content-Type must be text/csv' }, 400);
  }

  // 4. Get request body as stream
  const csvStream = c.req.raw.body?.pipeThrough(new TextDecoderStream());
  if (!csvStream) {
    return c.json({ error: 'Request body required' }, 400);
  }

  // 5. Process with resource limits
  const signal = AbortSignal.timeout(30000); // 30s timeout

  return stream(c, async (stream) => {
    c.header('Content-Type', 'text/event-stream');

    for await (const record of parseStringStream(csvStream, {
      signal,
      engine: EnginePresets.balanced({ workerPool: pool }),
      maxBufferSize: 10 * 1024 * 1024,  // 10M chars
      maxFieldCount: 100_000,             // 100k fields
    })) {
      // Validate and process...
    }
  });
});

Documentation

For comprehensive security implementation:

πŸ“– How-To: Secure CSV Processing - Step-by-step implementation guide

πŸ’‘ Security Model - Understanding the security architecture

Known Security Considerations

1. Resource Exhaustion (DoS)

Threat: Attackers upload multiple large CSV files simultaneously to overwhelm server resources.

Mitigation: Use WorkerPool with limited maxWorkers setting.

Severity: πŸ”΄ High (can cause service outage)

2. Memory Exhaustion

Threat: Extremely long fields or massive number of records consume excessive memory.

Mitigation: Configure maxBufferSize and maxFieldCount.

Severity: 🟑 Medium (can cause crashes)

3. CPU Exhaustion

Threat: Maliciously crafted CSV files with complex escaping slow down parsing.

Mitigation: Use timeout protection with AbortSignal.

Severity: 🟑 Medium (can degrade performance)

4. Compression Bombs

Threat: Small compressed file expands to enormous size when decompressed.

Mitigation: Implement stream-based size limits before parsing.

Severity: 🟑 Medium (can exhaust disk/memory)

Built-in Protections

web-csv-toolbox includes these built-in security features:

  • Buffer size limits (default: 10M characters)
  • Field count limits (default: 100k fields/record)
  • Binary size limits (default: 100MB for ArrayBuffer/Uint8Array)
  • Automatic RangeError on limit violations

These provide a baseline defense, but application-level controls (WorkerPool, timeouts, validation) are essential for production deployments.

Security Best Practices

Defense in Depth

Implement multiple security layers:

  1. Infrastructure: Rate limiting, WAF, CDN
  2. Application: WorkerPool limits, size checks, timeouts
  3. Library: Built-in limits (maxBufferSize, maxFieldCount)
  4. Data: Schema validation (Zod, etc.)

Fail Fast

Reject invalid requests as early as possible:

// βœ… Good: Early rejection
if (pool.isFull()) return 503;

// ❌ Bad: Queue and timeout later
await queueRequest();  // Wastes resources

Monitoring

Log security-relevant events:

if (pool.isFull()) {
  console.warn('WorkerPool saturated - possible attack', {
    ip: c.req.header('X-Forwarded-For'),
    timestamp: new Date().toISOString()
  });
  // Alert monitoring system
}

Disclosure Policy

We follow responsible disclosure:

  1. Report received β†’ Private acknowledgment
  2. Vulnerability confirmed β†’ Private discussion of fix
  3. Patch developed β†’ Testing and validation
  4. Patch released β†’ Public disclosure with credit

Security fixes will be addressed on a best-effort basis as this is a personal open-source project.

Security Updates

Security patches are released as:

  • Patch releases (0.x.Y) for current minor version
  • Security advisories on GitHub
  • Release notes highlighting security fixes

Subscribe to releases on GitHub to stay informed.

Attribution

We credit security researchers who responsibly disclose vulnerabilities (with permission).

Contact

For general security questions (non-vulnerability): Open a GitHub Discussion

There aren’t any published security advisories