
Code Security Review
- 23 installs
- 14 repo stars
- Updated January 23, 2026
- dauquangthanh/hanoi-rainbow
Code Security Review is an agent skill that audits source and configuration for vulnerabilities and control gaps so teams can remediate risks with CWE- and OWASP-aligned guidance.
About
Code Security Review is a Hanoi Rainbow skill for deep application security audits spanning authentication, injection, cryptography, APIs, dependencies, and misconfigurations. Engage it before major releases, after threat-model updates, or when compliance requires documented control validation. It produces assessment-style reports, not automated DAST replacement or infrastructure pentesting of networks.
- Threat modeling and attack-surface mapping
- Auth, input validation, and secrets checks
- CVE and dependency vulnerability lens
- Compliance hooks for PCI-DSS, GDPR, HIPAA
Code Security Review by the numbers
- 23 all-time installs (skills.sh)
- Ranked #1,559 of 2,203 Security skills by installs in the Skillselion catalog
- Data as of Jul 29, 2026 (Skillselion catalog sync)
npx skills add https://github.com/dauquangthanh/hanoi-rainbow --skill code-security-reviewAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 23 |
|---|---|
| repo stars | ★ 14 |
| Last updated | January 23, 2026 |
| Repository | dauquangthanh/hanoi-rainbow ↗ |
How do you know whether your application code meets secure-coding expectations and compliance obligations before release?
Performs OWASP- and CWE-oriented security code review with severity, CVSS context, and remediation guidance.
Who is it for?
Developers or security champions reviewing web apps, APIs, or services with sensitive data or regulatory requirements.
Skip if: Organizations seeking only performance tuning or pure infrastructure/network penetration tests without code review.
When should I use this skill?
You need a security audit, vulnerability assessment, or OWASP-oriented review of application code and dependencies.
What you get
A security report with classified findings, severity, CWE/OWASP mapping, exploit notes, and remediation steps is delivered.
Files
Code Security Review
Overview
Performs comprehensive security code reviews to identify vulnerabilities, assess security risks, and provide actionable remediation guidance. Covers OWASP Top 10, CWE classifications, compliance requirements, and security best practices.
Security Review Workflow
1. Initial Assessment
Gather context about the application:
- Application type: Web app, API, mobile, desktop, embedded
- Data sensitivity: PII, financial data, healthcare records, proprietary information
- Compliance requirements: PCI-DSS, GDPR, HIPAA, SOC 2, ISO 27001
- Authentication mechanisms: OAuth, JWT, session-based, API keys
- Technology stack: Languages, frameworks, libraries, databases
- External integrations: Third-party APIs, cloud services, payment processors
Perform threat modeling:
- Identify critical assets (data, functions, resources)
- Map attack surfaces (user inputs, APIs, file uploads, network interfaces)
- Determine threat actors (external attackers, malicious insiders, automated bots)
- Assess existing security controls
2. Code Analysis
Systematically review code for security vulnerabilities:
Priority Areas:
1. Authentication & Authorization - Login flows, session management, access controls 2. Input Validation - All user inputs, API parameters, file uploads 3. Data Protection - Encryption at rest and in transit, sensitive data handling 4. API Security - Rate limiting, authentication, input validation 5. Dependency Security - Third-party libraries, outdated packages, known CVEs 6. Configuration - Security headers, CORS, environment variables, secrets management 7. Error Handling - Information disclosure, stack traces, error messages 8. Business Logic - Race conditions, workflow bypasses, state manipulation
3. Vulnerability Classification
Classify each finding:
- Severity: Critical, High, Medium, Low, Informational
- CWE ID: Common Weakness Enumeration identifier
- OWASP Category: Map to OWASP Top 10 if applicable
- CVSS Score: Calculate if applicable (use CVSS 3.1)
- Exploitability: How easy to exploit
- Impact: Data loss, privilege escalation, DoS, data breach
4. Documentation
Produce comprehensive security report:
- Executive Summary - High-level findings and risk overview
- Detailed Findings - Each vulnerability with code examples and exploit scenarios
- Remediation Guidance - Specific fixes with secure code examples
- Compliance Assessment - Status against required standards
- Remediation Timeline - Prioritized action plan
- Security Metrics - Vulnerability counts by severity and category
Severity Classification
Critical (CVSS 9.0-10.0):
- Remote code execution
- Authentication bypass
- SQL injection with data access
- Hardcoded credentials for production systems
- Complete access control bypass
High (CVSS 7.0-8.9):
- Privilege escalation
- Sensitive data exposure (PII, financial)
- Cross-site scripting (XSS) with session theft
- Insecure deserialization
- XML external entity (XXE) injection
Medium (CVSS 4.0-6.9):
- Information disclosure
- Cross-site request forgery (CSRF)
- Weak cryptography
- Security misconfiguration
- Missing security headers
Low (CVSS 0.1-3.9):
- Version disclosure
- Verbose error messages
- Missing best practices
- Security through obscurity
Informational:
- Recommendations for defense in depth
- Future-proofing suggestions
- Security hygiene improvements
Report Structure
Generate security reports in this format:
Executive Summary
- Total vulnerabilities by severity
- Critical risk areas
- Compliance status summary
- Overall security posture rating
- Recommended immediate actions
Detailed Findings
For each vulnerability:
## [SEVERITY] Finding Title (CWE-XXX)
**Severity**: Critical/High/Medium/Low
**CWE ID**: CWE-XXX
**OWASP**: A0X:YYYY
**CVSS Score**: X.X (if applicable)
**Description**:
[Clear explanation of the vulnerability]
**Location**:
- File: path/to/file.ext
- Lines: XX-XX
- Function/Class: function_name()
**Vulnerable Code**:[Actual vulnerable code snippet]
**Exploit Scenario**:
[Step-by-step demonstration of how an attacker could exploit this]
**Impact**:
[What could happen if exploited - data breach, privilege escalation, etc.]
**Remediation**:
[Specific steps to fix the vulnerability]
**Secure Code Example**:
[Working secure implementation]
**References**:
- [Relevant CWE, CVE, or documentation links]
Remediation Timeline
- Phase 1 (Critical - Week 1): List of critical issues
- Phase 2 (High - Weeks 2-3): List of high severity issues
- Phase 3 (Medium - Month 2): List of medium severity issues
- Phase 4 (Low - Month 3): List of low severity issues
Compliance Assessment
For each applicable standard, document:
- Requirements checked
- Compliance status (Compliant/Non-Compliant/Partially Compliant)
- Specific gaps identified
- Remediation needed for compliance
Detailed References
For comprehensive vulnerability patterns, testing procedures, and compliance details:
- OWASP Top 10 & CWE Patterns: See security-review-workflow.md for:
- Detailed vulnerability patterns for each OWASP Top 10 category
- Code examples of vulnerable and secure implementations
- Testing procedures and detection methods
- Complete CWE mappings and classifications
- Security Testing Procedures: See security-testing-checklist.md for:
- Comprehensive testing checklist by category
- Manual and automated testing techniques
- Security testing tools and configurations
- API security testing procedures
- Compliance Requirements: See compliance-requirements.md for:
- PCI-DSS requirements and validation
- GDPR data protection requirements
- HIPAA security and privacy rules
- SOC 2 security controls
- Report Examples: See report-example.md for:
- Complete security report template
- Example findings with remediation guidance
- Executive summary examples
- Remediation timeline structures
Best Practices
Be Thorough:
- Review ALL user input points
- Check ALL database queries
- Verify ALL authentication and authorization checks
- Test ALL file operations and uploads
- Examine ALL external integrations
Be Practical:
- Prioritize by risk (likelihood × impact)
- Consider exploitability and business context
- Account for compensating controls
- Balance security with usability
Be Clear:
- Provide step-by-step exploit scenarios
- Show exact vulnerable code locations
- Give specific, actionable remediation steps
- Include working secure code examples
Be Professional:
- Focus on code issues, not developers
- Use industry-standard classifications (CWE, OWASP, CVSS)
- Provide credible references (NIST, OWASP, vendor documentation)
- Document assumptions and testing limitations
Compliance Requirements
Overview
This document provides guidance on assessing code security compliance with common regulatory and industry standards. Use this when evaluating code against specific compliance frameworks.
Table of Contents
- PCI-DSS (Payment Card Industry Data Security Standard)
- GDPR (General Data Protection Regulation)
- HIPAA (Health Insurance Portability and Accountability Act)
- SOC 2
- Compliance Assessment Process
---
PCI-DSS
Requirement 3: Protect Stored Cardholder Data
3.4: Render PAN unreadable anywhere it is stored
What to Check:
- Primary Account Number (PAN) encryption at rest
- Strong cryptography (AES-256, RSA 2048+)
- Key management practices
- Avoid storing sensitive authentication data (CVV, PIN)
Code Review Points:
# ❌ BAD: Weak encryption
import hashlib
card_hash = hashlib.md5(card_number.encode()).hexdigest() # MD5 is not encryption
# ❌ BAD: Plain text storage
db.execute("INSERT INTO payments (card_number) VALUES (?)", (card_number,))
# ✅ GOOD: Strong encryption with proper key management
from cryptography.fernet import Fernet
cipher = Fernet(get_encryption_key_from_secure_vault())
encrypted_pan = cipher.encrypt(card_number.encode())
db.execute("INSERT INTO payments (encrypted_pan) VALUES (?)", (encrypted_pan,))Compliance Validation:
- [ ] PAN is encrypted using strong cryptography (AES-256 minimum)
- [ ] Encryption keys stored separately from encrypted data
- [ ] Key rotation policy implemented
- [ ] CVV/CVV2/PIN never stored
- [ ] Disk-level encryption enabled
---
Requirement 6: Develop and Maintain Secure Systems
6.5: Address common coding vulnerabilities in software-development processes
Required Coverage:
- 6.5.1: Injection flaws (SQL, OS, LDAP)
- 6.5.2: Buffer overflows
- 6.5.3: Insecure cryptographic storage
- 6.5.4: Insecure communications
- 6.5.5: Improper error handling
- 6.5.6: All "high risk" vulnerabilities identified in vulnerability identification process
- 6.5.7: Cross-site scripting (XSS)
- 6.5.8: Improper access control
- 6.5.9: Cross-site request forgery (CSRF)
- 6.5.10: Broken authentication and session management
Compliance Validation:
- [ ] All inputs validated and sanitized
- [ ] Parameterized queries used (no dynamic SQL)
- [ ] TLS 1.2+ for all cardholder data transmission
- [ ] Secure session management
- [ ] CSRF protection implemented
- [ ] XSS prevention (output encoding, CSP)
---
Requirement 8: Identify and Authenticate Access
8.1: Define and implement policies to ensure proper user identification management
What to Check:
- Unique user IDs for all users
- Multi-factor authentication for remote access
- Password complexity requirements
- Account lockout after failed attempts
Code Review Points:
// ❌ BAD: Weak password requirements
if (password.length >= 6) { /* accept */ }
// ❌ BAD: No account lockout
if (bcrypt.compare(password, user.password_hash)) { /* login */ }
// ✅ GOOD: Strong password policy and lockout
const PASSWORD_MIN_LENGTH = 12;
const MAX_LOGIN_ATTEMPTS = 3;
const LOCKOUT_DURATION = 30 * 60 * 1000; // 30 minutes
if (user.failed_attempts >= MAX_LOGIN_ATTEMPTS) {
if (Date.now() - user.last_failed_attempt < LOCKOUT_DURATION) {
throw new Error('Account temporarily locked');
}
user.failed_attempts = 0;
}
if (!validatePasswordComplexity(password)) {
throw new Error('Password must be 12+ chars with upper, lower, number, special char');
}8.2: Ensure proper user-authentication management
Compliance Validation:
- [ ] Passwords at least 12 characters or 8 with complexity
- [ ] MFA required for administrative access
- [ ] MFA required for all remote network access
- [ ] Sessions timeout after 15 minutes of inactivity
- [ ] Failed login attempts limited (max 6 attempts)
- [ ] Account locked for at least 30 minutes after max attempts
- [ ] Password history maintained (prevent reuse of last 4 passwords)
---
Requirement 10: Track and Monitor Network Resources
10.1: Implement audit trails to link all access to system components
What to Check:
- User identification logged
- Event type logged
- Date and time logged
- Success or failure indication
- Origination of event
- Identity or name of affected data/system/resource
Code Review Points:
# ❌ BAD: No audit logging
def update_payment(payment_id, amount):
db.execute("UPDATE payments SET amount = ? WHERE id = ?", (amount, payment_id))
# ✅ GOOD: Comprehensive audit logging
def update_payment(payment_id, amount, user_id, ip_address):
db.execute("UPDATE payments SET amount = ? WHERE id = ?", (amount, payment_id))
audit_log.record({
'event_type': 'PAYMENT_UPDATE',
'user_id': user_id,
'payment_id': payment_id,
'old_amount': old_amount,
'new_amount': amount,
'timestamp': datetime.utcnow(),
'ip_address': ip_address,
'success': True
})Compliance Validation:
- [ ] All individual user access logged
- [ ] All actions by privileged users logged
- [ ] Access to audit trails logged
- [ ] Invalid logical access attempts logged
- [ ] All authentication mechanisms logged
- [ ] Initialization of audit logs logged
- [ ] Creation and deletion of system objects logged
---
PCI-DSS Compliance Assessment Template
## PCI-DSS Compliance Status
| Requirement | Status | Findings | Remediation |
| ------------- | -------- |----------|-------------|
| 3.4: Encrypt PAN | ⚠️ Partial | Weak encryption (MD5) | Implement AES-256 |
| 6.5: Secure coding | ❌ Non-Compliant | SQL injection found | Use parameterized queries |
| 8.1: User identification | ✅ Compliant | Proper implementation | - |
| 8.2: Authentication | ⚠️ Partial | No MFA for admins | Implement MFA |
| 10.1: Audit trails | ❌ Non-Compliant | Incomplete logging | Add comprehensive logging |
**Overall Status:** ❌ Non-Compliant
**Critical Issues:** 2
**Estimated Remediation Time:** 4-6 weeks---
GDPR
Data Protection Principles (Article 5)
What to Check:
- Lawfulness, fairness, transparency
- Purpose limitation
- Data minimization
- Accuracy
- Storage limitation
- Integrity and confidentiality
- Accountability
Technical and Organizational Measures (Article 32)
Required Security Measures:
- Pseudonymization and encryption of personal data
- Ongoing confidentiality, integrity, availability
- Ability to restore data after incident
- Regular testing and evaluation
Code Review Points:
# ❌ BAD: Excessive data collection
user_data = {
'email': email,
'password': password,
'ip_address': request.ip,
'user_agent': request.user_agent,
'location': geolocate(request.ip),
'device_fingerprint': generate_fingerprint(),
# Too much data without clear purpose
}
# ✅ GOOD: Data minimization
user_data = {
'email': email,
'password_hash': bcrypt.hash(password),
# Only collect what's necessary for the stated purpose
}Compliance Validation:
- [ ] Personal data encrypted at rest and in transit
- [ ] Data retention policies implemented
- [ ] Right to erasure (deletion) implemented
- [ ] Data portability features available
- [ ] Consent management system in place
- [ ] Data breach notification procedures
- [ ] Privacy by design principles followed
- [ ] Data minimization applied
- [ ] Purpose limitation documented
---
Right to Erasure (Article 17)
Code Review Points:
# ✅ GOOD: Complete data deletion
def delete_user_data(user_id):
# Delete from all systems
db.execute("DELETE FROM users WHERE id = ?", (user_id,))
db.execute("DELETE FROM user_profiles WHERE user_id = ?", (user_id,))
db.execute("DELETE FROM user_preferences WHERE user_id = ?", (user_id,))
# Anonymize audit logs (retain for legal compliance)
db.execute(
"UPDATE audit_logs SET user_id = 'DELETED_USER' WHERE user_id = ?",
(user_id,)
)
# Remove from backup systems (schedule for next backup cycle)
queue_backup_deletion(user_id)
# Log the deletion (required for accountability)
compliance_log.record({
'action': 'USER_DATA_DELETION',
'user_id': user_id,
'timestamp': datetime.utcnow(),
'request_source': 'USER_REQUEST'
})Compliance Validation:
- [ ] User can request data deletion
- [ ] All personal data deleted within 30 days
- [ ] Data deleted from backups
- [ ] Anonymization applied where deletion not possible
- [ ] Deletion confirmation provided to user
---
GDPR Compliance Assessment Template
## GDPR Compliance Status
| Requirement | Status | Findings |
| ------------- | -------- |----------|
| Lawful basis for processing | ✅ | Consent mechanism implemented |
| Data minimization | ⚠️ | Excessive logging of IP addresses |
| Encryption | ✅ | TLS 1.3, AES-256 at rest |
| Right to erasure | ❌ | No deletion mechanism |
| Data portability | ⚠️ | Export available, format not machine-readable |
| Breach notification | ✅ | Process documented and tested |
**Overall Status:** ⚠️ Partially Compliant
**Critical Gaps:** Right to erasure---
HIPAA
Security Rule - Technical Safeguards (45 CFR § 164.312)
Access Control (§ 164.312(a)(1))
Required Implementation:
- Unique user identification (Required)
- Emergency access procedures (Required)
- Automatic logoff (Addressable)
- Encryption and decryption (Addressable)
Code Review Points:
// ❌ BAD: Shared credentials
String DB_USER = "app_user";
String DB_PASS = "shared_password";
// ✅ GOOD: Individual user accounts
public class DataAccess {
private String userId;
private AuditLogger auditLogger;
public void accessPatientRecord(String patientId) {
// Check user authorization
if (!authService.canAccessPatient(userId, patientId)) {
auditLogger.logUnauthorizedAccess(userId, patientId);
throw new UnauthorizedException();
}
// Log access
auditLogger.logAccess(userId, patientId, "READ");
// Retrieve data
return patientRepository.findById(patientId);
}
}Compliance Validation:
- [ ] Unique user ID for all users
- [ ] Emergency access procedures documented
- [ ] Session timeout implemented (15 minutes)
- [ ] PHI encrypted at rest (AES-256)
- [ ] PHI encrypted in transit (TLS 1.2+)
---
Audit Controls (§ 164.312(b))
Required: Hardware, software, and procedural mechanisms to record and examine access to ePHI
Code Review Points:
# ✅ GOOD: Comprehensive HIPAA audit logging
class HIPAAAuditLogger:
def log_access(self, user_id, patient_id, action, phi_fields):
"""Log access to Protected Health Information"""
self.write_audit_entry({
'timestamp': datetime.utcnow().isoformat(),
'user_id': user_id,
'patient_id': patient_id,
'action': action, # CREATE, READ, UPDATE, DELETE
'phi_fields_accessed': phi_fields,
'ip_address': request.remote_addr,
'success': True
})
def log_failed_access(self, user_id, patient_id, reason):
"""Log unauthorized access attempts"""
self.write_audit_entry({
'timestamp': datetime.utcnow().isoformat(),
'user_id': user_id,
'patient_id': patient_id,
'action': 'UNAUTHORIZED_ACCESS',
'reason': reason,
'ip_address': request.remote_addr,
'success': False
})Compliance Validation:
- [ ] All PHI access logged
- [ ] All modifications to PHI logged
- [ ] All deletions of PHI logged
- [ ] All disclosure of PHI logged
- [ ] Failed access attempts logged
- [ ] Audit logs retained for 6 years
- [ ] Audit logs protected from modification
---
Integrity (§ 164.312(c)(1))
Required: Mechanisms to ensure ePHI is not improperly altered or destroyed
Code Review Points:
# ✅ GOOD: Data integrity controls
def update_patient_record(patient_id, updates, user_id):
# Verify data integrity before update
current_record = get_patient_record(patient_id)
if current_record.checksum != calculate_checksum(current_record):
raise IntegrityError("Record has been tampered with")
# Create audit trail before modification
create_version_snapshot(current_record)
# Apply updates
new_record = apply_updates(current_record, updates)
new_record.checksum = calculate_checksum(new_record)
new_record.last_modified_by = user_id
new_record.last_modified_at = datetime.utcnow()
# Save with integrity verification
save_with_transaction(new_record)
# Log modification
audit_log.record_modification(patient_id, user_id, updates)Compliance Validation:
- [ ] Mechanisms to detect unauthorized alterations
- [ ] Data integrity verification implemented
- [ ] Version control for PHI records
- [ ] Backup and recovery procedures tested
---
HIPAA Compliance Assessment Template
## HIPAA Security Rule Compliance
| Requirement | Standard | Status | Findings |
| ------------- | ---------- |--------|----------|
| Access Control | § 164.312(a) | ⚠️ | No automatic logoff |
| Audit Controls | § 164.312(b) | ✅ | Comprehensive logging |
| Integrity | § 164.312(c) | ⚠️ | No data integrity checksums |
| Transmission Security | § 164.312(e) | ✅ | TLS 1.3 enforced |
**Overall Status:** ⚠️ Partially Compliant
**Required Actions:** Implement automatic logoff, add integrity controls---
SOC 2
Trust Services Criteria
CC6.1: Logical and Physical Access Controls
What to Check:
- User authentication (CC6.1)
- Authorization mechanisms (CC6.1)
- Access provisioning and termination (CC6.2)
- Credential lifecycle management (CC6.2)
Compliance Validation:
- [ ] Multi-factor authentication implemented
- [ ] Role-based access control (RBAC)
- [ ] Least privilege principle enforced
- [ ] Access reviews performed quarterly
- [ ] Terminated user access revoked within 24 hours
---
CC6.6: Encryption
Code Review Points:
// ❌ BAD: No encryption in transit
app.get('/api/customer-data', (req, res) => {
res.json(customerData); // Sent over HTTP
});
// ✅ GOOD: Encryption in transit
const https = require('https');
const app = express();
// Force HTTPS
app.use((req, res, next) => {
if (!req.secure) {
return res.redirect('https://' + req.get('host') + req.url);
}
next();
});
// Set security headers
app.use((req, res, next) => {
res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
next();
});Compliance Validation:
- [ ] TLS 1.2+ for data in transit
- [ ] AES-256 for data at rest
- [ ] Key management procedures documented
- [ ] Certificate lifecycle management
---
CC7.2: System Monitoring
Compliance Validation:
- [ ] Security monitoring implemented
- [ ] Alerting for suspicious activity
- [ ] Log aggregation and analysis
- [ ] Incident response procedures
- [ ] Regular security testing
---
SOC 2 Compliance Assessment Template
## SOC 2 Type II Compliance
| Control | Status | Evidence | Gaps |
| --------- | -------- |----------|------|
| CC6.1: Access Controls | ✅ | MFA implemented, RBAC in place | None |
| CC6.2: Access Provisioning | ⚠️ | Manual process | Automate deprovisioning |
| CC6.6: Encryption | ✅ | TLS 1.3, AES-256 | None |
| CC7.2: Monitoring | ⚠️ | Basic logging | Enhance alerting |
**Overall Readiness:** 75%
**Audit-Ready Timeline:** 2-3 months---
Compliance Assessment Process
1. Identify Applicable Standards
Determine which compliance frameworks apply based on:
- Industry sector (healthcare, finance, retail)
- Geographic location (EU, US, other)
- Data types processed (PII, PHI, payment cards)
- Business relationships (customers, partners)
2. Map Requirements to Code
For each applicable standard:
- List specific technical requirements
- Identify relevant code sections
- Document security controls
- Note any gaps or deficiencies
3. Perform Gap Analysis
Compare current implementation against requirements:
- Compliant: Meets all requirements
- Partially Compliant: Meets some requirements
- Non-Compliant: Does not meet requirements
- Not Applicable: Requirement doesn't apply
4. Prioritize Remediation
Order by:
1. Regulatory risk (fines, legal action) 2. Security risk (likelihood × impact) 3. Effort required (quick wins first) 4. Business impact (customer trust, contracts)
5. Document Findings
Include in security report:
- Compliance status summary
- Specific requirement violations
- Risk assessment for each gap
- Detailed remediation steps
- Estimated timeline and effort
- Responsible parties
---
Multi-Standard Compliance Matrix
Use this to track compliance across multiple standards:
| Security Control | PCI-DSS | GDPR | HIPAA | SOC 2 |
|---|---|---|---|---|
| Encryption at rest | 3.4 | Art 32 | §312(a) | CC6.6 |
| Encryption in transit | 4.1 | Art 32 | §312(e) | CC6.6 |
| Access control | 7.1 | Art 25 | §312(a) | CC6.1 |
| Audit logging | 10.1 | Art 30 | §312(b) | CC7.2 |
| MFA | 8.3 | - | §312(a) | CC6.1 |
| Data retention | 3.1 | Art 5 | §310 | - |
| Incident response | 12.10 | Art 33 | §308 | CC7.3 |
This allows efficient review of controls that satisfy multiple requirements simultaneously.
Security Report Example
This document provides a complete example of a security review report. Use this as a template when generating security reports.
---
Security Review Report
Application: E-Commerce Web Application Review Date: January 14, 2026 Reviewer: Security Team Scope: 152 files, 23,450 lines of code Technology Stack: Node.js, Express, PostgreSQL, React
---
Executive Summary
Security Rating: 🔴 HIGH RISK
Vulnerability Summary:
- Critical: 2
- High: 5
- Medium: 11
- Low: 7
- Informational: 4
Overall Assessment:
The application contains multiple critical security vulnerabilities that pose significant risk to user data and business operations. Most critical issues involve SQL injection, broken authentication, and insecure cryptographic storage. The application should NOT be deployed to production until all critical and high-severity vulnerabilities are remediated.
Key Findings:
1. SQL injection vulnerability in user search functionality (CRITICAL) 2. Authentication bypass through JWT manipulation (CRITICAL) 3. Sensitive data (credit cards) stored in plain text (HIGH) 4. Missing rate limiting on API endpoints (HIGH) 5. Cross-site scripting (XSS) in product reviews (HIGH)
Compliance Status:
- PCI-DSS: ❌ Non-Compliant (3 critical requirements failed)
- GDPR: ⚠️ Partially Compliant (right to erasure not implemented)
- OWASP Top 10: ❌ Multiple vulnerabilities present
Immediate Actions Required:
1. Fix SQL injection in user search (Week 1) 2. Implement proper JWT validation (Week 1) 3. Encrypt sensitive data at rest (Week 1-2) 4. Add rate limiting (Week 2) 5. Sanitize user-generated content (Week 2)
Estimated Remediation Time: 4-6 weeks
---
Detailed Findings
Critical Vulnerabilities
---
CRITICAL-1: SQL Injection in User Search
Severity: Critical CWE ID: CWE-89 (SQL Injection) OWASP: A03:2021 - Injection CVSS Score: 9.8 (Critical)
Description:
The user search functionality constructs SQL queries using unvalidated user input, allowing attackers to inject arbitrary SQL commands. This can lead to unauthorized data access, data modification, or complete database compromise.
Location:
- File:
src/controllers/userController.js - Lines: 45-52
- Function:
searchUsers()
Vulnerable Code:
async function searchUsers(req, res) {
const searchTerm = req.query.q;
// Vulnerable: Direct string concatenation
const query = `SELECT * FROM users WHERE username LIKE '%${searchTerm}%' OR email LIKE '%${searchTerm}%'`;
const results = await db.query(query);
res.json(results);
}Exploit Scenario:
An attacker can craft a malicious search query to extract sensitive data:
Step 1: Send request to /api/users/search?q=test
Step 2: Modify to: /api/users/search?q=test' UNION SELECT id, username, password_hash, email, credit_card FROM users--
Step 3: Response contains all user data including hashed passwords and credit cards
Step 4: Attacker downloads entire user databaseProof of Concept:
curl "https://api.example.com/api/users/search?q=test'%20UNION%20SELECT%20id,%20username,%20password_hash,%20email,%20credit_card%20FROM%20users--"Impact:
- Confidentiality: Complete database compromise
- Integrity: Attacker can modify or delete database records
- Availability: Attacker can drop tables or cause denial of service
- Compliance: PCI-DSS 6.5.1 violation
Remediation:
Use parameterized queries to prevent SQL injection:
async function searchUsers(req, res) {
const searchTerm = req.query.q;
// Input validation
if (!searchTerm || searchTerm.length < 2) {
return res.status(400).json({ error: 'Search term too short' });
}
if (searchTerm.length > 100) {
return res.status(400).json({ error: 'Search term too long' });
}
// Secure: Parameterized query
const query = `
SELECT id, username, email, created_at
FROM users
WHERE username ILIKE $1 OR email ILIKE $1
LIMIT 50
`;
const searchPattern = `%${searchTerm}%`;
const results = await db.query(query, [searchPattern]);
// Log search for audit
auditLog.record({
action: 'USER_SEARCH',
user_id: req.user.id,
search_term: searchTerm,
results_count: results.length
});
res.json(results);
}Additional Recommendations:
- Implement input validation and sanitization
- Use ORM (Sequelize, TypeORM) with built-in protections
- Apply least privilege to database user
- Enable database query logging and monitoring
- Implement Web Application Firewall (WAF) rules
References:
- CWE-89: <https://cwe.mitre.org/data/definitions/89.html>
- OWASP SQL Injection: <https://owasp.org/www-community/attacks/SQL_Injection>
- Node.js Parameterized Queries: <https://node-postgres.com/features/queries>
Priority: P0 - Fix immediately before any production deployment
---
CRITICAL-2: Authentication Bypass via JWT Manipulation
Severity: Critical CWE ID: CWE-347 (Improper Verification of Cryptographic Signature) OWASP: A07:2021 - Identification and Authentication Failures CVSS Score: 9.1 (Critical)
Description:
The JWT verification middleware accepts tokens with the "none" algorithm, allowing attackers to forge tokens and authenticate as any user without knowing the secret key.
Location:
- File:
src/middleware/auth.js - Lines: 12-23
- Function:
verifyToken()
Vulnerable Code:
const jwt = require('jsonwebtoken');
function verifyToken(req, res, next) {
const token = req.headers.authorization?.split(' ')[1];
if (!token) {
return res.status(401).json({ error: 'No token provided' });
}
// Vulnerable: Accepts 'none' algorithm
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
}Exploit Scenario:
Step 1: Capture a valid JWT token from network traffic
Step 2: Decode the JWT payload (it's base64-encoded)
Step 3: Modify the payload: change "user_id": 123 to "user_id": 1 (admin)
Step 4: Change algorithm in header to "none"
Step 5: Create new token without signature
Step 6: Send request with forged token
Step 7: Successfully authenticated as admin userProof of Concept:
// Forged token with admin privileges
const header = {
"alg": "none",
"typ": "JWT"
};
const payload = {
"user_id": 1,
"username": "admin",
"role": "admin",
"exp": 9999999999
};
const forgedToken =
base64url(JSON.stringify(header)) + '.' +
base64url(JSON.stringify(payload)) + '.';
// Use this token to access admin endpoints
fetch('/api/admin/users', {
headers: { 'Authorization': `Bearer ${forgedToken}` }
});Impact:
- Complete authentication bypass
- Privilege escalation to administrator
- Access to all user accounts
- Ability to modify or delete any data
- PCI-DSS 8.2 violation
Remediation:
const jwt = require('jsonwebtoken');
function verifyToken(req, res, next) {
const token = req.headers.authorization?.split(' ')[1];
if (!token) {
return res.status(401).json({ error: 'No token provided' });
}
try {
// Secure: Explicitly specify allowed algorithms
const decoded = jwt.verify(token, process.env.JWT_SECRET, {
algorithms: ['HS256'], // Only allow HMAC SHA-256
issuer: 'your-app-name',
audience: 'your-app-users'
});
// Additional validation
if (!decoded.user_id || !decoded.role) {
return res.status(401).json({ error: 'Invalid token payload' });
}
// Check token blacklist (for revoked tokens)
if (await tokenBlacklist.isBlacklisted(token)) {
return res.status(401).json({ error: 'Token has been revoked' });
}
req.user = decoded;
next();
} catch (error) {
if (error.name === 'TokenExpiredError') {
return res.status(401).json({ error: 'Token expired' });
}
if (error.name === 'JsonWebTokenError') {
return res.status(401).json({ error: 'Invalid token' });
}
return res.status(500).json({ error: 'Authentication error' });
}
}Additional Recommendations:
- Implement token refresh mechanism
- Add token blacklist/revocation
- Use short token expiration times (15 minutes)
- Implement rate limiting on authentication endpoints
- Add MFA for sensitive operations
- Monitor for suspicious token usage patterns
References:
- CWE-347: <https://cwe.mitre.org/data/definitions/347.html>
- JWT Best Practices: <https://datatracker.ietf.org/doc/html/rfc8725>
- OWASP JWT Cheat Sheet: <https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html>
Priority: P0 - Fix immediately before any production deployment
---
High Severity Vulnerabilities
---
HIGH-1: Sensitive Data Stored in Plain Text
Severity: High CWE ID: CWE-311 (Missing Encryption of Sensitive Data) OWASP: A02:2021 - Cryptographic Failures CVSS Score: 7.5 (High)
Description:
Credit card numbers and CVV codes are stored in the database without encryption. If the database is compromised, all payment information is immediately accessible to attackers.
Location:
- File:
src/models/payment.js - Lines: 34-42
- Table:
payments
Vulnerable Code:
const Payment = sequelize.define('Payment', {
user_id: DataTypes.INTEGER,
card_number: DataTypes.STRING(16), // Plain text!
cvv: DataTypes.STRING(3), // Should NEVER be stored!
expiry_date: DataTypes.STRING(5),
amount: DataTypes.DECIMAL(10, 2)
});Impact:
- PCI-DSS 3.4 critical violation
- Immediate fines if discovered during audit
- Complete exposure of payment data if database compromised
- Reputational damage and loss of customer trust
- Legal liability for data breach
Remediation:
const crypto = require('crypto');
const { Fernet } = require('cryptography');
// Load encryption key from secure vault (not environment variables!)
const encryptionKey = await keyVault.getSecret('payment-encryption-key');
const cipher = new Fernet(encryptionKey);
const Payment = sequelize.define('Payment', {
user_id: DataTypes.INTEGER,
// Only store last 4 digits for display
card_last_four: DataTypes.STRING(4),
// Store full PAN encrypted (if absolutely necessary)
encrypted_pan: DataTypes.TEXT,
// NEVER store CVV - use tokenization instead
payment_token: DataTypes.STRING, // Token from payment processor
expiry_date: DataTypes.STRING(5),
amount: DataTypes.DECIMAL(10, 2)
});
// Encrypt before storing
Payment.beforeCreate(async (payment) => {
if (payment.card_number) {
// Extract last 4 for display
payment.card_last_four = payment.card_number.slice(-4);
// Encrypt full PAN
payment.encrypted_pan = cipher.encrypt(
Buffer.from(payment.card_number)
).toString();
// Remove plaintext from model
delete payment.card_number;
}
});
// Decrypt when needed (should be rare!)
Payment.prototype.getDecryptedPAN = function() {
if (!this.encrypted_pan) return null;
const decrypted = cipher.decrypt(this.encrypted_pan);
return decrypted.toString();
};Better Approach - Use Payment Tokenization:
// Use Stripe, PayPal, or other payment processor tokenization
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
async function processPayment(cardDetails, amount) {
// Create payment method (card never touches your server)
const paymentMethod = await stripe.paymentMethods.create({
type: 'card',
card: cardDetails // Tokenized by Stripe.js in browser
});
// Store only the payment method ID
const payment = await Payment.create({
user_id: req.user.id,
payment_method_id: paymentMethod.id,
card_last_four: paymentMethod.card.last4,
card_brand: paymentMethod.card.brand,
amount: amount
});
// Process payment
const charge = await stripe.paymentIntents.create({
amount: amount * 100, // Stripe uses cents
currency: 'usd',
payment_method: paymentMethod.id,
confirm: true
});
return { payment, charge };
}Priority: P0 - Critical for PCI-DSS compliance
---
HIGH-2: Missing Rate Limiting on API Endpoints
Severity: High CWE ID: CWE-770 (Allocation of Resources Without Limits) OWASP: A04:2021 - Insecure Design CVSS Score: 7.2 (High)
Description:
API endpoints lack rate limiting, allowing attackers to perform brute force attacks, credential stuffing, and denial of service attacks without restrictions.
Location:
- All API endpoints
- Particularly critical:
/api/auth/login,/api/password/reset
Impact:
- Brute force attacks on user accounts
- Credential stuffing with leaked passwords
- API abuse and resource exhaustion
- Denial of service
- Increased infrastructure costs
Remediation:
const rateLimit = require('express-rate-limit');
const RedisStore = require('rate-limit-redis');
const redis = require('redis');
// Create Redis client for distributed rate limiting
const redisClient = redis.createClient({
host: process.env.REDIS_HOST,
port: process.env.REDIS_PORT
});
// Strict rate limit for authentication endpoints
const authLimiter = rateLimit({
store: new RedisStore({
client: redisClient,
prefix: 'rl:auth:'
}),
windowMs: 15 * 60 * 1000, // 15 minutes
max: 5, // 5 requests per window
message: 'Too many login attempts, please try again later',
standardHeaders: true,
legacyHeaders: false,
// Return remaining attempts
handler: (req, res) => {
res.status(429).json({
error: 'Too many attempts',
retryAfter: Math.ceil(req.rateLimit.resetTime / 1000)
});
}
});
// General API rate limit
const apiLimiter = rateLimit({
store: new RedisStore({
client: redisClient,
prefix: 'rl:api:'
}),
windowMs: 60 * 1000, // 1 minute
max: 100, // 100 requests per minute
message: 'Too many requests, please slow down'
});
// Apply to routes
app.post('/api/auth/login', authLimiter, loginController);
app.post('/api/auth/register', authLimiter, registerController);
app.post('/api/password/reset', authLimiter, resetPasswordController);
app.use('/api/', apiLimiter);
// User-specific rate limiting
function userRateLimiter(req, res, next) {
const userId = req.user?.id;
if (!userId) return next();
const key = `user:${userId}:requests`;
redisClient.incr(key, (err, requests) => {
if (requests === 1) {
redisClient.expire(key, 60); // 1 minute window
}
if (requests > 200) { // 200 requests per minute per user
return res.status(429).json({
error: 'Rate limit exceeded'
});
}
next();
});
}
app.use('/api/', userRateLimiter);Priority: P1 - Implement within 1 week
---
Remediation Timeline
Phase 1: Critical Issues (Week 1)
Risk Reduction: 70%
- [ ] CRITICAL-1: Fix SQL injection in user search
- Effort: 1 day
- Owner: Backend team
- Dependencies: None
- [ ] CRITICAL-2: Fix JWT authentication bypass
- Effort: 2 days
- Owner: Security team
- Dependencies: None
- [ ] HIGH-1: Encrypt sensitive payment data
- Effort: 3-4 days
- Owner: Backend + DevOps
- Dependencies: Key management setup
Deliverables:
- Code fixes merged to main branch
- Unit tests for SQL injection prevention
- Integration tests for JWT validation
- Encryption key rotation procedure
---
Phase 2: High Priority (Weeks 2-3)
Risk Reduction: 20%
- [ ] HIGH-2: Implement rate limiting
- [ ] HIGH-3: Fix XSS in product reviews
- [ ] HIGH-4: Add CSRF protection
- [ ] HIGH-5: Implement secure session management
Deliverables:
- Rate limiting deployed to all environments
- XSS test suite
- CSRF tokens on all forms
- Session security audit
---
Phase 3: Medium Priority (Month 2)
Risk Reduction: 8%
- [ ] Fix all medium severity vulnerabilities
- [ ] Implement security headers
- [ ] Add input validation framework
- [ ] Enable database query logging
- [ ] Implement WAF rules
---
Phase 4: Low Priority & Hardening (Month 3)
Risk Reduction: 2%
- [ ] Fix low severity issues
- [ ] Implement security monitoring
- [ ] Add intrusion detection
- [ ] Perform penetration testing
- [ ] Document security architecture
---
Compliance Assessment
PCI-DSS Status: ❌ NON-COMPLIANT
| Requirement | Status | Findings | Priority |
|---|---|---|---|
| 3.4: Encrypt cardholder data | ❌ Failed | Plain text storage | P0 |
| 6.5.1: Injection flaws | ❌ Failed | SQL injection present | P0 |
| 6.5.10: Authentication | ❌ Failed | JWT bypass possible | P0 |
| 8.2: Multi-factor auth | ⚠️ Partial | Only for admins | P1 |
| 10.1: Audit trails | ⚠️ Partial | Incomplete logging | P2 |
Estimated Time to Compliance: 4-6 weeks Compliance Owner: CISO
---
GDPR Status: ⚠️ PARTIALLY COMPLIANT
| Requirement | Status | Findings |
|---|---|---|
| Right to access (Art 15) | ✅ Compliant | Export function implemented |
| Right to erasure (Art 17) | ❌ Non-Compliant | No deletion mechanism |
| Data minimization (Art 5) | ⚠️ Partial | Excessive logging |
| Encryption (Art 32) | ⚠️ Partial | Missing for some data |
| Breach notification (Art 33) | ✅ Compliant | Process documented |
Priority Actions:
1. Implement user data deletion (P1) 2. Reduce log data retention (P2) 3. Encrypt all personal data (P1)
---
Security Metrics
Vulnerability Distribution
Critical: ██ 2 (7%)
High: █████ 5 (17%)
Medium: ███████████ 11 (38%)
Low: ███████ 7 (24%)
Info: ████ 4 (14%)OWASP Top 10 Coverage
| Category | Vulnerabilities | Severity |
|---|---|---|
| A01: Broken Access Control | 2 | High |
| A02: Cryptographic Failures | 3 | Critical/High |
| A03: Injection | 2 | Critical/High |
| A04: Insecure Design | 4 | High/Medium |
| A05: Security Misconfiguration | 6 | Medium/Low |
| A06: Vulnerable Components | 3 | Medium |
| A07: Authentication Failures | 2 | Critical/High |
| A08: Data Integrity Failures | 2 | Medium |
| A09: Logging Failures | 3 | Medium/Low |
| A10: SSRF | 0 | - |
CWE Distribution
Most common vulnerability categories:
1. CWE-89: SQL Injection (2 findings) 2. CWE-79: Cross-site Scripting (3 findings) 3. CWE-311: Missing Encryption (3 findings) 4. CWE-352: CSRF (2 findings) 5. CWE-770: Missing Rate Limiting (4 findings)
---
Conclusion
This application requires immediate security remediation before production deployment. The presence of critical SQL injection and authentication bypass vulnerabilities poses unacceptable risk to user data and business operations.
Recommendations:
1. Immediate: Fix all critical vulnerabilities (Week 1) 2. Short-term: Address high severity issues (Weeks 2-3) 3. Medium-term: Achieve PCI-DSS and GDPR compliance (4-6 weeks) 4. Ongoing: Implement security testing in CI/CD pipeline 5. Long-term: Establish security champions program
Next Steps:
1. Convene security review meeting with stakeholders 2. Assign ownership for each vulnerability 3. Create JIRA tickets with detailed remediation steps 4. Establish weekly security sync meetings 5. Schedule retest after Phase 1 completion
---
Appendix A: Testing Methodology
Tools Used:
- Manual code review (primary)
- OWASP ZAP for dynamic testing
- Snyk for dependency scanning
- SonarQube for static analysis
- Custom security test scripts
Limitations:
- Testing performed in staging environment
- No social engineering testing
- No physical security assessment
- Infrastructure security not in scope
- Denial of service testing limited
---
Appendix B: Security Team Contacts
Questions or Concerns:
- Security Team: <security@example.com>
- CISO: <ciso@example.com>
- On-call Security: +1-555-SECURITY
For Urgent Security Issues:
- Slack: #security-incidents
- PagerDuty: Security Team escalation
---
Report Version: 1.0 Classification: CONFIDENTIAL Distribution: Security team, Engineering leadership, CISO
Security Review Workflow
Step 1: Initial Security Assessment
Gather Context:
- Identify application type (web app, API, mobile, desktop, embedded)
- Determine data sensitivity level (PII, financial, healthcare, etc.)
- Note compliance requirements (PCI-DSS, GDPR, HIPAA, SOC 2)
- Check authentication/authorization mechanisms
- Identify external integrations and APIs
- Review security configuration files
Threat Modeling:
- Identify assets (data, functions, resources)
- Determine threat actors (external attackers, insiders, automated bots)
- Map attack surfaces (user inputs, APIs, file operations, network)
- Assess security controls in place
Step 2: OWASP Top 10 Analysis
Review code for OWASP Top 10 vulnerabilities:
2.1 A01: Broken Access Control
What to Check:
- Authorization checks on all sensitive operations
- Horizontal privilege escalation (accessing other users' data)
- Vertical privilege escalation (accessing admin functions)
- Direct object references without authorization
- Missing function-level access control
- CORS misconfiguration
- Force browsing to unauthorized pages
Vulnerable Examples:
❌ Missing Authorization Check:
@app.route('/user/<user_id>/profile')
def get_profile(user_id):
# No check if current user can access this profile
user = User.query.get(user_id)
return jsonify(user.to_dict())❌ Insecure Direct Object Reference (IDOR):
// User can modify user_id to access others' orders
app.get('/api/orders/:order_id', (req, res) => {
const order = db.getOrder(req.params.order_id);
res.json(order); // No ownership check
});✅ Secure Implementation:
@app.route('/user/<user_id>/profile')
@login_required
def get_profile(user_id):
current_user_id = get_current_user_id()
# Verify user can access this profile
if user_id != current_user_id and not current_user_has_admin_role():
abort(403, "Access denied")
user = User.query.get_or_404(user_id)
return jsonify(user.to_dict())2.2 A02: Cryptographic Failures
What to Check:
- Sensitive data transmitted over plain HTTP
- Weak encryption algorithms (MD5, SHA1, DES, RC4)
- Hard-coded encryption keys
- Insufficient key length
- Missing encryption for sensitive data at rest
- Predictable random number generation
- Password storage without proper hashing
Vulnerable Examples:
❌ Weak Hashing:
// MD5 is cryptographically broken
String passwordHash = DigestUtils.md5Hex(password);❌ Hard-Coded Secret:
const jwt = require('jsonwebtoken');
const token = jwt.sign(payload, 'my-secret-key-123'); // Hard-coded❌ Insecure Random:
import random
token = random.randint(100000, 999999) # Predictable✅ Secure Implementation:
// Use bcrypt with sufficient work factor
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(12);
String passwordHash = encoder.encode(password);// Load secret from environment
const token = jwt.sign(payload, process.env.JWT_SECRET, {
algorithm: 'HS256',
expiresIn: '1h'
});import secrets
token = secrets.token_urlsafe(32) # Cryptographically secure2.3 A03: Injection
What to Check:
- SQL Injection in database queries
- NoSQL Injection in MongoDB/other NoSQL
- Command Injection in system calls
- LDAP Injection
- XML Injection
- XPath Injection
- Template Injection
- Expression Language Injection
Vulnerable Examples:
❌ SQL Injection:
# Never concatenate user input into SQL
query = f"SELECT * FROM users WHERE username = '{username}' AND password = '{password}'"
cursor.execute(query)❌ Command Injection:
const { exec } = require('child_process');
// User input directly in command
exec(`ping -c 4 ${req.body.host}`, (err, stdout) => {
res.send(stdout);
});❌ NoSQL Injection:
// Vulnerable to {$ne: null} injection
db.users.find({ username: req.body.username, password: req.body.password });✅ Secure Implementation:
# Use parameterized queries
query = "SELECT * FROM users WHERE username = ? AND password = ?"
cursor.execute(query, (username, password_hash))// Validate and sanitize input
const host = req.body.host;
if (!/^[\w.-]+$/.test(host)) {
return res.status(400).send('Invalid host');
}
// Use execFile with array arguments
execFile('ping', ['-c', '4', host], (err, stdout) => {
res.send(stdout);
});// Ensure inputs are strings, not objects
db.users.findOne({
username: String(req.body.username),
password: String(req.body.password)
});2.4 A04: Insecure Design
What to Check:
- Missing security requirements in design
- Insufficient threat modeling
- No rate limiting on sensitive operations
- Lack of defense in depth
- Missing input validation architecture
- No security logging and monitoring
- Insecure default configurations
Example Issues:
❌ No Rate Limiting:
@app.route('/login', methods=['POST'])
def login():
# No rate limiting - vulnerable to brute force
username = request.json['username']
password = request.json['password']
# authenticate...✅ Rate Limiting Implemented:
from flask_limiter import Limiter
limiter = Limiter(app, key_func=get_remote_address)
@app.route('/login', methods=['POST'])
@limiter.limit("5 per minute") # Max 5 attempts per minute
def login():
username = request.json['username']
password = request.json['password']
# authenticate...2.5 A05: Security Misconfiguration
What to Check:
- Default credentials still enabled
- Unnecessary features enabled
- Error messages revealing sensitive info
- Security headers missing
- Outdated software versions
- Unnecessary services running
- Improper permissions
Vulnerable Examples:
❌ Detailed Error Messages:
try:
# database operation
except Exception as e:
# Exposes internal details
return jsonify({'error': str(e), 'traceback': traceback.format_exc()}), 500❌ Missing Security Headers:
// No security headers set
app.get('/', (req, res) => {
res.send('<h1>Welcome</h1>');
});✅ Secure Implementation:
try:
# database operation
except DatabaseError as e:
logger.error(f"Database error: {e}")
# Generic error message to user
return jsonify({'error': 'An error occurred. Please try again later.'}), 500const helmet = require('helmet');
app.use(helmet()); // Sets secure headers
// Or manually:
app.use((req, res, next) => {
res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('X-Frame-Options', 'DENY');
res.setHeader('X-XSS-Protection', '1; mode=block');
res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
res.setHeader('Content-Security-Policy', "default-src 'self'");
next();
});2.6 A06: Vulnerable and Outdated Components
What to Check:
- Outdated dependencies with known CVEs
- Unused dependencies increasing attack surface
- Dependencies from untrusted sources
- No dependency scanning in CI/CD
- Transitive dependency vulnerabilities
Detection Methods:
# Python
pip-audit
safety check
# Node.js
npm audit
yarn audit
# Java
mvn dependency-check:check
./gradlew dependencyCheckAnalyze
# .NET
dotnet list package --vulnerable
# Go
go list -json -m all | nancy sleuthReport Format:
Vulnerability: lodash Prototype Pollution
Severity: High (CVSS 7.4)
CVE: CVE-2020-8203
Affected: lodash@4.17.15
Fixed in: lodash@4.17.21
Impact: Remote code execution possible
Remediation: Update to version 4.17.21 or higher2.7 A07: Identification and Authentication Failures
What to Check:
- Weak password requirements
- No multi-factor authentication
- Session fixation vulnerabilities
- Exposed session identifiers in URLs
- Session timeout not implemented
- Credential stuffing protection missing
- Permits brute force attacks
Vulnerable Examples:
❌ Weak Session Management:
// Session ID in URL - vulnerable to fixation
$session_id = $_GET['sessionid'];
session_id($session_id);
session_start();❌ No Session Timeout:
// Session never expires
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true
// No maxAge set
}));✅ Secure Implementation:
// Regenerate session ID on login
session_start();
session_regenerate_id(true);
$_SESSION['user_id'] = $authenticated_user_id;app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
secure: true, // HTTPS only
httpOnly: true, // Not accessible via JavaScript
maxAge: 3600000, // 1 hour timeout
sameSite: 'strict' // CSRF protection
}
}));2.8 A08: Software and Data Integrity Failures
What to Check:
- No integrity verification for updates
- Unsigned packages/artifacts
- Insecure deserialization
- No CI/CD pipeline security
- Auto-update without verification
- Untrusted data in pipelines
Vulnerable Examples:
❌ Insecure Deserialization:
import pickle
# Dangerous - can execute arbitrary code
user_data = pickle.loads(request.data)❌ No Integrity Check:
// Downloads script without verification
const script = await fetch('https://cdn.example.com/lib.js').then(r => r.text());
eval(script); // Extremely dangerous✅ Secure Implementation:
import json
# Use safe serialization
user_data = json.loads(request.data)
# Add schema validation
validate_schema(user_data, USER_SCHEMA)<!-- Use Subresource Integrity -->
<script src="https://cdn.example.com/lib.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
crossorigin="anonymous"></script>2.9 A09: Security Logging and Monitoring Failures
What to Check:
- No logging of security events
- Logs don't include sufficient context
- No alerting on suspicious activity
- Logs stored insecurely
- No log retention policy
- Missing audit trail
What to Log:
Security Events:
- Authentication attempts (success/failure)
- Authorization failures
- Input validation failures
- Privilege escalations
- Account changes (password reset, permission changes)
- Data access to sensitive resources
- Security configuration changes
Example Implementation:
import logging
security_logger = logging.getLogger('security')
@app.route('/admin/users/<user_id>/promote')
@require_admin
def promote_user(user_id):
current_admin = get_current_user()
# Log security-relevant action
security_logger.info(
f"Admin privilege escalation",
extra={
'event': 'privilege_escalation',
'admin_id': current_admin.id,
'admin_username': current_admin.username,
'target_user_id': user_id,
'ip_address': request.remote_addr,
'user_agent': request.user_agent.string,
'timestamp': datetime.utcnow().isoformat()
}
)
# Perform action
promote_to_admin(user_id)
return jsonify({'success': True})2.10 A10: Server-Side Request Forgery (SSRF)
What to Check:
- User-controlled URLs in backend requests
- No URL validation/allowlisting
- Access to internal services possible
- Cloud metadata endpoints accessible
- No network segmentation
Vulnerable Examples:
❌ SSRF Vulnerability:
@app.route('/fetch')
def fetch_url():
# User can access internal services
url = request.args.get('url')
response = requests.get(url)
return response.content✅ Secure Implementation:
from urllib.parse import urlparse
import ipaddress
ALLOWED_DOMAINS = ['api.example.com', 'cdn.example.com']
@app.route('/fetch')
def fetch_url():
url = request.args.get('url')
# Parse and validate URL
parsed = urlparse(url)
# Only allow HTTPS
if parsed.scheme != 'https':
abort(400, "Only HTTPS URLs allowed")
# Check domain allowlist
if parsed.netloc not in ALLOWED_DOMAINS:
abort(400, "Domain not allowed")
# Prevent access to private IP ranges
try:
ip = socket.gethostbyname(parsed.netloc)
if ipaddress.ip_address(ip).is_private:
abort(400, "Private IP addresses not allowed")
except socket.gaierror:
abort(400, "Invalid domain")
# Make request with timeout
response = requests.get(url, timeout=5, allow_redirects=False)
return response.contentStep 3: Additional Security Checks
3.1 Cross-Site Scripting (XSS)
Check for:
- User input rendered without escaping
- DOM-based XSS
- Reflected XSS
- Stored XSS
- Content-Security-Policy missing
Examples:
❌ XSS Vulnerable:
// React - dangerous HTML injection
<div dangerouslySetInnerHTML={{__html: userInput}} />
// jQuery - XSS vulnerable
$('#output').html(userInput);
// Plain JS - XSS vulnerable
element.innerHTML = userInput;✅ XSS Protected:
// React - auto-escapes
<div>{userInput}</div>
// jQuery - text() escapes
$('#output').text(userInput);
// Plain JS - textContent escapes
element.textContent = userInput;
// DOMPurify for HTML sanitization
import DOMPurify from 'dompurify';
element.innerHTML = DOMPurify.sanitize(userInput);3.2 Cross-Site Request Forgery (CSRF)
Check for:
- State-changing operations without CSRF token
- CSRF token validation missing
- SameSite cookie attribute not set
- GET requests causing state changes
Examples:
❌ No CSRF Protection:
@app.route('/account/delete', methods=['POST'])
@login_required
def delete_account():
# No CSRF token verification
current_user.delete()
return redirect('/goodbye')✅ CSRF Protected:
from flask_wtf.csrf import CSRFProtect
csrf = CSRFProtect(app)
@app.route('/account/delete', methods=['POST'])
@login_required
def delete_account():
# CSRF token automatically verified by Flask-WTF
current_user.delete()
return redirect('/goodbye')3.3 API Security
Check for:
- Missing authentication on endpoints
- No rate limiting
- Excessive data exposure
- Mass assignment vulnerabilities
- GraphQL query depth attacks
- API keys in client-side code
Examples:
❌ Mass Assignment:
@app.route('/user/update', methods=['PUT'])
def update_user():
user = get_current_user()
# User can set any field including is_admin
user.update(**request.json)
db.commit()✅ Protected:
ALLOWED_FIELDS = {'name', 'email', 'phone'}
@app.route('/user/update', methods=['PUT'])
def update_user():
user = get_current_user()
# Only allow specific fields
update_data = {k: v for k, v in request.json.items() if k in ALLOWED_FIELDS}
user.update(**update_data)
db.commit()3.4 File Upload Security
Check for:
- No file type validation
- Executable files allowed
- Path traversal in filenames
- No file size limits
- Files stored in web-accessible directory
Examples:
❌ Insecure Upload:
@app.route('/upload', methods=['POST'])
def upload():
file = request.files['file']
# Dangerous - user controls filename
file.save(f'/uploads/{file.filename}')✅ Secure Upload:
import os
from werkzeug.utils import secure_filename
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'pdf'}
MAX_FILE_SIZE = 10 * 1024 * 1024 # 10MB
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/upload', methods=['POST'])
def upload():
file = request.files['file']
# Validate file exists
if not file or file.filename == '':
abort(400, "No file provided")
# Validate file type
if not allowed_file(file.filename):
abort(400, "File type not allowed")
# Check file size
file.seek(0, os.SEEK_END)
if file.tell() > MAX_FILE_SIZE:
abort(400, "File too large")
file.seek(0)
# Secure filename
filename = secure_filename(file.filename)
# Generate unique filename
unique_filename = f"{uuid.uuid4()}_{filename}"
# Store outside web root
filepath = os.path.join('/secure/uploads', unique_filename)
file.save(filepath)
return jsonify({'filename': unique_filename})3.5 XML External Entity (XXE)
Check for:
- XML parsers with external entity processing enabled
- SOAP endpoints processing user XML
- SVG file uploads
Examples:
❌ XXE Vulnerable:
from xml.etree.ElementTree import parse
# Vulnerable to XXE
tree = parse(user_xml_file)✅ XXE Protected:
from defusedxml.ElementTree import parse
# Protected against XXE
tree = parse(user_xml_file)Step 4: Language-Specific Security
Java/Spring:
- Check for SQL injection (use PreparedStatement)
- Validate @RequestBody with constraints
- Use Spring Security properly
- CSRF protection enabled
- Session fixation protection
Node.js/Express:
- helmet middleware for security headers
- express-rate-limit for rate limiting
- csrf middleware for CSRF protection
- Avoid eval() and new Function()
- Validate environment variables
Python/Flask/Django:
- SQLAlchemy parameterized queries
- Django ORM (safe by default)
- CSRF middleware enabled
- Secure session configuration
- Jinja2 auto-escaping
.NET/C#:
- Entity Framework parameterized queries
- AntiForgeryToken for CSRF
- ValidateInput attribute
- Authentication/authorization filters
- Data annotations for validation
PHP:
- Prepared statements (PDO or MySQLi)
- htmlspecialchars() for output escaping
- FILTER_* constants for input validation
- password_hash() for passwords
- CSRF token validation
Step 5: Security Configuration Review
Check:
Web Server:
- TLS 1.2+ only
- Strong cipher suites
- HSTS enabled
- Security headers configured
- Directory listing disabled
- Default pages removed
Database:
- Strong authentication
- Encrypted connections
- Principle of least privilege
- Audit logging enabled
- Backup encryption
Cloud/Infrastructure:
- IAM roles properly scoped
- Security groups restrictive
- Encryption at rest enabled
- Logging enabled
- Secrets management (not hard-coded)
Step 6: Compliance Validation
PCI-DSS (Payment Card Industry)
Key Requirements:
- Cardholder data encrypted in transit and at rest
- Strong access control measures
- Regular security testing
- Network segmentation
- Secure authentication
Check for:
- Credit card data in logs
- PAN (Primary Account Number) storage
- CVV/CVC storage (prohibited)
- Encryption key management
GDPR (General Data Protection Regulation)
Key Requirements:
- User consent for data processing
- Right to data deletion
- Right to data portability
- Data breach notification
- Privacy by design
Check for:
- PII data inventory
- Consent management
- Data retention policies
- Deletion mechanisms
- Data export functionality
HIPAA (Health Insurance Portability and Accountability Act)
Key Requirements:
- PHI (Protected Health Information) encryption
- Access controls and audit logs
- Data integrity controls
- Breach notification
Check for:
- Health data encryption
- Audit logging of PHI access
- Authentication mechanisms
- Data integrity verification
Step 7: Generate Security Report
Security Testing Checklist
Use this for systematic security reviews:
Authentication & Authorization:
- [ ] All endpoints require authentication
- [ ] Authorization checks on every operation
- [ ] No horizontal privilege escalation possible
- [ ] No vertical privilege escalation possible
- [ ] Session management secure
- [ ] Password policy enforced
- [ ] MFA available for sensitive operations
Input Validation:
- [ ] All input validated (whitelist approach)
- [ ] SQL injection prevention (parameterized queries)
- [ ] XSS prevention (output encoding)
- [ ] Command injection prevention
- [ ] Path traversal prevention
- [ ] File upload restrictions
Cryptography:
- [ ] Strong algorithms only (AES-256, RSA-2048+)
- [ ] Secure password hashing (bcrypt, Argon2)
- [ ] TLS 1.2+ enforced
- [ ] No hard-coded secrets
- [ ] Secure random number generation
- [ ] Certificate validation
Session Management:
- [ ] Secure session ID generation
- [ ] Session fixation protection
- [ ] Proper session timeout
- [ ] HttpOnly and Secure flags set
- [ ] SameSite attribute configured
- [ ] Session invalidation on logout
Error Handling:
- [ ] Generic error messages to users
- [ ] Detailed errors logged server-side
- [ ] No stack traces exposed
- [ ] No sensitive data in errors
Logging & Monitoring:
- [ ] Security events logged
- [ ] Sufficient log detail
- [ ] Logs protected from tampering
- [ ] Alerting on suspicious activity
- [ ] Log retention policy
API Security:
- [ ] API authentication required
- [ ] Rate limiting implemented
- [ ] Input validation on all endpoints
- [ ] No excessive data exposure
- [ ] CORS properly configured
- [ ] API versioning
Data Protection:
- [ ] Sensitive data encrypted at rest
- [ ] Sensitive data encrypted in transit
- [ ] PII handling compliant with regulations
- [ ] Secure data deletion
- [ ] Backup encryption
Dependencies:
- [ ] No known vulnerable dependencies
- [ ] Dependency scanning in CI/CD
- [ ] Regular dependency updates
- [ ] SCA (Software Composition Analysis) tools
Configuration:
- [ ] Security headers configured
- [ ] Default credentials changed
- [ ] Unnecessary features disabled
- [ ] Secure defaults
- [ ] Environment-specific configs
Related skills
FAQ
Does it replace automated SAST/DAST tools?
It guides manual, context-aware review; combine with scanners and pentests for defense in depth.
Which compliance frameworks are referenced?
The skill mentions PCI-DSS, GDPR, HIPAA, SOC 2, and ISO 27001 as context during assessment.
Can it review mobile or desktop apps?
Initial assessment includes application type; analysis adapts to web, API, mobile, desktop, or embedded contexts.