The vectors most teams are already watching
Dependency confusion attacks — where an internal package name is registered on a public registry and installed instead of the internal version — became widely understood after a public security researcher demonstrated the technique in 2021. Typosquatting on npm, PyPI, and RubyGems is a variation that predates that disclosure and remains active: packages named reqeusts, colourama, or python-dateuitls that harvest credentials or establish reverse shells on install.
Both attack vectors are dependency-level problems with dependency-level mitigations: private registry configuration, package allowlists, lockfile verification in CI, scoped package prefixes for internal packages. Software composition analysis (SCA) tools scan dependency manifests and lockfiles for these patterns. Most engineering teams at growing companies have at least some coverage here.
The supply chain risk that gets less attention — and that is harder to detect with off-the-shelf tooling — is the one introduced in the pull request itself. Not through a dependency, but through code patterns in the application layer that create the conditions for supply chain compromise, that normalize dangerous patterns for future contributors, or that undermine the integrity controls the organization already has in place.
Prototype pollution: the JavaScript supply chain risk hiding in plain code
Prototype pollution (CWE-1321) is a JavaScript vulnerability class where a program allows user-controlled keys in a deeply nested object assignment to modify Object.prototype. Once the prototype is polluted, every object in the application inherits the attacker-controlled property, which can override default values in ways that affect application behavior globally — including security checks, authorization logic, and configuration values.
Why is this a supply chain concern? Because prototype pollution in application code is frequently introduced through careless adoption of utility patterns from internal or third-party libraries. A merge deep extend function that doesn't handle __proto__ or constructor keys is a canonical example — it appears throughout JavaScript codebases and is the basis for numerous high-severity CVEs in popular libraries like lodash, jQuery, and minimist.
When a developer copies a utility pattern from a library that has a prototype pollution vulnerability into application code, the vulnerability moves from a dependency (which SCA scanners watch) to first-party code (which SCA doesn't scan). A SAST rule for CWE-1321 in application code catches this transition. Without it, the code review process has no mechanism to flag the pattern — human reviewers rarely recognize prototype pollution in code that looks like ordinary object merging.
A concrete example: a growing Node.js platform migrated away from a vulnerable version of a deep merge utility by writing their own merge function. The custom function had the same __proto__ pollution vulnerability as the library they removed. SCA showed zero vulnerable dependencies — the library was gone. SAST flagged the CWE-1321 pattern in the new code. Without PR-stage SAST, the migration would have closed the known CVE while introducing an identical unregistered vulnerability.
Hardcoded credentials and secret patterns in application code
Secret detection — scanning for hardcoded API keys, tokens, private keys, and password strings in source code — is a direct supply chain risk vector. A hardcoded secret in application code is a latent exfiltration path: anyone with read access to the repository (including any compromised dependency with filesystem access) can read it. If the code is ever open-sourced, published to a package registry, or deployed to a container image, the secret travels with it.
CWE-798 (use of hardcoded credentials) covers this class broadly. Pattern detection for common secret formats — AWS credential patterns, GitHub personal access tokens, GCP service account key JSON, JWT signing secrets, database connection strings with inline passwords — is table-stakes for PR-stage scanning. The interesting detection challenge is application-specific secrets: internal service tokens, private API keys for vendor services, signing secrets for custom HMAC implementations. These don't match the regex patterns for common services and require custom detection rules based on the token format your internal services use.
The supply chain dimension: a compromised or malicious dependency that reads environment variables at import time is a known attack pattern. Hardcoded secrets in application code remove even the environment variable boundary — the secret is in the source, accessible via the module system, without requiring process environment access. Code review is the only detection point before the secret enters git history, where removing it requires history rewrite rather than just deletion.
Dependency pinning and integrity verification patterns
Beyond what SCA tools scan for in manifests, code review is the point where dependency management patterns get established. How a team pins dependencies, whether they use lockfile verification in CI, whether they verify package integrity hashes — these patterns are introduced and normalized through code review.
A PR that adds a new npm dependency with ^ version prefix in a security-sensitive service is a supply chain risk decision, not just a version management decision. The caret means "any compatible version, including future minor and patch releases," which means a compromised future release of that package installs automatically in CI without any explicit upgrade action. In a payments service, a logging library or utility that gets silently upgraded could introduce malicious code without any PR activity to catch it.
SAST rules for supply chain hygiene in this category look different from injection rules. They're not taint analysis — they're policy checks on configuration patterns. A rule that flags newly added dependencies in package.json or requirements.txt that use unpinned version constraints in specific path patterns (services that handle payments, authentication, cryptographic operations) is a code review automation use case that keeps supply chain risk decisions visible rather than implicit.
The internal code pattern as supply chain risk
Supply chain risk isn't only about what comes in from outside. Internal code patterns that weaken integrity controls create exploitable conditions for any supply chain compromise that does occur.
Disabling TLS certificate verification (verify=False in Python requests, NODE_TLS_REJECT_UNAUTHORIZED=0 in Node.js, InsecureSkipVerify: true in Go) is a pattern commonly introduced during development debugging and sometimes left in production code. It maps to CWE-295 (improper certificate validation). In a supply chain attack context, it means that a compromised dependency performing HTTPS requests won't detect a man-in-the-middle — the TLS handshake that should verify the server's identity is deliberately disabled.
Similarly, eval() usage in JavaScript, Python's exec() and eval(), and Ruby's eval/instance_eval patterns create code execution paths that a compromised module feeding data into those calls can exploit. CWE-94 (code injection) rules flag these patterns. Their presence in code review is a signal that the application has code execution sinks that amplify the impact of any data injection that reaches them — including injection from a compromised dependency.
We're not saying that every use of eval() is malicious or that TLS verification should never be conditionally disabled in test environments. We're saying these patterns deserve explicit review at the PR stage — a comment that says "this disables certificate verification, confirm this is not reaching production" is a cheap gate that prevents a class of deployment accidents that create supply chain attack surface.
Code review as integrity checkpoint
The supply chain security conversation often focuses on the perimeter — what enters the build via dependencies, registries, and build tooling. Code review is the interior checkpoint: the moment when patterns that undermine integrity controls, introduce exfiltration paths, or normalize dangerous practices are visible before they become part of the deployed system.
The tooling side of this is SAST rules for CWE-1321, CWE-798, CWE-295, CWE-94, and related patterns — deployed at the PR stage with enough specificity to flag the actual vulnerable patterns your codebase uses, not just textbook examples. The process side is a review culture that treats these findings as design decisions requiring explicit acknowledgment, not just bugs to fix before merge.
The dependency confusion and typosquatting vectors that get the most security attention are attacks that happen to your organization. The code patterns discussed here are risks that your engineers introduce — not maliciously, but because no one flagged them during review. That's the category where code review automation has the most value, because the detection point is exactly where the pattern is introduced, and the cost to change course is at its minimum.