Security & Module Risk

Magento 2 Core File Integrity Checks on 2.4.x

Magento 2 has no built-in checksum tool. Here is the diff-against-clean-install method we use to catch hand-edited vendor code during an audit.

Jason Schuman · December 1, 2025

Core code that has been hand-edited is no longer core code

Every Magento 2.4.x store installs its core code through a tool called Composer into a directory called vendor/magento/*. That code is supposed to stay untouched between updates: you upgrade it, you patch it, but you never open a file inside vendor/magento/module-checkout and change a line by hand.

In practice, hand-edited core files still show up in stores we check.

This article shows you how to check for it directly, without guessing based on version numbers or update notes.

An illustration showing Vendor Code validation

Why "integrity" means something specific here

Magento 2 does not come with a built-in file checker the way Magento 1 did. There is no bin/magento core:file:verify command.

What you have instead is a Composer install that is fully reproducible. Every package version listed in composer.lock matches an exact, publicly available set of files.

So the integrity check comes down to a diff. The question is whether your live store matches a fresh Composer install of the same version and patch level.

If a file inside vendor/magento is different from a clean install of the same package version, someone edited core code directly. There is no other explanation.

The diff-against-clean-install method

This is the approach we use during a deep-dive audit, and it works the same way on any 2.4.x store.

  • Find the exact version string with composer show -a magento/product-community-edition (or magento/product-enterprise-edition).
  • In a temporary directory, run a clean Composer install pinned to that exact version and the same composer.lock if you have it.
  • Run diff -rq vendor/magento production/vendor/magento to diff the clean install against your live store.
  • Every file the diff flags is worth reviewing. It either changed in an official patch you missed, or someone modified it directly.

A full diff of the entire vendor/ directory is noisy the first time you run it. Narrow it to vendor/magento first, since that is where direct core edits do the most damage.

What to exclude before you trust the results

Not every difference is tampering. Build files and generated code will always differ between a clean install and a running store.

Exclude these directories from the diff entirely:

  • generated/code and generated/metadata, because helper files are built automatically at compile time
  • pub/static, because it contains deployed static content like CSS and JavaScript
  • var/, because it contains cache, session, and log data
  • any file with a modified date older than the current package version, which usually just means your server preserved file dates during a deployment

Once those are out of the picture, whatever remains inside vendor/magento/module-* is worth reading line by line.

What agency hand-offs actually look like on disk

The most common pattern is not malware. It is a developer under deadline pressure who needed to change checkout or shipping behavior and opened the core file instead of writing a proper plugin.

That edit works until the next composer update. Composer has no record of the hand edit, so it overwrites the file with the official package version.

The store then breaks in production with no matching code change in version control, because the "fix" never existed anywhere Git could see it.

Direct core edit

A line inside vendor/magento/module-sales/Model/Order.php was changed by hand. Invisible to git log if the vendor directory is excluded from version control, and wiped out on the next Composer update.

Missed proper override

The correct fix was a plugin or preference in a custom module. It was skipped because it takes longer to set up than opening the file directly.

Injected backdoor

A single hidden line added to pub/index.php or a core startup file after a stolen admin password or unpatched extension.

Disguised file drop

A PHP file placed in pub/media with an image-like name. Diffing vendor/magento will not catch this, so check writable upload directories separately.

Automated checks worth running alongside the manual diff

The manual diff is the ground truth, but two automated tools catch different kinds of problems and take minutes to run.

Magento Security Scan Tool (magento.com/security/tools/scan) checks your public store URL against a database of known malware signatures and disclosed core vulnerabilities. It will not see hand-edited files that don't match a known pattern, but it is free and catches the break-ins that follow a documented method.

Composer audit checks your composer.lock for installed packages with disclosed CVEs. Run composer audit with Composer 2.4 or later. This checks known vulnerabilities in dependency versions, not file-level tampering, so treat it as a separate signal from the diff.

Neither tool replaces the diff. They cover known threats; the diff catches anything unique to your store.

An illustration of Core code that has been hand-edited is no longer core code

What this means for a 2.4.x store you did not build from scratch

If you inherited a store through an agency hand-off, an acquisition, or years of contractor turnover, you cannot assume vendor/magento matches what Composer thinks it installed. The only way to know is to diff it.

Run the diff once as a baseline, then again after every core upgrade and every security incident. It takes an afternoon and it answers a question that otherwise sits as an open assumption in your platform's risk profile.

Knowing whether your core files match what Composer says you installed is the first fact in any real security review. Patch timing, extension review, and access control all depend on that fact being true.