Review Process and Feedback

Learn effective security review processes, checklists, and how to communicate security issues constructively during code review.

Effective security review is not just about finding issues - it's about communicating them in a way that helps developers learn and fix problems quickly.

Security Review Checklist

Use this checklist as a starting point for security reviews:

Input Validation

[ ] All user input is validated before use
[ ] Validation uses allowlists where possible
[ ] Input length limits are enforced
[ ] Special characters are handled appropriately
[ ] Numeric inputs have range checks
[ ] File uploads validate type and size

Authentication

[ ] Passwords are hashed with bcrypt/argon2/scrypt
[ ] Password requirements are enforced (length, complexity)
[ ] Rate limiting on login attempts
[ ] Session tokens are cryptographically random
[ ] Sessions are invalidated on logout
[ ] Session timeout is implemented
[ ] Password reset tokens expire quickly
[ ] MFA is available for sensitive operations

Authorization

[ ] Authorization checked on every request
[ ] Authorization is server-side
[ ] Object-level authorization (user owns resource)
[ ] Function-level authorization (user has permission)
[ ] No direct object references without checks
[ ] Admin functions require admin role
[ ] API keys have appropriate scopes

Data Protection

[ ] Sensitive data encrypted at rest
[ ] TLS 1.2+ for data in transit
[ ] No sensitive data in URLs
[ ] No sensitive data in logs
[ ] PII handled per privacy requirements
[ ] Secrets not hardcoded in source
[ ] Secrets not in version control

Error Handling

[ ] Errors don't leak sensitive information
[ ] Stack traces not shown in production
[ ] Failed operations logged for monitoring
[ ] Failures default to secure state
[ ] Rate limiting on error-prone endpoints

Security Headers

[ ] Content-Security-Policy configured
[ ] X-Content-Type-Options: nosniff
[ ] X-Frame-Options or frame-ancestors CSP
[ ] Strict-Transport-Security (HSTS)
[ ] Referrer-Policy configured
[ ] Permissions-Policy for sensitive APIs

Prioritizing Findings

Not all security issues are equal. Use this framework to prioritize:

Critical - Fix Before Merge

  • SQL/Command injection
  • Authentication bypass
  • Remote code execution
  • Exposed credentials/secrets
  • Missing authorization on sensitive endpoints

High - Fix Soon

  • XSS vulnerabilities
  • CSRF vulnerabilities
  • Weak cryptography
  • Session management issues
  • Insecure deserialization

Medium - Track and Plan

  • Missing security headers
  • Verbose error messages
  • Missing rate limiting
  • Weak password requirements
  • Missing input validation

Low - Improve Over Time

  • Missing audit logging
  • Code quality issues
  • Documentation gaps
  • Non-security best practices

Writing Effective Feedback

Good security feedback is specific, actionable, and educational.

Bad Feedback Examples

"This is insecure."
-> Too vague, doesn't help the developer

"You need to fix this SQL injection."
-> Missing specifics about what and how

"This is a security vulnerability, please fix."
-> No context, no guidance

Good Feedback Examples

"SQL Injection vulnerability on line 42.

The user input `request.args.get('id')` is concatenated directly
into the SQL query without sanitization.

Attack example:
  id = "1; DROP TABLE users; --"

Fix: Use parameterized queries:
  cursor.execute('SELECT * FROM users WHERE id = %s', (user_id,))

Reference: https://owasp.org/www-community/attacks/SQL_Injection"
"Missing authorization check in get_document() (line 87).

Currently any authenticated user can access any document by ID.
This allows horizontal privilege escalation - User A can access
User B's documents by guessing document IDs.

Suggested fix:
  doc = Document.query.filter_by(
      id=doc_id,
      owner_id=current_user.id
  ).first_or_404()

This ensures users can only access their own documents."

Feedback Template

## [Severity] Issue Title

**Location:** file.py, line 42

**Problem:** Brief description of the vulnerability

**Impact:** What could an attacker do?

**Proof of Concept:** Example attack input or scenario

**Suggested Fix:** Code example or approach

**References:** Links to learn more

Handling Pushback

Developers may push back on security findings. Handle this constructively:

"It's just internal / behind a VPN"

Response: "Defense in depth means we protect against internal threats too. VPNs can be compromised, and employees can be malicious. Let's add the protection anyway - it's low effort and high value."

"We don't have time to fix this"

Response: "I understand the time pressure. Let's prioritize - the SQL injection is critical and must be fixed. The missing headers can wait for the next sprint. Can we create a ticket to track the lower-priority items?"

"Nobody would actually exploit this"

Response: "Attackers actively scan for these patterns. There are automated tools that find SQL injection, XSS, etc. Even if the risk seems low, the fix is usually simple. Let's not leave a known vulnerability."

"This is how we've always done it"

Response: "I understand it's existing code. Security standards evolve as new attacks emerge. Let's fix it going forward - we can add a ticket to remediate the existing instances."

Review Tools and Automation

Combine manual review with automated tools:

Pre-Review Automation

Run these before manual review to catch obvious issues:

# GitHub Actions example
- name: Run SAST
  uses: github/codeql-action/analyze@v2

- name: Check dependencies
  run: npm audit --audit-level=high

- name: Secrets scan
  uses: gitleaks/gitleaks-action@v2

During Review

Use IDE plugins and browser extensions:

  • SonarLint - Real-time SAST in your IDE
  • Snyk - Dependency vulnerability scanning
  • GitHub Security - Code scanning alerts in PRs

Post-Review

Track security debt:

# Security debt tracking example
| Issue | Severity | File | Created | Status |
|-------|----------|------|---------|--------|
| Missing rate limiting | Medium | auth.py | 2024-01-15 | Backlog |
| Verbose errors | Low | api.py | 2024-01-10 | In Progress |

Building a Security Review Culture

Make Security Everyone's Job

  • Include security in definition of done
  • Rotate security review responsibility
  • Celebrate security fixes, not just features
  • Share security knowledge in team meetings

Provide Training

  • Regular security awareness sessions
  • OWASP Top 10 walkthrough
  • Language-specific security training
  • Incident post-mortems (redacted if needed)

Measure and Improve

Track metrics to improve over time:

  • Time to fix security issues
  • Security issues found in review vs production
  • Coverage of security review (% of PRs reviewed)
  • Developer security training completion

Quick Reference Card

Print this for your desk:

SECURITY CODE REVIEW QUICK REFERENCE
====================================

ALWAYS CHECK:
- User input -> validation -> use
- Authentication on sensitive endpoints
- Authorization on every data access
- Parameterized queries for SQL
- Output encoding for HTML/JS
- Secrets not in code

RED FLAGS:
- String concatenation + SQL/commands
- eval(), exec(), pickle, yaml.load()
- innerHTML with user data
- shell=True with user input
- Missing authorization checks
- Hardcoded secrets/passwords

QUESTIONS TO ASK:
- What if this input is malicious?
- Who should be allowed to do this?
- What data could leak on error?
- Is this logged for security monitoring?

Found an issue?