OwnerTrail is a file integrity checker, SEO spam and malware scanner for WordPress. Every day it checks each core, plugin and theme file against the genuine release, reads any file the official checksums cannot vouch for, looking for the shapes malware takes, and requests your own pages as Googlebot to catch Japanese SEO spam: the keyword spam that shows search engines thousands of spam pages while you see a clean site. Every finding comes with plain steps: what it means, and what to do.
And who owns the plugins on your site today? Not who wrote them - who controls them right now, and who committed to them last week.
WordPress.org does not review plugin ownership transfers. When a plugin is sold, the new owner inherits commit access, their first release is unaudited, and nobody is notified. In April 2026 the WordPress Plugins Team closed 31 plugins at once after a single buyer acquired the portfolio through Flippa and planted hidden code across all of them. It had been sitting there since August 2025.
We replayed OwnerTrail's committer checks against the public commit history of those 31 plugins. Every one would have raised a high "new committer" warning, a median of 139 days before the hidden code switched on. The hidden code itself was in the official releases, so file checksums alone would not have caught it; the change of hands is the signal.
This is a known gap, not an accusation: WordPress meta ticket #5509, "Notify users of
changes to plugin ownership", is open and unresolved.
OwnerTrail reads the public
WordPress.org plugin directory and the public plugin SVN repository, builds a record of who has committed to each of your installed plugins, and tells you the moment that record changes.
You can do this by hand: open a plugin's directory page, read the listed author and contributors, open its SVN development log, and compare the committer names against what you saw last time. That works for one plugin, once. This does it for every plugin on your site, every day, and stays quiet until something actually changes.
What it detects
- Ownership change — the listed author or the contributor list changed.
- New committer — somebody with no prior history in that plugin has committed for the first time. This is the signal that precedes the attack.
- Dormant then active — a plugin silent for six months suddenly ships a release.
- Abandoned or withdrawn — no update in over a year, or removed from the directory entirely.
- Not monitorable — premium or custom plugins that wordpress.org knows nothing about, named honestly rather than quietly ignored.
The next update waits for you - free. While a plugin's change of owner or new committer is open, its next update is held - from the Update button, bulk updates, automatic updates, WP-CLI, and a zip uploaded over it alike - until you have looked and acknowledged the finding. A new controller's first release is the one most likely to matter, and in the 31 plugins compromised in 2025-26 the hidden code came 41 to 321 days after the new committer, so the hold lasts up to a year. No licence, no upgrade: it is part of the free plugin.
Each plugin gets a trust score from 0 to 100. Findings you have reviewed can be acknowledged, and plugins you do not care about can be muted, so the plugin stays quiet until something genuinely changes.
Is your code genuine?
Every day OwnerTrail compares WordPress core and every plugin from
wordpress.org with the official fingerprint of each file, and themes, other plugins, must-use plugins and drop-ins with the copy it first saw. A changed file, an unexpected PHP file (including any in the uploads folder) or a changed wp-config.php is reported on the Code screen and, when email alerts are on, emailed within the hour. Only file names are sent; wp-config.php's contents are never read into a finding or an email. Updates installed by WordPress itself never raise a finding. You can open areas to change (for example the theme while a developer works on it); changes there are noted quietly.
The files that run before WordPress does (wp-config.php, index.php, wp-load.php, .htaccess, .user.ini, a physical robots.txt or sitemap) are also read for the shapes a hidden loader takes: encoded code being run, a stylesheet or image loaded as PHP, another file run before every page, search engines sent somewhere visitors are not. That catches a loader planted before OwnerTrail was installed, which a comparison with the first copy cannot. A finding names the file, what was found and the line, never the content.
Matching the first copy is never taken as proof. Every file nothing vouches for (premium plugins, themes, must-use plugins, upload and language folders) is also read for the shapes malware takes: PHP or compressed data hidden in a font or image, a file that is both an image and PHP, decoded or form input being run, remote file-manager scripts, folders with dropper names such as
ext17395f, an
.htaccess that switches PHP back on, and names built to sit beside genuine ones. Every file in wp-admin, wp-includes and the WordPress root is compared with the official list whatever its extension, PHP anywhere in uploads, languages, fonts, upgrade or backup folders is reported, and a planted file with a back-dated time is named. A premium plugin or theme can be verified file by file against the vendor's own zip, uploaded on the Code screen: the zip is only read and fingerprinted, never unpacked or run, and deleted straight after. If the first full check finds anything serious, OwnerTrail says plainly that the site may already have been compromised before it was installed.
A plugin or theme that appears without being installed through WordPress, one named after another (such as "flavor-starter" beside "flavor"), and a file manager or migration tool being installed are serious findings. Installed themes that are not in use are listed: their code can still be run from the web.
A plugin you delete, in WordPress or over FTP, leaves every OwnerTrail screen at once. A folder left in the plugins directory with no plugin in it (what a failed delete or a cleanup can leave behind) is listed, and any code in it is a serious finding.
What search engines see
SEO spam hides from the site's owner: a visitor gets a "page not found" while Googlebot gets a page of spam. Once a day, and whenever you press Test now on the Code screen, OwnerTrail asks your own site for its front page, sitemap, robots.txt and a made-up page, once as a browser and once as Googlebot arriving from a Google search, and compares the answers. Only status codes, sizes and page titles are kept, never the pages. These requests go to your own site's address only.
Code lock
On activation, OwnerTrail locks WordPress's built-in plugin, theme and file editors for every user, administrators included. WordPress itself recommends turning these editors off, and code changes made through them are the most common way a site is quietly altered.
One click ("Only allow code changes over FTP", on the first-run report or the Code screen) also stops plugins and themes being uploaded, installed or deleted from the admin, including installs other plugins make through WordPress's installer. Updates of installed code keep running. A site owner (the administrator who activated OwnerTrail) can unlock for one hour; it relocks by itself. Deactivating OwnerTrail removes every lock.
The Code screen also lists installed plugins that can change code despite the lock (those that install code, run code stored in the database, or write into plugin and theme folders), so you can decide whether you need them.
What it does not do
It does not block or delay updates, and it is not a malware scanner: it tells you that code changed, not whether the change is malicious. It does not check for known vulnerabilities — use a dedicated vulnerability scanner alongside it. This plugin answers one question that those tools do not: who controls this code now?
It also cannot see a compromise that does not involve a change of ownership. In June 2026 ShapedPlugin shipped compromised Pro updates because its own build pipeline was breached; the committer record looked entirely normal throughout, and nothing here would have flagged it. Provenance monitoring answers one question well and is silent on the rest.
Licence and brand
The code is GPLv2 or later. Fork it, read it, ship it.
The OwnerTrail name, wordmark and logo are not covered by that licence and remain the property of
Decodeinfy. A fork is welcome; calling it OwnerTrail is not.
- Install through Plugins > Add New, or upload the folder to
/wp-content/plugins/.
- Activate it. Activation makes no network request and takes well under a second.
- Open OwnerTrail in the admin menu. The first scan runs in the background and builds a committer baseline for every installed plugin, ten at a time.
- Nothing is reported on that first pass - a baseline has nothing to compare against yet. Findings appear when something changes afterwards.
Optionally, turn on the email digest under OwnerTrail > Settings. It is off by default and sends nothing until you save a valid address.
1.3.7
Hosting security scanners no longer mistake OwnerTrail's own detection code for malware. What OwnerTrail detects is unchanged.
- Fixed: a host's malware scanner reported one of OwnerTrail's detection files as malicious, judging by its file name and by the way it listed the functions malware calls. OwnerTrail's files no longer contain the words and function names such scanners look for: the names its checks hunt for are kept as checksums, and its detection files have plain names.
- Checked before release with Microsoft Defender, php-malware-finder, the Neo23x0 signature-base rules and the Linux Malware Detect signatures, with no findings.
1.3.6
- New, and free: when a plugin changes owner or gains a new committer, its next update is held - Update button, bulk updates, automatic updates, WP-CLI, and a zip uploaded over it - until you acknowledge the finding, for up to a year. The plugin's row on the Plugins screen says why, with a link to review. Updates copied in over FTP, git or Composer are not held. With an active OwnerTrail Pro licence, Pro holds instead and adds approval of an exact version.
- Hardened before release by trying to get a held update through: an update manager or host proxy that fetches the package itself, a zip uploaded over the plugin, wp plugin install --force, Pro installed without a licence, and a takeover that waits longer than 90 days are all held.
- New: after two weeks and a finished check, OwnerTrail's own screens ask once for a review on WordPress.org. Dismiss it and it does not come back.
1.3.5
Background code checks now finish on large sites and slow hosts. Found by testing on a real site whose check could never finish.
- Fixed: checking a large plugin could take minutes (six for WordPress core on a slow disk), because every file was written back to the database on every check. Unchanged files are no longer rewritten and the rest are written in batches: the same check now takes seconds.
- Fixed: a large plugin is read in short slices, each going on where the last one stopped, so a server's time limit can no longer cut a check off part-way.
- Fixed: when the server did stop a check part-way, that plugin was dropped from the check and its old result stayed on the Code screen as if current, while the rest of the check waited until the next day. It is now checked again, a follow-up run is always scheduled, and the Code screen restarts a check an earlier version left stuck.
- Fixed: a plugin the server stops three times running is named on the Code screen as not checked, instead of quietly showing an old result.
- Fixed: uninstalling removes the code check's lock and progress records.
1.3.4
Hardening for shared hosting and a sharper eye for disguised code, from a security review focused on large sites and self-sabotage.
- Security: quarantine can never move the files a site cannot start without (wp-config.php, index.php, wp-load.php, wp-settings.php), the files WordPress ships in wp-admin and wp-includes, known firewall bootstraps, or OwnerTrail itself, whatever a check says.
- New: the code reader catches more disguised calls: a function named by a string pieced together and run on the spot, a name built by XORing two strings, a short-echo (<?=) tag hiding PHP in an image or font, and a .user.ini in any folder that runs a PHP file before every request.
- Fixed: a very large uploads folder (tens of thousands of files) is read in short time-slices and resumed where it stopped, instead of starting over and never finishing on a small host.
- Fixed: the search-engine cloaking check ignores nonces, cache-busters and tracking tags, so two fetches of the same page are not mistaken for cloaking.
- Fixed: a vendor zip is bounded (at most 15,000 files and 250 MB uncompressed) and the upload is always deleted after it is read.
1.3.3
This release hardens OwnerTrail against the ways a real user, or an intruder who already has an admin account, could break or silence it. Found by an adversarial review and a foothold (assume-breach) test.
- Security: only a site owner can now do the things that weaken what OwnerTrail watches: change settings, mute a plugin, acknowledge a finding, trust a vendor zip, mark code as expected, or reset. A second administrator can no longer quietly blind it.
- Security: the owners are emailed if OwnerTrail is switched off even when email alerts are off, and it is recorded.
- Security: code that hooks OwnerTrail's own filters or actions from elsewhere is flagged.
- Fixed: plugins whose folder name has capitals or underscores (some premium plugins) are now checked, not dropped and listed as leftovers to delete.
- Fixed: acknowledging a change no longer silences later edits to the same file.
- Fixed: changing a plugin's or theme's version line no longer hides a change; replacing a plugin from an uploaded zip is recorded.
- Fixed: an upgrade from an earlier version is no longer mistaken for a fresh install that "may already be compromised".
- Fixed: the code check cannot run twice at once; a very large uploads folder is read within a time budget; on a network only the main site checks the shared files.
- Fixed: an owner's one-hour unlock opens Code lock only for that owner; an owner demoted from administrator is no longer treated as one.
- Fixed: a changed file stays official and urgent when wordpress.org cannot be reached; the dashboard warns when scheduled checks have stopped.
- Fixed: a sitemap on the site's own subdomain is not mistaken for SEO spam elsewhere; files in code-free folders are read reliably on Windows hosts.
- Fixed: uninstalling on a multisite network cleans every site.
1.3.2
- Changed: new name, OwnerTrail - File Integrity Checker, SEO Spam & Malware Scanner. The name, description and tags now say what OwnerTrail does today: file integrity and security checks as well as plugin ownership monitoring.
1.3.1
- New: "What should I do?" under every finding, in plain words. When a change may have been yours, "Yes, that was us" marks it as expected in one click; anything that looks like malware never offers that.
- New: tick findings and acknowledge them together, with an optional note; "Acknowledge all" never includes malware.
- New: findings are graded Malware, Suspicious, Exposure and Note, and the same problem is listed once, with how many times it was seen.
- New: more malware shapes are caught: shell commands passed by name or kept in a variable, request data read through getenv, getallheaders, the raw request body or $GLOBALS, request names built at run time, code hidden in .php.bak and .php.jpg files, and code appended to the end of very large files.
- New: .maintenance, must-use plugins named like a host's, and allowed root files are read too.
- Changed: a changed file with no sign of malware in the change is medium, not high; a change with malware shapes is critical.
- Changed: the Overview and the notices give one count of findings to review, and say how many are important.
- Fixed: when wordpress.org's checksum service did not answer, every WordPress file was reported as changed.
- Fixed: plugins and themes installed through WordPress were reported as appearing without the installer.
- Fixed: a plugin whose first history lookup failed reported all its past committers as new.
- Fixed: a finding you acknowledged came back the next day while the file was unchanged; findings closed by an update to OwnerTrail's checks close themselves.
- Fixed: findings older than the retention period were deleted while still open, then raised again as new.
- Fixed: an urgent email held back by the one-hour gap was never sent; muted plugins no longer appear in it.
- Fixed: the daily digest skipped days when the scheduled task ran a little early.
- Fixed: a folder the web server cannot read no longer stops the code check.
- Fixed: files added while an area was open to change were not read.
- Fixed: themes whose folder name has capitals (Divi, Avada) can be verified against the vendor's zip and marked as expected.
- Fixed: many smaller display issues: filters kept after acknowledging, links for code findings, counts on the dashboard widget, site names in email subjects.
1.3.0
- New: matching the first copy is no longer taken as proof. Files nothing vouches for are read for the shapes malware takes: PHP or compressed data hidden in fonts and images, image/PHP polyglots, decoded or form input being run, remote file-manager scripts, dropper folder names, .htaccess files that switch PHP back on, lookalike file names.
- New: every file in wp-admin, wp-includes and the WordPress root is compared with the official list whatever its extension; unknown root files and hidden root folders are reported.
- New: PHP in uploads, languages, fonts, upgrade and backup folders is reported (translation files and empty index.php files excepted).
- New: start-up files (wp-config.php, index.php, wp-load.php, .htaccess, .user.ini, robots.txt, physical sitemaps) are read for hidden loaders, never shown.
- New: "What search engines see" asks your own site for a few pages as a visitor, as Googlebot and as a visitor from Google, to catch SEO spam that hides from the owner.
- New: verify a premium plugin or theme against the vendor's zip; wordpress.org themes are verified against their official zip.
- New: a plugin or theme that appears without WordPress's installer, lookalike package names, and file managers or migration tools being installed are reported; unused themes are noted; back-dated files are named.
- New: a deleted plugin leaves every OwnerTrail screen at once; folders left in the plugins directory with no plugin in them are listed.
- New: if the first full check finds anything serious, OwnerTrail says the site may already have been compromised before it was installed.
- Changed: every installed theme is now checked, not only the active one.
- Fixed: removing an unexpected file no longer reports it as missing.
1.2.0
- New: "Your site at a glance", a first-run report with next steps and one-click email alerts.
- New: the dashboard widget leads with the week's all-clear.
- New: optional weekly summary email (off by default).
- New: serious findings are emailed within the hour when email alerts are on.
- New: Scan now shows a progress bar and checks one plugin at a time.
- New: Code lock. The built-in code editors are locked on activation; one click also stops plugin and theme uploads, installs and deletes from the admin. Only a site owner can unlock, for an hour at a time.
- New: the code check also covers must-use plugins, drop-ins, loose PHP in wp-content and the site's configuration files, and lists the plugins that can change code despite Code lock.
- New: daily code integrity check. WordPress core and every directory plugin are compared with wordpress.org's official file fingerprints; themes and other plugins with the copy OwnerTrail first saw; PHP files in uploads are flagged. A change is named by file on the new Code screen and, outside the areas you open to change, emailed within the hour.
- New: a plugin wordpress.org has closed is flagged with the date and reason, even when it was closed before OwnerTrail was installed (it was shown as "not monitorable" before).
- New: when a plugin changes hands or is closed and WordPress would update it by itself, its page offers one click to turn auto-updates off, and the urgent email says so.
- New: when email alerts are on, the owners are emailed if OwnerTrail is switched off: who did it and when.
- Fix: a plugin removed since the last scan no longer counts in the Scan now progress or stays on the Code screen.
- Fix: "findings to review" no longer counts plugins that simply cannot be checked.
- New: beside a serious finding, a short note on what OwnerTrail Pro would have done about it (only while Pro is not installed; dismissible), and a line in the weekly summary when there is something to count.
- New: a code finding whose files are later put back as they were says so ("Since put back as it was"), and still waits for you to acknowledge it.
- Fix: editing a file again while an earlier change to it is still unacknowledged is now a new finding, not a silent repeat.
- Fix: uninstalling now also removes the per-user settings OwnerTrail stores.
- Fix: Hello Dolly, which ships with WordPress as hello.php, is read under its wordpress.org name, so its ownership is monitored instead of shown as "cannot be checked".
1.0.0