
Web application security is no longer something that should be handled only by dedicated security engineers. Modern developers are responsible for designing, implementing, and deploying applications that protect user data, business logic, credentials, infrastructure, and APIs.
This is where OWASP becomes extremely important.
The Open Worldwide Application Security Project (OWASP) provides open standards, documentation, methodologies, and tools that help developers understand and prevent common application security vulnerabilities.
This article provides a complete developer-oriented security roadmap covering OWASP fundamentals, HTTP and browser security, authentication, authorization, injection attacks, XSS, CSRF, API security, cryptography, database security, file uploads, SSRF, dependencies, security testing, Node.js/NestJS security, and production architecture.
1. Introduction to OWASP
What Is OWASP?
OWASP stands for the Open Worldwide Application Security Project.
It is a nonprofit organization focused on improving software security.
OWASP provides:
- Security standards
- Security testing methodologies
- Developer guidelines
- Security verification requirements
- Vulnerability awareness
- Security tools
- Training materials
- Security projects
One of the most famous OWASP resources is the OWASP Top 10, which describes major categories of web application security risks.
The important idea is:
OWASP is not a programming framework. It is a security knowledge and standards ecosystem.
OWASP Foundation
The OWASP Foundation supports open-source security projects and provides resources that developers, security engineers, architects, and organizations can use to improve application security.
Some important OWASP projects include:
- OWASP Top 10
- OWASP API Security Top 10
- OWASP ASVS
- OWASP Web Security Testing Guide
- OWASP Dependency-Check
- OWASP ZAP
- OWASP Cheat Sheet Series
2. Vulnerability vs Threat vs Attack vs Risk
These terms are often confused.
Vulnerability
A vulnerability is a weakness in a system.
Example:
app.get('/users/:id', async (req, res) => {
const user = await User.findById(req.params.id);
res.json(user);
});
If the application does not verify that the current user is allowed to access that user ID, the application may contain an authorization vulnerability.
Threat
A threat is something that could potentially cause harm.
Examples:
- Attacker
- Malware
- Stolen credentials
- Malicious insider
Attack
An attack is the actual exploitation of a vulnerability.
For example:
Attacker
↓
Changes /users/100 to /users/101
↓
Server returns another user's data
Risk
Risk combines the likelihood and impact of a security problem.
A simplified model is:
Risk ≈ Likelihood × Impact
A vulnerability with low impact may be less urgent than a vulnerability that exposes passwords or financial information.
3. Security Mindset for Developers
Security should not be an afterthought.
Instead of asking:
"Does this feature work?"
Ask:
"How can this feature be abused?"
For every feature, think about:
Input
↓
Validation
↓
Authentication
↓
Authorization
↓
Business Logic
↓
Database
↓
Response
↓
Logging
For example, when implementing:
DELETE /api/users/123
Do not only ask:
Does the endpoint delete the user?
Ask:
- Is the requester authenticated?
- Is the requester authorized?
- Can one user delete another user?
- Can a normal user delete an admin?
- Is the ID predictable?
- Is the operation logged?
- Is the request rate-limited?
- Can the operation be replayed?
- Is the response leaking information?
This mindset is one of the most important security skills a developer can develop.
4. HTTP and Browser Security Fundamentals
Understanding web security requires understanding how browsers communicate with servers.
A typical request looks like:
GET /api/profile HTTP/1.1
Host: example.com
Authorization: Bearer TOKEN
Cookie: sessionId=abc123
The server responds:
HTTP/1.1 200 OK
Content-Type: application/json
{
"name": "John"
}
Security problems can occur at every stage of this communication.
5. Cookies
Cookies allow servers to store small pieces of information in the browser.
Example:
Set-Cookie: sessionId=abc123
The browser automatically sends:
Cookie: sessionId=abc123
Important cookie attributes include:
HttpOnly
Set-Cookie: sessionId=abc123; HttpOnly
JavaScript cannot directly access the cookie.
This helps reduce the impact of some XSS attacks.
Secure
Set-Cookie: sessionId=abc123; Secure
The browser sends the cookie only over HTTPS.
SameSite
Set-Cookie: sessionId=abc123; SameSite=Lax
Controls when cookies are sent in cross-site requests.
Common values:
Strict
Lax
None
6. Sessions
A traditional session system works like:
Browser
↓
POST /login
↓
Server
↓
Create Session
↓
sessionId
↓
Cookie
The browser later sends:
Cookie: sessionId=abc123
The server looks up the session and identifies the user.
Sessions can be stored in:
- Memory
- Redis
- Database
For distributed applications, Redis is commonly used for session storage.
7. Same-Origin Policy
The browser's Same-Origin Policy prevents websites from freely interacting with resources from other origins.
An origin consists of:
scheme + host + port
For example:
https://example.com:443
is different from:
http://example.com:80
and:
https://api.example.com
8. CORS
CORS stands for Cross-Origin Resource Sharing.
Suppose your frontend runs on:
https://frontend.example.com
and your API runs on:
https://api.example.com
The server can explicitly allow the frontend:
Access-Control-Allow-Origin: https://frontend.example.com
With Express:
app.use(cors({
origin: 'https://frontend.example.com',
credentials: true
}));
Avoid blindly doing:
origin: '*'
especially when credentials are involved.
9. CSRF
Cross-Site Request Forgery occurs when an attacker causes a victim's browser to send an authenticated request to another website.
Imagine:
Victim
↓
Logged into bank.com
The attacker creates a malicious website.
The victim visits it.
The malicious page attempts to trigger:
POST https://bank.com/transfer
If the browser automatically sends authentication cookies, the request may be authenticated.
CSRF defenses include:
- SameSite cookies
- CSRF tokens
- Origin validation
- Referer validation
- Avoiding unsafe state changes through GET requests
10. OWASP Top 10
The OWASP Top 10 provides a high-level classification of important web application security risks.
The current 2025 OWASP Top 10 categories include:
- Broken Access Control
- Security Misconfiguration
- Software Supply Chain Failures
- Cryptographic Failures
- Injection
- Insecure Design
- Authentication Failures
- Software or Data Integrity Failures
- Security Logging and Alerting Failures
- Mishandling of Exceptional Conditions
The exact categories and terminology can evolve between OWASP editions, so developers should always verify the version they are using.
11. A01 — Broken Access Control
Broken access control occurs when users can perform actions they should not be allowed to perform.
Example:
GET /api/users/123
User A changes:
123
to:
124
and receives User B's data.
This is commonly known as:
IDOR — Insecure Direct Object Reference
and is closely related to BOLA — Broken Object Level Authorization.
The solution is not to hide IDs.
The server must enforce authorization.
if (resource.ownerId !== currentUser.id) {
return res.status(403).json({
message: 'Forbidden'
});
}
12. Authentication vs Authorization
Authentication answers:
Who are you?
Authorization answers:
What are you allowed to do?
Example:
Login
↓
Authentication
↓
User = Abanoub
↓
Authorization
↓
Can Abanoub access this resource?
Never confuse the two.
13. RBAC
Role-Based Access Control assigns permissions based on roles.
Example:
User
Admin
Moderator
Manager
Example:
if (user.role !== 'admin') {
return res.status(403).end();
}
A more scalable design uses permissions:
users:read
users:create
users:update
users:delete
Then roles map to permissions.
14. ABAC
Attribute-Based Access Control evaluates attributes.
For example:
User.department === Resource.department
and:
User.clearanceLevel >= Resource.requiredLevel
ABAC can model more complex business rules than simple RBAC.
15. Multi-Tenant Authorization
In SaaS applications, different organizations may use the same application.
For example:
Company A
├── Users
├── Projects
└── Documents
Company B
├── Users
├── Projects
└── Documents
A critical rule is:
Every resource query must enforce tenant isolation.
For example:
Project.findOne({
_id: projectId,
tenantId: currentUser.tenantId
});
Not:
Project.findOne({
_id: projectId
});
16. Authentication Security
A secure authentication system requires more than a login form.
Important topics include:
- Password hashing
- Session management
- Access tokens
- Refresh tokens
- Token rotation
- Brute-force protection
- Credential stuffing protection
- Account enumeration protection
17. Password Hashing
Never store:
password123
in the database.
Do not use simple hashing such as:
crypto.createHash('sha256')
for password storage.
Password hashing should use dedicated password hashing algorithms such as:
- Argon2
- bcrypt
Example conceptually:
Password
↓
Argon2
↓
Password Hash
↓
Database
The hash should be computationally expensive enough to make large-scale guessing attacks more difficult.
18. bcrypt and Argon2
bcrypt is widely used and supported.
Argon2 is a modern password hashing algorithm designed to resist brute-force attacks, particularly attacks accelerated by specialized hardware.
The important principle is:
Password hashing is intentionally expensive.
19. JWT
A JSON Web Token contains claims such as:
{
"sub": "123",
"role": "user",
"exp": 1780000000
}
The server signs the token.
The client sends:
Authorization: Bearer TOKEN
JWTs can be useful for stateless authentication, but they are not automatically secure simply because they are JWTs.
Security depends on:
- Signing algorithms
- Key management
- Token expiration
- Token storage
- Token revocation strategy
- Audience and issuer validation
- Refresh token handling
20. Access Tokens and Refresh Tokens
A common architecture is:
Access Token
Short lifetime
+
Refresh Token
Longer lifetime
For example:
Access Token → 10 minutes
Refresh Token → longer lifetime
When the access token expires:
Client
↓
Refresh Token
↓
Server
↓
New Access Token
Refresh tokens should be protected carefully.
21. Refresh Token Rotation
Instead of keeping one refresh token forever:
Refresh Token A
↓
Used
↓
Refresh Token B
The old token becomes invalid.
This helps detect token theft and replay.
A secure implementation can maintain refresh-token state in Redis or a database.
22. Account Enumeration
An application should avoid revealing whether an account exists.
Bad:
Email does not exist.
or:
Incorrect password.
depending on the supplied email.
A safer generic response might be:
Invalid email or password.
For password reset:
If an account exists, a reset email will be sent.
23. Brute Force and Credential Stuffing
Brute Force
An attacker repeatedly guesses passwords for one account.
Credential Stuffing
An attacker uses leaked username/password combinations from another service.
Defenses include:
- Rate limiting
- Login attempt throttling
- MFA
- Strong password policies
- Breached-password detection
- Monitoring
- Device/risk detection
24. Injection Attacks
Injection occurs when untrusted input is interpreted as part of another language or command.
Examples:
- SQL Injection
- NoSQL Injection
- Command Injection
- LDAP Injection
- Template Injection
- XSS
The general rule is:
Never allow untrusted data to become executable syntax.
25. SQL Injection
Unsafe:
const query = `
SELECT * FROM users
WHERE email = '${email}'
`;
If user input becomes SQL syntax, the attacker may manipulate the query.
Use parameterized queries:
const result = await db.query(
'SELECT * FROM users WHERE email = $1',
[email]
);
ORMs can help, but they do not automatically eliminate every injection vulnerability.
26. NoSQL Injection
MongoDB applications can also suffer from injection when user-controlled objects are passed directly into database operations.
Never blindly trust:
req.body
as a database query.
Instead, validate and construct the query explicitly:
const user = await User.findOne({
email: validatedEmail
});
27. Command Injection
Unsafe:
exec(`ping ${host}`);
If attacker-controlled input reaches the shell, the attacker may execute commands.
Prefer APIs that avoid shell interpretation.
For example, use argument arrays where appropriate:
spawn('ping', ['-c', '1', host]);
Even then, validate the input.
28. XSS
Cross-Site Scripting occurs when attacker-controlled content is executed as JavaScript in another user's browser.
There are three major types:
- Reflected XSS
- Stored XSS
- DOM-based XSS
29. Reflected XSS
The malicious input is immediately reflected in the response.
Example concept:
/search?q=<malicious-input>
If the server inserts the value into HTML without proper encoding, the browser may interpret it as markup or script.
30. Stored XSS
The malicious payload is stored on the server.
For example:
User submits comment
↓
Database
↓
Another user opens page
↓
Payload executes
Stored XSS can be especially dangerous because one attacker-controlled value can affect many users.
31. DOM XSS
DOM XSS occurs when client-side JavaScript processes untrusted data unsafely.
Dangerous example:
element.innerHTML = userInput;
Safer:
element.textContent = userInput;
Frameworks such as Angular provide useful protections, but developers can still bypass those protections with unsafe APIs.
32. XSS Prevention
Important defenses include:
Output Encoding
Encode data according to its context:
- HTML
- Attribute
- JavaScript
- CSS
- URL
Sanitization
When HTML must be accepted, sanitize it with a trusted sanitizer.
CSP
A Content Security Policy can reduce the impact of some XSS vulnerabilities.
HttpOnly Cookies
Sensitive cookies should generally use:
HttpOnly
Secure
SameSite
when appropriate.
33. Content Security Policy
A CSP controls which resources the browser is allowed to load or execute.
Example:
Content-Security-Policy:
default-src 'self';
script-src 'self';
object-src 'none';
base-uri 'self';
A strong CSP can significantly reduce the impact of XSS.
However, CSP should be treated as a defense-in-depth mechanism, not a replacement for secure coding.
34. CSRF Protection
Common defenses include:
SameSite Cookies
SameSite=Lax
or:
SameSite=Strict
depending on application requirements.
CSRF Tokens
The server generates a token.
The client sends it with state-changing requests.
X-CSRF-Token: RANDOM_VALUE
The server verifies it.
Double Submit Cookie
The application stores a CSRF token in a cookie and requires the client to submit the same value in a request parameter/header.
Origin Validation
The server can validate:
Origin: https://example.com
against trusted origins.
35. API Security
Modern applications heavily depend on APIs.
A secure API should implement:
Authentication
Authorization
Validation
Rate Limiting
Logging
Error Handling
Security Headers
Monitoring
36. Input Validation
Never assume API clients are trustworthy.
Validate:
- Type
- Length
- Format
- Range
- Allowed values
- Nested structures
Example:
{
"age": 25
}
should not automatically become:
{
"age": {
"$gt": 0
}
}
without proper validation.
37. Mass Assignment
Suppose your API expects:
{
"name": "John"
}
but the client sends:
{
"name": "John",
"role": "admin"
}
If the server blindly persists the entire object, the user may escalate privileges.
Instead, explicitly select fields:
const update = {
name: req.body.name
};
This is called an allowlist approach.
38. Excessive Data Exposure
Suppose the API returns:
{
"id": 1,
"name": "John",
"email": "john@example.com",
"passwordHash": "...",
"internalNotes": "...",
"isAdmin": true
}
The frontend may only need:
{
"id": 1,
"name": "John"
}
Return only the data required by the client.
39. Pagination Abuse
An endpoint like:
GET /users?limit=1000000
can consume large amounts of:
- CPU
- Memory
- Database resources
- Network bandwidth
Use limits:
Default limit = 20
Maximum limit = 100
40. API Rate Limiting
Rate limiting protects APIs against:
- Brute force
- Credential stuffing
- DoS attempts
- Expensive endpoint abuse
- Excessive scraping
Example concept:
100 requests / minute / user
Sensitive endpoints should often have stricter limits.
41. Security Headers
Important security headers include:
Content-Security-Policy
Controls allowed resources.
Strict-Transport-Security
Forces browsers to use HTTPS.
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options
X-Content-Type-Options: nosniff
Referrer-Policy
Controls how much referrer information is sent.
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy
Controls access to browser features.
Frame Protection
Modern applications commonly use CSP:
frame-ancestors 'none'
to prevent unwanted framing.
42. Cryptography
Cryptography has several different purposes.
Do not confuse:
Encryption
Hashing
Encoding
Signing
43. Encryption vs Hashing
Encryption is reversible:
Plaintext
↓
Encryption
↓
Ciphertext
↓
Decryption
↓
Plaintext
Hashing is designed to be one-way:
Input
↓
Hash Function
↓
Digest
Passwords should normally be stored using password hashing rather than reversible encryption.
44. Symmetric Encryption
The same secret key is used to encrypt and decrypt.
Key
↓
Encrypt
↓
Ciphertext
↓
Decrypt
↓
Plaintext
AES is a common symmetric encryption algorithm.
45. Asymmetric Cryptography
Uses a key pair:
Public Key
Private Key
Common algorithms include:
- RSA
- ECC
Asymmetric cryptography is useful for:
- Key exchange
- Digital signatures
- Authentication
46. Digital Signatures
A digital signature provides integrity and authenticity.
Conceptually:
Message
↓
Hash
↓
Sign with Private Key
↓
Signature
The receiver uses the public key to verify the signature.
JWT signatures are an example of this concept.
47. Key Management
Strong cryptography with poor key management is still insecure.
Never hard-code:
const SECRET = 'my-super-secret';
in source code.
Use:
- Environment variables
- Secret managers
- Key management systems
- Proper access control
- Key rotation
48. Database Security
Database security includes more than preventing SQL injection.
Important practices include:
- Least privilege
- Separate database users
- Strong authentication
- Network restrictions
- Encryption
- Secure queries
- Backups
- Monitoring
- Secret management
The application should not connect as a database superuser.
49. Least Privilege
If an application only needs:
SELECT
INSERT
UPDATE
do not give it:
DROP DATABASE
CREATE USER
SUPERUSER
Give each component the minimum privileges required.
50. File Upload Security
File uploads are dangerous because attackers may upload:
- Executable files
- Web shells
- Malicious HTML
- Malware
- Oversized files
- Files designed to exploit parsers
Do not trust:
filename
extension
Content-Type
from the client alone.
51. Secure File Upload Pipeline
A safer pipeline looks like:
Upload
↓
Authentication
↓
Authorization
↓
Size Validation
↓
Extension Validation
↓
MIME Verification
↓
Content Validation
↓
Malware Scanning
↓
Random Filename
↓
Private Storage
Store uploads outside executable web directories whenever possible.
52. Path Traversal
Path traversal attempts to access files outside the intended directory.
Example concept:
../../../../etc/passwd
Never directly concatenate user input into filesystem paths.
Use safe path resolution and enforce that the final path remains inside the intended directory.
53. SSRF
Server-Side Request Forgery occurs when an attacker controls a URL that the server requests.
Example:
Attacker
↓
Your API
↓
Internal service
The server may have access to resources that the attacker cannot access directly.
Potential targets include:
- Internal services
- localhost
- Private networks
- Cloud metadata services
54. SSRF Prevention
Do not simply trust user-provided URLs.
Defenses include:
- Allowlisting destinations
- Blocking private IP ranges
- Blocking localhost
- Validating protocols
- Restricting redirects
- DNS/IP validation
- Network segmentation
- Egress controls
SSRF protection should exist at both application and infrastructure levels.
55. Serialization and Deserialization Security
Serialization converts objects into a transferable representation.
Deserialization reconstructs them.
Unsafe deserialization can become dangerous when attacker-controlled serialized data is interpreted by powerful object mechanisms.
The safest principle is:
Never deserialize untrusted data using unsafe object reconstruction mechanisms.
Prefer simple, well-defined data formats and strict schemas.
56. Security Misconfiguration
Common examples include:
Debug mode enabled
Default credentials
Exposed stack traces
Public .env files
Open database ports
Unnecessary services
Weak CORS configuration
Missing security headers
Production should not expose development information.
Bad:
{
"error": "MongoServerError...",
"stack": "..."
}
Better:
{
"message": "Internal server error"
}
Detailed information should remain in secure server-side logs.
57. Secrets
Never commit:
.env
private keys
API secrets
database passwords
JWT signing keys
to source control.
Use secret management mechanisms appropriate for the deployment environment.
Also remember:
Environment variables are configuration, not automatically a complete secret-management strategy.
58. Docker Security
Containers should follow least privilege.
Avoid running applications as root when unnecessary.
Use:
- Minimal base images
- Non-root users
- Read-only filesystems where practical
- Secret management
- Image scanning
- Pinned versions
- Network segmentation
59. Nginx Security
Nginx is commonly used as a reverse proxy.
Typical architecture:
Internet
↓
HTTPS
↓
Nginx
↓
Node.js
↓
Database
Nginx can provide:
- TLS termination
- Rate limiting
- Request size limits
- Security headers
- Reverse proxying
- Access logging
60. Dependency Security
Modern applications depend on hundreds or thousands of packages.
One vulnerable dependency can become an application vulnerability.
Useful practices include:
npm audit
and:
Dependabot
Dependency scanners
Lock files
Automated CI security checks
Use lock files such as:
package-lock.json
to make dependency resolution more predictable.
61. Supply-Chain Attacks
An attacker may compromise:
Developer
↓
Package
↓
Dependency
↓
Application
Possible attacks include:
- Malicious packages
- Compromised maintainers
- Dependency confusion
- Typosquatting
- Compromised build pipelines
Security must therefore include the software supply chain.
62. Logging and Monitoring
Logging is critical for detecting attacks and investigating incidents.
Useful events include:
Login success
Login failure
Password reset
Permission changes
Role changes
Admin actions
Suspicious requests
Rate-limit violations
Security configuration changes
63. What Should Never Be Logged?
Avoid logging:
Passwords
Access tokens
Refresh tokens
Session IDs
Private keys
Credit card information
Sensitive personal data
Logs themselves are sensitive infrastructure.
64. Audit Logs
An audit log answers:
Who?
What?
When?
Where?
What changed?
Was it successful?
Example:
{
"actorId": "123",
"action": "ROLE_CHANGED",
"targetUserId": "456",
"timestamp": "2026-08-10T10:00:00Z",
"ip": "..."
}
Audit logs are especially important for administrative operations.
65. Secure Coding Principles
Input Validation
Treat all external data as untrusted.
Sources include:
- HTTP requests
- Cookies
- Headers
- Query parameters
- Files
- Webhooks
- Message queues
Output Encoding
Encode output according to its context.
Fail Securely
When something goes wrong:
Default → Deny
not:
Default → Allow
Defense in Depth
Never rely on one security control.
For example:
Input Validation
+
Authorization
+
Database Restrictions
+
Rate Limiting
+
Monitoring
If one layer fails, another layer can reduce the damage.
66. OWASP API Security Top 10
API-specific security risks include areas such as:
- Broken Object Level Authorization
- Broken Authentication
- Broken Object Property Level Authorization
- Unrestricted Resource Consumption
- Broken Function Level Authorization
- Unrestricted Access to Sensitive Business Flows
- Server-Side Request Forgery
- Security Misconfiguration
- Improper Inventory Management
- Unsafe Consumption of APIs
API security requires understanding both technical vulnerabilities and business logic.
67. OWASP ASVS
OWASP ASVS stands for:
Application Security Verification Standard
It provides requirements that can be used to verify the security of an application.
Instead of asking:
"Did we follow OWASP?"
you can ask:
"Which security requirements does our application satisfy?"
ASVS can be used during:
Architecture
Development
Code Review
Testing
Security Audits
Release
68. OWASP Testing Guide
Security testing should follow a methodology.
A simplified workflow is:
Reconnaissance
↓
Enumeration
↓
Authentication Testing
↓
Authorization Testing
↓
Input Validation
↓
Session Testing
↓
Business Logic Testing
↓
Configuration Testing
↓
Reporting
The goal is not simply to find vulnerabilities.
The goal is to systematically evaluate the application's security.
69. Security Testing Tools
Common tools include:
Burp Suite
Used for:
- HTTP interception
- Request manipulation
- Replaying requests
- API testing
- Authentication testing
OWASP ZAP
An open-source web application security testing proxy.
Nmap
Used for network discovery and service enumeration.
Postman
Useful for API development and security testing.
npm audit
Useful for identifying known vulnerable npm dependencies.
Tools are only as effective as the methodology behind them.
70. Secure Node.js Application
A production Node.js application should consider:
Express Security
Helmet
CORS
Rate Limiting
Validation
Authentication
Authorization
JWT
Secure Cookies
CSRF
Database Security
Logging
Error Handling
Dependency Security
Example:
app.use(helmet());
app.use(express.json({ limit: '1mb' }));
Use validation libraries and explicitly define accepted input.
71. Secure Express Architecture
A useful architecture is:
Request
↓
Nginx
↓
Rate Limiting
↓
Express
↓
Security Middleware
↓
Authentication
↓
Authorization
↓
Validation
↓
Controller
↓
Service
↓
Repository
↓
Database
This separates security responsibilities.
72. Secure NestJS Application
NestJS provides several mechanisms useful for security.
Guards
Guards are useful for:
- Authentication
- Authorization
- Role checks
Example:
@UseGuards(AuthGuard)
@Get('/profile')
getProfile() {
return this.userService.profile();
}
Pipes
Pipes can validate and transform incoming data.
Example:
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
forbidNonWhitelisted: true,
transform: true
})
);
This is extremely useful for preventing unexpected fields from entering your application.
73. NestJS Authorization
You can implement:
Authentication Guard
↓
Roles Guard
↓
Controller
For example:
@Roles('admin')
@UseGuards(AuthGuard, RolesGuard)
@Delete(':id')
deleteUser() {}
But remember:
Authorization should be based on business rules, not only decorators.
Resource ownership must still be checked.
74. Production Security Architecture
A realistic deployment might look like:
Internet
│
▼
HTTPS/TLS
│
▼
Nginx
│
┌─────┴─────┐
│ │
Rate Limit Headers
│
▼
API Gateway
│
┌──────┼──────┐
│ │ │
Auth Users Orders
│ │ │
└──────┼──────┘
│
Redis
│
Database
Each layer provides different security controls.
75. Zero Trust Basics
Zero Trust follows a principle similar to:
Never trust automatically; verify explicitly.
For service-to-service communication:
Service A
↓
Authentication
↓
Authorization
↓
Service B
Do not assume that because traffic is inside a private network, it is automatically trusted.
76. Final Production Project
The best way to learn application security is to build a complete secure application.
A suitable final project is a:
Secure Authentication and Authorization Platform
Technology stack:
Frontend
Angular
Backend
Node.js + NestJS
Database
PostgreSQL or MongoDB
Cache
Redis
Reverse Proxy
Nginx
Deployment
Docker
Security
HTTPS
JWT
Refresh Tokens
RBAC
CSRF
CSP
Security Headers
Rate Limiting
Audit Logs
77. Authentication Flow
A possible architecture:
POST /auth/login
↓
Validate Input
↓
Find User
↓
Verify Password
↓
Create Access Token
↓
Create Refresh Token
↓
Store Refresh Token State
↓
Return Authentication Response
78. Refresh Token Flow
Client
↓
Access Token Expired
↓
POST /auth/refresh
↓
Validate Refresh Token
↓
Check Token State
↓
Rotate Refresh Token
↓
Generate New Access Token
↓
Return Tokens
If token reuse is detected, the application can invalidate the relevant token family/session.
79. RBAC Flow
Example:
Admin
├── users:read
├── users:create
├── users:update
└── users:delete
Manager
├── users:read
└── users:update
User
└── profile:read
Authorization should be enforced server-side.
80. Redis Security
Redis can be used for:
- Sessions
- Refresh-token state
- Rate limiting
- Temporary security data
- Token revocation
But Redis itself must be secured.
Do not expose Redis directly to the public Internet.
Use:
Authentication
Network Restrictions
TLS where appropriate
Least Privilege
Secure Configuration
81. Database Security in the Final Project
The application should use:
Application DB User
↓
Minimum Required Permissions
↓
Database
Sensitive data should be protected.
Queries should be parameterized or safely constructed.
Indexes should be designed carefully.
82. Rate Limiting Architecture
Different endpoints may require different limits.
For example:
Login
5 attempts / minute
Password Reset
3 requests / hour
Normal API
100 requests / minute
Admin API
Stricter limits
The exact values should depend on the application's behavior and threat model.
83. Security Headers
The production application should implement appropriate headers such as:
Content-Security-Policy
Strict-Transport-Security
X-Content-Type-Options
Referrer-Policy
Permissions-Policy
Frame protection should be configured through appropriate CSP directives such as:
frame-ancestors
84. HTTPS
Production applications should use HTTPS.
Architecture:
Client
↓
HTTPS
↓
Nginx
↓
Node.js
HTTPS protects data in transit from network interception and tampering.
85. Security Testing the Final Project
Test the application against:
Authentication
Authorization
IDOR/BOLA
Brute Force
Credential Stuffing
SQL Injection
NoSQL Injection
XSS
CSRF
SSRF
Path Traversal
File Upload
Mass Assignment
Rate Limiting
Security Headers
CORS
Session Management
Error Handling
Dependency Vulnerabilities
You can use:
Burp Suite
OWASP ZAP
Postman
Nmap
npm audit
Dependency scanners
86. Security Checklist
Before production, ask:
Authentication
- Are passwords hashed securely?
- Are authentication tokens protected?
- Are refresh tokens rotated?
- Are sessions invalidated correctly?
- Is brute-force protection implemented?
Authorization
- Is every sensitive resource authorized?
- Is ownership verified?
- Are roles and permissions enforced server-side?
- Is tenant isolation implemented?
Input
- Is every external input validated?
- Are request sizes limited?
- Are database queries safely constructed?
- Is mass assignment prevented?
XSS
- Is output encoded?
- Is unsafe HTML sanitized?
- Is CSP configured?
- Are sensitive cookies HttpOnly?
CSRF
- Are state-changing requests protected?
- Are cookies configured with appropriate SameSite settings?
- Is Origin validation considered?
API
- Is rate limiting implemented?
- Is excessive data exposure prevented?
- Are pagination limits enforced?
- Are sensitive business operations protected?
Infrastructure
- Is HTTPS enabled?
- Is Nginx configured securely?
- Are secrets protected?
- Are containers running with minimal privileges?
- Are databases private?
Monitoring
- Are security events logged?
- Are sensitive values excluded from logs?
- Are suspicious activities detected?
- Are alerts configured?
87. The Developer Security Mental Model
A secure developer should think about an application in layers:
USER
│
▼
BROWSER
│
▼
HTTPS
│
▼
REVERSE PROXY
│
▼
API
│
┌────────┴────────┐
▼ ▼
AUTHENTICATION AUTHORIZATION
│ │
└────────┬────────┘
▼
INPUT VALIDATION
│
▼
BUSINESS LOGIC
│
┌────────┴────────┐
▼ ▼
DATABASE CACHE
│ │
└────────┬────────┘
▼
LOGGING
│
▼
MONITORING
Security is not a single feature.
It is a property of the entire system.
88. Final Takeaway
Learning OWASP should not mean memorizing a list of vulnerabilities.
The real goal is to develop a security mindset.
When building an application, continuously ask:
Who can access this?
What happens if the input is malicious?
What if the user modifies the request?
What if the token is stolen?
What if the database is compromised?
What if this endpoint is called 100,000 times?
What if this service receives an unexpected file?
What if an internal service is attacked through SSRF?
What information can leak through errors?
What happens when something fails?
Can we detect the attack?
The most important principles are:
Validate Input
+
Encode Output
+
Authenticate Correctly
+
Authorize Every Sensitive Operation
+
Use Least Privilege
+
Protect Secrets
+
Use Secure Cryptography
+
Limit Resources
+
Log Security Events
+
Monitor the System
+
Test Continuously
The strongest security architecture is not one that assumes attackers will never get through.
It is one that assumes something will eventually fail and is designed to limit the damage.
That is the core mindset behind secure software development.
Recommended Learning Path
If you want to turn this material into a practical developer security course, follow this sequence:
1. OWASP Fundamentals
↓
2. HTTP & Browser Security
↓
3. Authentication
↓
4. Authorization
↓
5. Injection
↓
6. XSS
↓
7. CSRF
↓
8. API Security
↓
9. Cryptography
↓
10. Database Security
↓
11. File Upload & Path Traversal
↓
12. SSRF
↓
13. Security Misconfiguration
↓
14. Dependency Security
↓
15. Logging & Monitoring
↓
16. Secure Coding
↓
17. OWASP API Security
↓
18. OWASP ASVS
↓
19. OWASP Testing Guide
↓
20. Burp Suite / ZAP
↓
21. Secure Node.js
↓
22. Secure NestJS
↓
23. Docker + Nginx + HTTPS
↓
24. Secure Architecture
↓
25. Final Production Project
By completing this path, you move from simply knowing what vulnerabilities are to understanding how to design, implement, test, and deploy secure production applications.
Top comments (0)