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

nestjs-security-cli

v2.1.1

Published

Advanced IP blocking, role-based security, and attack detection for NestJS applications

Downloads

244

Readme

NestJS Security CLI

Advanced IP blocking, role-based security, and attack detection for NestJS applications.

Requirements

  • Node.js >= 22.x
  • NestJS >= 11.x
  • TypeScript >= 5.x
  • You'll need to maintain the @nestjs/cache-manager and cache-manager packages.

Installation

npm install nestjs-security-cli

Quick Start

import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common'
import { MongooseModule } from '@nestjs/mongoose'
import { SecurityModule, BlacklistedIp, BlacklistedIpSchema, SecurityMiddleware } from 'nestjs-security-cli'

@Module( {
	imports: [
		SecurityModule.forRootAsync( {
			enableAdminPanel: true,
			useFactory: () => ({
				enableDatabase: true,
				defaultBlockDurationHours: 24,
				enableAutoBlocking: true,
				// example of customizing the suspicious patterns
				suspiciousPatterns: [
					{ pattern: '/vendor', name: 'Composer Attempt' },
					{ pattern: '/phpunit', name: 'PHPUnit Attempt' },
					{ pattern: '/lib', name: 'Lib Attempt' },
					{ pattern: '/laravel', name: 'Laravel Attempt' },
					{ pattern: '/www', name: 'WWW Attempt' },
					{ pattern: '/ws', name: 'Web Socket Attempt' },
					{ pattern: '/yii', name: 'Yii Attempt' },
					{ pattern: '/zend', name: 'Zend Attempt' },
					{ pattern: '/test', name: 'Test Attempt' },
					{ pattern: '/tests', name: 'Tests Attempt' },
					{ pattern: '/testing', name: 'Testing Attempt' },
					{ pattern: '/cms', name: 'CMS Attempt' },
					{ pattern: '/crm', name: 'CRM Attempt' }
				]
			}),
			imports: [ MongoDbModule ],
			providers: [ ...IpBlockerProvider ]
		} )
	]
} )
export class AppModule {
}

DATABASE_CONNECTION provider

if you're needing to use the database connection, and the import options isn't working, you can try to pass it directly into the providers array.

    {
        provide: 'DATABASE_CONNECTION',
        inject: [ConfigService],
        useFactory: (configService: ConfigService): Promise<typeof mongoose> => {
        return mongoose.connect(configService.get<string>('DATABASE_HOST'), {
            dbName: configService.get<string>('DATABASE_NAME')
        })
    }

with forRoot

import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common'
import { ConfigModule, ConfigService } from '@nestjs/config'
import { MongooseModule } from '@nestjs/mongoose'
import { SecurityModule, BlacklistedIp, BlacklistedIpSchema } from 'nestjs-security-cli'

@Module( {
	imports: [
		ConfigModule.forRoot(),
		MongoDbModule,
		SecurityModule.forRoot( {
			enableDatabase: true,
			defaultBlockDurationHours: 24,
			enableAutoBlocking: true,
			enableAdminPanel: true,
		} ),
	],
	providers: [ ...IpBlockerProvider ], // Required if enableDatabase is true
} )
export class AppModule {
}

export class AppModule {}

Cache-Only Mode (No Database)

If you don't want to use MongoDB, you can skip the schema registration:

import { Module } from '@nestjs/common'
import { SecurityModule } from 'nestjs-security-cli'

@Module( {
	imports: [
		SecurityModule.forRoot( {
			enableDatabase: false, // This will use only cache
			defaultBlockDurationHours: 24,
			enableAutoBlocking: true
		} )
	]
} )
export class AppModule {}

SecurityService

Since this has switched to using the @Inject('IP_BLOCKER') model to be registered in your app. So by passing the IpBlockerProvider, it will automatically register the model. More on this down below.

Clean up cron

There's a cron that runs to clean up old blocks. By default, it runs every day at midnight. CLEANUP_CRON environment variable.

	// Cleanup expired entries (runs daily)
	@Cron(CronExpression.EVERY_DAY_AT_MIDNIGHT)
	async cleanupExpiredBlocks(): Promise<void> {
		const result = await this.blacklistedIpModel.updateMany(
			{ active: true, expiresAt: { $lt: new Date() } },
			{ active: false }
		)
		console.log(`🧹 Cleaned up ${result.modifiedCount} expired IP blocks`)
	}

Role type

The roles that can be defined in your app. Persist the roles in your user model as an array of strings.

export type Role = 'Admin' | 'User' | 'Moderator' | 'Guest'

Register the IpBlacklistGuard globally

this is no longer needed, since the SecurityModule is now registered globally by default

All you have to do is apply the guard to your controllers.

@UseGuards(IpBlacklistGuard) // add this to any, or all controller endpoints
@Controller()
export class AppController {
	@Get()
	someEndpoint(): object {
		return { message: 'Hello World!' }
	}
}

Admin & Roles guards

  • The Admin guard accepts ONLY users with the role Admin.
  • The Role guard accepts users with ane of (or all) the type "Roles" as mentioned above.
  • To leverage the admin panel, you'll need to create a role called Admin. The user model in your app should have a field called "Roles", which is an array of strings.

To use the AdminGuard just add the decorator to your controller method.

@UseGuards( AdminGuard )
@Controller( 'my-contoller' )

To use the RoleGuard just add the decorator to your controller method.

@Roles( 'Admin', 'User' )
@UseGuards( RoleGuard )

The AdminGuard uses both JwtService and ConfigService to verify the JWT token. So if you're using this in your app, just make sure that the env var is JWT_SECRET and this will work. ( This could be dynamic later ). Also, when passing the token to the methods, you'll need to pass the token as access_token in either the request cookies, or the header authorization bearer token.

const user = await this.jwtService.verifyAsync( token, {
	secret: this.configService.get<string>( 'JWT_SECRET' )
} )

The admin panel

To use the built-in admin panel, you can set the enableAdminPanel: true in the configs as shown in the to set the available endpoints.

Available endpoints:

  • POST /security/blacklist. This will accept a JSON object with the following fields:
    • ip: The IP address to blacklist
    • hours: The duration of the blacklist in hours
    • reason: The reason for the blacklist
  • GET /security/blacklist. This will return a list of all blacklisted IPs
  • GET /security/blacklist/:ip. This will return the details of a specific IP address
  • DELETE /security/blacklist/:ip. This will delete a specific IP address
  • GET /security/analytics. This will return analytics for the last 24 hours

Features

  • 🛡️ IP Blacklisting with MongoDB persistence
  • 🚫 Automatic attack pattern detection
  • ⚡ Redis/Memory caching for fast lookups
  • 👥 Role-based access control (RBAC)
  • 📊 Security analytics and reporting
  • ⏰ Scheduled cleanup of expired blocks

Configuration Options

export interface SecurityConfigInterface {
	enableDatabase?: boolean
	mongooseConnection?: string
	cache?: {
		ttl?: number
		max?: number
		store?: any
	}
	enableAdminPanel?: boolean
	adminPath?: string
	enableAutoBlocking?: boolean
	suspiciousPatterns?: Array<{
		pattern: string
		name: string
		blockDurationHours?: number
	}>
	defaultBlockDurationHours?: number
	enableRateLimit?: boolean
	rateLimitOptions?: {
		windowMs?: number
		max?: number
	}
	enableLogging?: boolean
	logLevel?: 'error' | 'warn' | 'info' | 'debug'
}

API Documentation

[coming soon]

License

MIT