Why security review belongs in every pull request
Most vulnerabilities are introduced by ordinary feature work: a new endpoint that forgets an ownership check, a search box that builds a query from a string, a debug log that prints a token. A yearly penetration test finds some of them months later. Reviewing security on each pull request finds them while the author still has the context to fix them in minutes.
Application security code review also produces evidence. Frameworks such as SOC 2, ISO 27001 and PCI DSS expect changes to be reviewed before release, and a reviewed pull request with security findings resolved is exactly that evidence.
What to check: the high-impact categories
The OWASP Top 10 is a good map of where real-world breaches come from. In code review, these categories matter most:
- Broken access control. Every request must check that the caller may act on the specific record, not just that they are logged in. Insecure direct object references (IDOR) — loading /invoices/123 without checking ownership — are among the most common findings.
- Injection. SQL, NoSQL, OS command, LDAP and template injection all come from mixing untrusted input into an interpreter. Use parameterised queries and never build commands from strings.
- Authentication and sessions. Slow password hashing (Argon2, bcrypt, scrypt), session rotation on login, Secure and HttpOnly cookies, and correct JWT validation — including rejecting the 'none' algorithm.
- Secrets in code. API keys, tokens and private keys committed to the repository, including in test fixtures and config files.
- Server-side request forgery (SSRF). Endpoints that fetch a user-supplied URL can be pointed at internal services and cloud metadata endpoints.
- Cryptography. Weak hashes for passwords, predictable random values for tokens (Math.random is not a secure generator), and home-made encryption.
- Sensitive data exposure. Personal data or credentials written to logs, error messages or analytics events.
- Unsafe deserialisation and parsing. XML parsers with external entities enabled (XXE), and deserialising untrusted data into objects.
- Vulnerable dependencies. New packages or version bumps with known vulnerabilities, or packages that don't need the access they request.
The secure code review process
- 1. Scope the change. Identify what the change touches: authentication, permissions, payments, file handling, data export, new dependencies. High-risk areas get deeper review and a second, security-aware reviewer.
- 2. Think like an attacker. For new endpoints and data flows, spend a few minutes on what an attacker would try: other users' IDs, oversized input, unexpected types, replayed requests.
- 3. Run automated checks. SAST, secret scanning and dependency scanning run in CI; an AI reviewer adds intent-level findings on the pull request.
- 4. Review by hand where it matters. Read the authorisation logic, input handling and data flows the tools can't reason about.
- 5. Triage findings. Separate true issues from false positives, rate severity, and decide what blocks the merge.
- 6. Fix and verify. Fix, add a test that would have caught the issue, and re-review.
- 7. Turn lessons into rules. When the same issue appears twice, encode it as an automated rule so it never needs a human to catch it again.
Security code review tools
No single tool covers everything. Most teams combine several categories, each catching a different class of problem:
| Category | What it finds | Examples |
|---|---|---|
| SAST (static analysis) | Known vulnerable code patterns: injection sinks, dangerous APIs | Semgrep, CodeQL, SonarQube, Checkmarx, Snyk Code |
| Secret scanning | Keys, tokens and credentials committed to the repository | Gitleaks, TruffleHog, GitHub secret scanning |
| Dependency scanning (SCA) | Known vulnerabilities in third-party packages | Dependabot, Snyk Open Source, OWASP Dependency-Check |
| AI code review | Logic and access-control flaws, explained in context on the pull request | Mesrai and other AI reviewers |
| DAST | Vulnerabilities in the running application | OWASP ZAP, Burp Suite |
Manual vs automated security code review
Automated tools are fast, consistent and good at known patterns. They struggle with business-logic flaws such as the missing ownership check above, because nothing in the code is a known bad pattern — the problem is what's missing. Human and AI reviewers can reason about intent: who should be allowed to do this, and does the code enforce it? The strongest setup runs SAST, secret and dependency scanning as automated gates and adds a review step that reads each change for logic and access-control flaws.
| Automated (SAST, scanners) | Review (human or AI) | |
|---|---|---|
| Speed | Seconds to minutes | Minutes (AI) to hours (human) |
| Consistency | Same result every time | Varies by reviewer or model |
| Known patterns (injection, secrets) | Strong | Strong |
| Business logic and authorisation | Weak | Strong |
| False positives | Can be high without tuning | Lower when the reviewer has context |
Language-specific checks: Python and Java
Each language has its own dangerous APIs. A few that come up often in review:
- Python. subprocess with shell=True and user input; SQL built with f-strings; pickle.loads or yaml.load on untrusted data (use yaml.safe_load); eval and exec; requests calls with verify=False; debug mode left on in Flask or Django settings.
- Java. XML parsers without external entities disabled (XXE); Java deserialisation of untrusted input; SQL built by string concatenation instead of PreparedStatement; overly broad permitAll() rules in Spring Security; Runtime.exec with user input.
- JavaScript / TypeScript. dangerouslySetInnerHTML or innerHTML with user content; child_process.exec with user input; prototype pollution through deep-merge helpers; missing CSRF protection on cookie-authenticated state changes.
Security code review guidelines and standards
Two OWASP resources are worth using as references. The OWASP Code Review Guide explains how to review code for security, category by category. The OWASP Application Security Verification Standard (ASVS) lists concrete security requirements at three levels, which teams often turn into review checklists and automated rules.
Security code review checklist
- Every endpoint checks the caller's permission for the specific record, not just login.
- All database access uses parameterised queries or a safe query builder.
- No user input reaches a shell command, file path, template or redirect URL unvalidated.
- No secrets, tokens or keys in code, fixtures or committed config.
- Passwords are hashed with Argon2, bcrypt or scrypt.
- Tokens and IDs that must be unguessable use a cryptographically secure generator.
- Session cookies are Secure, HttpOnly and have an appropriate SameSite value.
- JWTs are verified with an explicit algorithm and expiry.
- Outbound requests to user-supplied URLs are restricted to allowed hosts.
- Logs and errors contain no personal data or credentials.
- New dependencies are necessary, maintained and free of known vulnerabilities.
How Mesrai helps with security code review
Mesrai's security agent reviews every pull request for missing authorisation, injection, exposed secrets, unsafe cookies and other vulnerability patterns, and explains each finding with a suggested fix. Because it reads the repository graph, it can see when a change removes a check that other code relied on.
- Security findings on every PR, ranked by severity
- Your own security policies as Mesrai Rules
- Works alongside SAST, secret and dependency scanning
- Your code is never used to train models; you choose the LLM provider