βοΈ Common Attacks and Security Measures
NestFlux implements multiple layers of security to protect against common web application attacks. This document explains the various security measures implemented and their limitations, helping you understand what's protected and what additional measures you might need.
π Overviewβ
Security is implemented through multiple defense mechanisms:
- π¦ Rate Limiting - DoS/DDoS protection at the application level
- π CORS Configuration - Cross-origin request control
- βοΈ Helmet - HTTP security headers
- π Request Size Limits - Payload size restrictions
- ποΈ SQL Injection Prevention - Drizzle ORM parameterized queries
- β Input Validation - Zod-based request validation and sanitization
Each measure addresses specific attack vectors but has limitations that should be understood for a complete security posture.
π¦ Denial of Service (DoS) Protectionβ
β What NestFlux Implementsβ
NestFlux uses the NestJS Throttler for application-level rate limiting. TTL can be customized via env variables.
π‘οΈ What It Preventsβ
- Application-level DoS: Protects against individual clients overwhelming your application
- Resource exhaustion: Prevents excessive API calls from consuming server resources
β οΈ What It Doesn't Preventβ
- Distributed Denial of Service (DDoS): Multiple clients attacking from different IPs
- Network-level attacks: Attacks targeting infrastructure below the application layer
- Resource-intensive requests: A few legitimate but heavy requests can still cause issues
π Additional DDoS Protectionβ
For production environments, implement external protection. For example:
- π¦ Azure Front Door: Microsoft's Web Application Firewall (WAF)
- βοΈ Cloudflare: Web Application Firewall (WAF) with DDoS protection
- π‘οΈ AWS Shield: Advanced DDoS protection for AWS infrastructure
π Cross-Origin Resource Sharing (CORS)β
β What NestFlux Implementsβ
Configurable CORS policy in the main application.
π‘οΈ What It Preventsβ
- Cross-origin attacks: Blocks unauthorized domains from making requests
- CSRF via XHR: Prevents malicious sites from making AJAX requests
- Data theft: Stops unauthorized JavaScript from accessing your API
β οΈ What It Doesn't Preventβ
- CSRF with forms: Simple POST forms can still bypass CORS
- Server-to-server attacks: CORS is a browser-enforced policy
- Mobile app attacks: Native apps aren't subject to CORS restrictions
π‘ Best Practicesβ
# Production configuration example
CORS_ONLY_ALLOW_DOMAINS="https://yourdomain.com,https://admin.yourdomain.com"
# β Never use in production:
# CORS_ONLY_ALLOW_DOMAINS="*"
βοΈ Helmet - HTTP Security Headersβ
β What NestFlux Implementsβ
Helmet middleware is applied globally.
β What is itβ
Helmet is a Node.js middleware for Express that helps secure web applications by setting various HTTP headers. It can prevent or mitigate common web vulnerabilitiesβlike cross-site scripting (XSS), clickjacking, and sniffing attacksβby configuring headers such as Content-Security-Policy, X-Frame-Options, and Strict-Transport-Security. Essentially, it acts as a protective helmet for your appβs HTTP responses.
π Security Headers Appliedβ
π‘οΈ Content Security Policy (CSP):
- Prevents XSS by controlling resource loading
- Blocks inline scripts and unauthorized external resources
πΌοΈ X-Frame-Options:
- Prevents clickjacking attacks
- Stops your site from being embedded in malicious frames
π X-Content-Type-Options:
- Prevents MIME type sniffing
- Ensures browsers respect declared content types
π X-DNS-Prefetch-Control:
- Controls DNS prefetching to prevent information leakage
π Referrer Policy:
- Controls referrer information sent with requests
β Additional Headers:
Strict-Transport-Security
(HSTS)X-Download-Options
X-Permitted-Cross-Domain-Policies
π‘οΈ What It Preventsβ
- XSS attacks: CSP blocks many cross-site scripting attempts
- Clickjacking: Frame options prevent UI redressing
- MIME sniffing attacks: Content type enforcement
- Information disclosure: Controlled referrer and DNS policies
β οΈ What It Doesn't Preventβ
- XSS in user-generated content: Still need input validation/sanitization
- SQL injection: Headers don't protect against database attacks
- Business logic flaws: Headers are preventative, not comprehensive
- Social engineering: Headers can't prevent user manipulation
π Request Size Limitsβ
β What NestFlux Implementsβ
Body parser with size restrictions on every request. This prevents larger requests from being processed, causing server stress.
π‘οΈ What It Preventsβ
- Large payload attacks: Prevents oversized requests from consuming memory
- Zip bombs: Limits compressed payload size
- Memory exhaustion: Caps request processing resource usage
- Storage overflow: Prevents filling up disk space with large uploads
β οΈ What It Doesn't Preventβ
- Multiple small requests: Many small requests can still overwhelm
- Slow loris attacks: Gradual payload delivery over time
- Application-level resource exhaustion: Complex operations on small payloads
- Network bandwidth attacks: Size limits don't control connection count
ποΈ SQL Injection Preventionβ
β What NestFlux Implementsβ
NestFlux uses Drizzle ORM which provides automatic SQL injection protection through parameterized queries and type-safe query building.
π‘οΈ What It Preventsβ
- Classic SQL injection: All values are automatically parameterized
- Union-based attacks: Query structure is enforced by TypeScript
- Boolean-based blind injection: Parameters prevent logical manipulation
- Time-based attacks: No dynamic SQL construction allows timing attacks
- Second-order injection: Stored data is also safely parameterized on retrieval
β οΈ Raw Query Safetyβ
For cases requiring raw SQL, Drizzle provides safe parameter binding:
import { sql } from 'drizzle-orm';
// β
SAFE: Using parameterized raw queries
async complexQuery(userId: number, searchTerm: string) {
return await this.query().execute(sql`
SELECT u.*, COUNT(r.id) as role_count
FROM user u
LEFT JOIN user_role ur ON u.id = ur.user_id
LEFT JOIN role r ON ur.role_id = r.id
WHERE u.id = ${userId}
AND u.name LIKE ${`%${searchTerm}%`}
GROUP BY u.id
`);
}
// β
SAFE: Using sql.raw with proper escaping
async dynamicOrderBy(column: string, direction: 'ASC' | 'DESC') {
// Validate column name against whitelist
const allowedColumns = ['name', 'email', 'createdAt'];
if (!allowedColumns.includes(column)) {
throw new BadRequestException('Invalid sort column');
}
return await this.query().execute(sql.raw(`
SELECT * FROM user
ORDER BY ${column} ${direction}
`));
}
// β NEVER DO: String concatenation
async unsafeQuery(userInput: string) {
// This is vulnerable to SQL injection
return await this.query().execute(sql.raw(`
SELECT * FROM user WHERE name = '${userInput}'
`)); // DON'T DO THIS!
}
β οΈ What It Doesn't Preventβ
- Logic flaws: Incorrect business logic can still expose data
- Authorization bypasses: SQL safety doesn't enforce access controls
- Data exposure: Overly broad queries can leak sensitive information
- Performance attacks: Complex queries can still cause DoS
- NoSQL injection: Only protects against SQL-based attacks
π‘ Best Practicesβ
1. Always Use Query Builders:
// β
Preferred approach
const users = await db.select().from(userTable).where(eq(userTable.id, userId));
// β Avoid raw SQL unless absolutely necessary
const users = await db.execute(sql`SELECT * FROM user WHERE id = ${userId}`);
2. Validate Dynamic Elements:
// β
Whitelist approach for dynamic queries
const buildSortClause = (column: string) => {
const allowedColumns = {
'name': userTable.name,
'email': userTable.email,
'created': userTable.createdAt,
};
return allowedColumns[column] || userTable.createdAt;
};
π§ Additional Security Considerationsβ
π¨ What You Still Needβ
π‘οΈ Request Body Validation with Zod:
NestFlux uses Zod extensively for runtime validation of request information, ensuring data integrity and preventing malicious payloads:
// Define validation schema
const USER_CREATE_SCHEMA = z.object({
name: z.string().min(1).max(100),
email: z.email(),
age: z.number().int().min(18).max(120),
roles: z.array(z.string().uuid()).optional(),
});
// API endpoint definition
const CREATE_USER_ENDPOINT = {
getPath: () => [],
method: EndpointMethod.POST,
bodyDto: USER_CREATE_SCHEMA,
responseDto: USER_SCHEMA,
} satisfies EndpointDefinition;
// Controller implementation
@Post()
async createUser(
@ValidatedBody(USER_CONTROLLER, 'create') body: z.infer<typeof USER_CREATE_SCHEMA>
) {
// body is automatically validated and type-safe
return this.userService.create(body);
}
π‘οΈ What Zod Validation Prevents:
- Type confusion attacks: Ensures data types match expectations
- Buffer overflow: Enforces string length and array size limits
- Invalid data structures: Rejects malformed objects and arrays
- Business logic bypasses: Enforces domain-specific validation rules
β οΈ What It Doesn't Prevent:
- Logic bombs: Malicious code in valid-looking data
- Denial of service: Large valid payloads can still cause issues
- Advanced XSS: Context-specific XSS vectors may still work
- Social engineering: Users providing valid but malicious data
π― Conclusionβ
NestFlux provides a solid foundation for web application security through multiple defense layers. However, security is not a one-time implementation but an ongoing process.
The built-in security measures protect against common attacks but should be supplemented with additional security practices, infrastructure-level protection, and regular security assessments based on your specific threat model and requirements.