nestjs-security-cli
v2.1.1
Published
Advanced IP blocking, role-based security, and attack detection for NestJS applications
Downloads
244
Maintainers
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-managerandcache-managerpackages.
Installation
npm install nestjs-security-cliQuick 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 blacklisthours: The duration of the blacklist in hoursreason: 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
