Eager autoloaded files run as soon as vendor/autoload.php is required, so a poisoned tag can execute before any application logic or class loading occurs. That turns a routine composer update or fresh install into a code execution event. Security teams should treat tag integrity, lockfile provenance, and autoload.files entries as part of the software supply chain trust boundary.
Why This Matters for Security Teams
This failure mode matters because it collapses the normal assumption that dependency installation is passive. If a Composer package uses eager autoloaded files, code from that package can run before application safeguards, feature flags, or request handling ever begin. A force-pushed tag turns source integrity into an execution question, not just a versioning issue. That is why supply chain controls need to cover tag provenance, lockfile integrity, and release discipline together, consistent with NIST SP 800-53 Rev 5 Security and Privacy Controls.
The usual mistake is to treat composer update as a controlled maintenance task when, in reality, it may be the first execution of untrusted code. Eager autoloaded files are especially risky because they run before the application has a chance to validate configuration, enforce authentication, or initialise monitoring. A malicious commit attached to a moved tag can therefore convert a routine deployment into a supply chain compromise with very little operator interaction.
In practice, many security teams encounter this only after an unexpected package change has already been pulled into CI or production rather than through intentional provenance checks.
How It Works in Practice
Composer resolves the package version from the tag, then installs dependencies and generates the autoloader. If the package defines files under autoload.files, those files are included as soon as vendor/autoload.php is required. That means the code path is not dependent on a class being instantiated or a route being hit. If the tag was force-pushed to a malicious commit, the build can execute attacker-controlled logic even when the application never explicitly calls into that package.
This is why the risk is broader than a malicious library method. The trigger is the trust relationship between package metadata, tag history, and autoload behaviour. The safer posture is to verify that the referenced tag still points to the expected commit, pin dependencies with a lockfile, and limit which packages are allowed to execute code at bootstrap. Supply chain integrity guidance from the OWASP Software Supply Chain Security Risks and dependency governance practices from GitHub supply chain security guidance both reinforce the same operational point: trust should be explicit, not implied by a tag name.
- Compare tag hashes against a known-good source of truth before build promotion.
- Treat composer.lock as a provenance artifact, not just a reproducibility aid.
- Review autoload.files usage as part of dependency risk assessment.
- Restrict CI and release pipelines so unexpected package changes trigger review.
- Monitor for newly introduced bootstrap code in third-party dependencies.
These controls tend to break down when teams install from mutable refs, mirror repositories without commit verification, or allow unsigned package releases into automated build pipelines because the tag name is treated as sufficient assurance.
Common Variations and Edge Cases
Tighter dependency verification often increases release friction, requiring organisations to balance developer speed against provenance assurance. That tradeoff is especially visible in fast-moving PHP projects where patch releases are frequent and teams rely on tags for convenience. Current guidance suggests that mutable release references should be treated as high risk, but there is no universal standard for how much validation is enough in every environment.
Some environments can reduce exposure by avoiding autoload.files entirely for third-party packages, but that is not always practical. Others may rely on internal package registries, artifact signing, or controlled mirrors to reduce the chance that a public tag change reaches production. The key distinction is whether the build consumes immutable artefacts or live source references. If the supply chain allows tag retargeting, provenance checks must happen before dependency resolution, not after.
For teams operating in regulated or high-assurance contexts, the relevant question is not just whether the code compiles. It is whether the dependency graph can be trusted to remain the same between review, build, and deployment. That is where NIST Cyber Supply Chain Risk Management guidance becomes practical: identify trust boundaries, verify source integrity, and assume bootstrap-time code can be the first point of compromise.
Best practice is evolving, but one point is settled: if a package can execute during autoload, then dependency review must include execution context, not just code content.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
MITRE ATT&CK and OWASP Agentic AI Top 10 address the attack and risk surface, while NIST CSF 2.0 and NIST AI RMF set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| NIST CSF 2.0 | GV.SC-1 | Supply chain risk governance applies to mutable package tags and trusted build inputs. |
| NIST AI RMF | AI RMF is relevant where supply chain automation and code-generating systems inherit untrusted inputs. | |
| MITRE ATT&CK | T1195.001 | Compromised supply chain code delivery matches malicious dependency insertion patterns. |
| OWASP Agentic AI Top 10 | Autonomous build and release agents can amplify trust in poisoned package inputs. |
Map package ingestion paths to supply chain attack techniques and add detections for altered artefacts.
Related resources from NHI Mgmt Group
- What breaks when a malicious package can use a GitHub token to exfiltrate files?
- What breaks when malicious code hides in build and config files instead of package hooks?
- What breaks when a malicious Python package uses startup hooks instead of a normal import path?
- What breaks when a malicious npm package can read developer secrets during install?