JSPM

nestjs-security-module

1.1.1
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 3
  • Score
    100M100P100Q60078F
  • License MIT

A plug-and-play NestJS security module with CORS, Helmet, rate limiting, audit logging, CSP, XSS sanitization, and more.

Package Exports

    This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (nestjs-security-module) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

    Readme

    NestJS Security Module πŸ”

    npm version Downloads/week

    A plug-and-play security module for NestJS, bundling best-practice HTTP headers, CORS, rate-limiting, audit logging, CSP, XSS sanitization and more.


    Table of Contents

    1. Features
    2. Installation
    3. Basic Usage
    4. Async / Env-Based Configuration
    5. Options Reference
    6. CORS Configuration
    7. Example .env
    8. Troubleshooting

    Features

    • πŸ”’ Helmet integration for standard security headers
    • 🌐 Enhanced CORS support with preflight request handling and case-sensitive headers
    • πŸ›‘οΈ Rate Limiting (per-IP)
    • πŸ“‹ Audit Logging (to console + file)
    • πŸ›‘ Content-Security-Policy (CSP)
    • 🧹 XSS Sanitization (deep sanitize middleware)
    • βš™οΈ Additional headers: Referrer-Policy, HSTS, Expect-CT, Permissions-Policy, COEP …and more

    Installation

    npm install nestjs-security-module
    # or
    yarn add nestjs-security-module

    Basic Usage

    Import and configure the module in your AppModule:

    // app.module.ts
    import { Module } from '@nestjs/common';
    import { SecurityModule } from 'nestjs-security-module';
    
    @Module({
      imports: [
        SecurityModule.forRoot({
          helmet: true,
          cors: {
            origin: 'http://localhost:3000',
            methods: ['GET', 'HEAD', 'POST'],
            allowedHeaders: ['Content-Type', 'content-type', 'Authorization', 'Accept', 'Origin', 'X-Requested-With'],
            credentials: true,
          },
          rateLimit: { windowMs: 60_000, max: 10 },
          auditLog: true,
          csp: true,
          sanitize: true,
          referrerPolicy: true,
          xFrameOptions: 'SAMEORIGIN',
          hsts: true,
          expectCt: true,
          permissionsPolicy: { geolocation: ['self'] },
          crossOriginEmbedderPolicy: true,
        }),
        // … your other modules
      ],
    })
    export class AppModule {}

    Async / Env-Based Configuration

    If you prefer loading options from environment variables via @nestjs/config, use the async API:

    // app.module.ts
    import { Module } from '@nestjs/common';
    import { ConfigModule, ConfigService } from '@nestjs/config';
    import { SecurityModule } from 'nestjs-security-module';
    
    @Module({
      imports: [
        ConfigModule.forRoot({ isGlobal: true }),
        SecurityModule.forRootAsync({
          imports: [ConfigModule],
          inject: [ConfigService],
          useFactory: (cfg: ConfigService) => ({
            helmet: cfg.get<boolean>('SECURITY_HELMET'),
            cors: cfg.get<boolean>('SECURITY_CORS')
              ? {
                  origin: cfg.get<string>('CORS_ORIGIN'),
                  methods: cfg.get<string>('CORS_METHODS').split(','),
                  allowedHeaders: ['Content-Type', 'content-type', 'Authorization', 'Accept', 'Origin', 'X-Requested-With'],
                  credentials: true,
                }
              : undefined,
            rateLimit: cfg.get<boolean>('SECURITY_RATE_LIMIT')
              ? {
                  windowMs: cfg.get<number>('RATE_LIMIT_WINDOW'),
                  max:      cfg.get<number>('RATE_LIMIT_MAX'),
                }
              : undefined,
            auditLog: cfg.get<boolean>('SECURITY_AUDIT_LOG'),
            csp:      cfg.get<boolean>('SECURITY_CSP') ? { directives: { defaultSrc: ["'self'"] } } : undefined,
            sanitize: cfg.get<boolean>('SECURITY_SANITIZE'),
            referrerPolicy: cfg.get<boolean>('SECURITY_REFERRER'),
            xFrameOptions: cfg.get<boolean>('SECURITY_XFRAME') ? 'SAMEORIGIN' : undefined,
            hsts: cfg.get<boolean>('SECURITY_HSTS') ? { maxAge: parseInt(cfg.get<string>('SECURITY_HSTS_MAX_AGE')) } : undefined,
            xContentTypeOptions: cfg.get<boolean>('SECURITY_XCONTENT_TYPE_OPTIONS'),
            expectCt: cfg.get<boolean>('SECURITY_EXPECT_CT') ? { maxAge: parseInt(cfg.get<string>('SECURITY_EXPECT_CT_MAX_AGE')) } : undefined,
            permissionsPolicy: cfg.get<boolean>('SECURITY_PERMISSIONS') ? { geolocation: ['self'] } : undefined,
            crossOriginEmbedderPolicy: cfg.get<boolean>('SECURITY_COEP'),
          }),
        }),
      ],
    })
    export class AppModule {}

    Options Reference

    Option Type Description
    helmet boolean Enable Helmet middleware
    cors boolean | CORSConfig Enable/customize CORS with enhanced support
    rateLimit { windowMs: number; max: number } IP-based rate limiting
    auditLog boolean Log requests to console + file
    csp boolean | object Enable CSP (Content Security Policy)
    sanitize boolean Deep sanitize incoming payloads
    referrerPolicy boolean | object Set Referrer-Policy header
    xFrameOptions boolean | 'DENY' | 'SAMEORIGIN' Set X-Frame-Options header
    hsts boolean | object Enforce HTTPS via Strict-Transport-Security
    xContentTypeOptions boolean Prevent MIME sniffing
    expectCt boolean | object Set Expect-CT header
    permissionsPolicy boolean | Record<string, string[]> Set Permissions-Policy header
    crossOriginEmbedderPolicy boolean | object Enable COEP header

    CORS Configuration

    The CORS configuration has been enhanced with the following improvements:

    Enhanced CORS Options

    interface CORSConfig {
      origin: string;
      methods: string[] | string;
      allowedHeaders?: string[];
      credentials?: boolean;
    }

    Key Improvements

    • βœ… Preflight Request Handling: Automatic OPTIONS request handling
    • βœ… Case-Sensitive Headers: Support for both Content-Type and content-type
    • βœ… Array/String Methods: Support for both array and string method definitions
    • βœ… Credentials Support: Proper handling of credentials in CORS requests
    • βœ… Max-Age Caching: 24-hour preflight response caching

    Example CORS Configuration

    cors: {
      origin: 'http://localhost:3000',
      methods: ['GET', 'HEAD', 'POST'], // Array format
      // or methods: 'GET,HEAD,POST',   // String format
      allowedHeaders: ['Content-Type', 'content-type', 'Authorization', 'Accept', 'Origin', 'X-Requested-With'],
      credentials: true,
    }

    Manual OPTIONS Endpoint (Optional)

    For additional control, you can add a manual OPTIONS endpoint:

    // app.controller.ts
    import { Controller, Options, Res } from '@nestjs/common';
    import { Response } from 'express';
    
    @Controller()
    export class AppController {
      @Options()
      handleOptions(@Res() res: Response): void {
        res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
        res.setHeader('Access-Control-Allow-Methods', 'GET,HEAD,POST,OPTIONS');
        res.setHeader('Access-Control-Allow-Headers', 'Content-Type,content-type,Authorization,Accept,Origin,X-Requested-With');
        res.setHeader('Access-Control-Allow-Credentials', 'true');
        res.setHeader('Access-Control-Max-Age', '86400');
        res.status(200).end();
      }
    }

    Example .env

    SECURITY_HELMET=true
    SECURITY_CORS=true
    CORS_ORIGIN=http://localhost:3000
    CORS_METHODS=GET,HEAD,POST
    SECURITY_RATE_LIMIT=true
    RATE_LIMIT_WINDOW=60000
    RATE_LIMIT_MAX=10
    SECURITY_AUDIT_LOG=true
    SECURITY_CSP=true
    SECURITY_SANITIZE=true
    SECURITY_REFERRER=true
    SECURITY_XFRAME=true
    SECURITY_HSTS=true
    SECURITY_HSTS_MAX_AGE=31536000
    SECURITY_XCONTENT_TYPE_OPTIONS=true
    SECURITY_EXPECT_CT=true
    SECURITY_EXPECT_CT_MAX_AGE=30
    SECURITY_PERMISSIONS=true
    SECURITY_COEP=true

    Troubleshooting

    CORS Issues

    If you encounter CORS errors, ensure:

    1. Origin is correctly set: Use specific origin instead of wildcard *
    2. Headers are case-sensitive: Include both Content-Type and content-type
    3. Methods are properly formatted: Use array format for better compatibility
    4. Credentials are enabled: Set credentials: true for authenticated requests

    Rate Limiting

    • Rate limiting is per-IP address
    • Default: 10 requests per 60 seconds
    • Configure via RATE_LIMIT_WINDOW and RATE_LIMIT_MAX environment variables

    Security Headers

    All security headers are automatically applied when enabled:

    • Content-Security-Policy
    • Strict-Transport-Security
    • X-Frame-Options
    • X-Content-Type-Options
    • Referrer-Policy
    • Permissions-Policy
    • Cross-Origin-Embedder-Policy

    Testing

    Test your CORS configuration:

    # Test preflight request
    curl -v -H "Origin: http://localhost:3000" \
         -H "Access-Control-Request-Method: POST" \
         -H "Access-Control-Request-Headers: content-type" \
         -X OPTIONS http://localhost:3001
    
    # Test regular request
    curl -v -H "Origin: http://localhost:3000" \
         -H "Content-Type: application/json" \
         -X POST http://localhost:3001

    Contributing

    This module includes enhanced CORS support and improved security features. For issues or contributions, please refer to the project repository.