What red teams look for - before vulnerabilities reach production

Most vulnerabilities I exploit during VAPT were already visible in pull requests.

They weren't hidden. They weren't zero-days. They weren't advanced.

They were approved during code review because:

  • The change worked
  • Tests passed
  • Nobody asked the security questions

From a red-team perspective, PR reviews are the last strong security gate before code reaches production.

This article is blunt on purpose.

Below are the exact security checks I mentally run when reviewing code, because these are the same patterns I exploit later.

1. Authentication & Authorization Changes

Red-team question:

Does this change allow someone to do something they couldn't do before?

What developers miss

  • New endpoints added without authentication
  • Role checks added only in the UI
  • Admin logic hidden behind client-side flags

What I look for in PRs

  • Every new route → where is auth enforced?
  • Are role checks server-side?
  • Are permissions inferred from client input?

Practical Example - The "Hidden" Admin Route

PR diff:

// Added new route for dashboard statistics
app.get('/api/stats', (req, res) => {
    return db.getStats(); // ❌ Missing authentication middleware
});

The exploit: I don't need a login. I just curl /api/stats. If the developer forgot requireAuth or @UseGuards(AuthGuard), I win.

The fix:

app.get('/api/stats', requireAuth, requireAdmin, (req, res) => {
    ...
});

Red-team reality: If auth logic changes in a PR, I read it first.

2. Client-Controlled Data Crossing Trust Boundaries

Red-team question:

Is the server trusting something the client controls?

Common examples

  • isAdmin, role, price, userId
  • Hidden fields added to JSON payloads
  • Frontend-only validation

What to check

  • Does the server recompute sensitive values?
  • Are IDs derived from session, not request body?
  • Are defaults safe?

Practical Example - Mass Assignment

PR diff:

// Update user profile
app.post('/update-profile', (req, res) => {
    const user = db.find(req.session.id);
    user.update(req.body); // ❌ BLIND TRUST
    user.save();
});

The exploit: I intercept the request and send:

{
  "name": "Hacker",
  "role": "admin",
  "is_verified": true
}

The backend blindly updates everything.

Red-team reality: If you trust the client, you trust the attacker.

3. Input Validation & Deserialization

Red-team question:

What happens if this input is malformed, oversized, or unexpected?

Red flags in PRs

  • JSON.parse() on user input
  • Direct deserialization into models
  • No size or depth limits

What to verify

  • Schema validation exists
  • Unknown fields are rejected
  • Size and depth limits enforced

Practical Example - Prototype Pollution

PR diff:

function mergeSettings(target, input) {
    for (let key in input) {
        target[key] = input[key];
    }
}

The exploit:

{
  "__proto__": {
    "isAdmin": true
  }
}

This pollutes the global object prototype.

Red-team reality: I will throw garbage at your parser until it breaks or gives me access.

4. Outbound HTTP Requests (SSRF Alert)

Red-team question:

Can I control where the server sends requests?

High-risk changes

  • URL fetchers
  • Webhooks
  • Import-from-URL features
  • Preview / metadata fetch logic

What to check

  • Is the destination allow-listed?
  • Are internal IPs blocked at the network layer?
  • Are redirects controlled?

Practical Example - Preview Feature

PR diff:

def get_preview(url):
    return requests.get(url).content  # ❌ Dangerous

The exploit: I submit:

http://169.254.169.254/latest/meta-data/

The server returns cloud credentials, not a preview.

Red-team reality: If I see axios.get(req.body.url), I'm already inside your cloud.

5. Secrets, Tokens & Configuration Files

Red-team question:

Did this PR accidentally ship credentials?

Common mistakes

  • .env changes
  • Temporary debug secrets
  • Tokens logged "just for testing"

Practical Example - Hardcoded Key

PR diff:

// TODO: Remove before prod
const STRIPE_KEY = "sk_live_51Mz...";

Even if deleted later, it's in git history forever.

The fix: Use environment variables or a secrets manager.

Red-team reality: Secrets leak → lateral movement → persistence.

6. Error Handling & Debug Output

Red-team question:

What does the app reveal when something breaks?

Practical Example - Verbose Errors

catch (SQLException e) {
    return Response.status(500).entity(e.getMessage()).build();
}

The exploit: Trigger an error → get DB type, table names, schema info.

Red-team reality: Error messages are free reconnaissance.

7. Logging & Audit Gaps

Red-team question:

If I abuse this feature, will anyone notice?

Practical Example - Silent Delete

app.delete('/user/:id', isAdmin, (req, res) => {
   db.deleteUser(req.params.id);
   res.send("Deleted");
});

No actor. No timestamp. No trail.

The fix:

logger.info("User deleted", {
  target_id: req.params.id,
  actor_id: req.user.id,
  timestamp: now()
});

Red-team reality: Silent abuse beats loud exploits.

8. Dependency Changes & Supply Chain Risk

Red-team question:

What new code just entered your system indirectly?

Practical Example - Typosquatting

"dependencies": {
  "cross-env": "^7.0.0",
  "eletron": "^12.0.0"
}

An attacker publishes eletron with a malicious post-install script.

Red-team reality: I don't need your code if I control your dependency.

9. CI/CD & Infrastructure-as-Code Changes

Red-team question:

Did this PR weaken your pipeline security?

Practical Example - Dangerous Workflow

on: pull_request_target
jobs:
  test:
    runs-on: self-hosted
    steps:
      - run: npm install && npm test

A forked PR can execute attacker-controlled code with secrets.

Red-team reality: Pipeline compromise → production compromise.

10. Feature Flags, Debug Code & Bypasses

Red-team question:

What happens if this flag is flipped?

Practical Example - Temporary Bypass

if (req.query.debug === 'true' || checkAuth(req)) {
    // Allow access
}

Someone forgets to remove it. Now auth is optional.

Red-team reality: Temporary code becomes permanent attack surface.

The Red-Team PR Security Checklist (Save This)

Before approving any PR:

  • Does this change affect auth or permissions?
  • Is any client input trusted by the server?
  • Are outbound requests introduced?
  • Could this leak secrets or sensitive data?
  • Are errors and logs safe?
  • Does this add new dependencies?
  • Does this touch CI/CD or infrastructure?
  • Is any debug or bypass logic present?

If one answer is unclear, the PR needs another look.

Conclusion

Most vulnerabilities are not hacked in. They are:

  • Reviewed
  • Approved
  • Deployed

Red teams don't magically break systems. We follow the paths code reviews allowed.

If you want fewer VAPT findings and fewer incidents:

Make security part of PR reviews - not postmortems.

Follow me for weekly red-team writeups, VAPT case studies, and practical secure-development guides. Connect with me on LinkedIn and GitHub.