=== NyaxAgent — Malware Cleanup & Security Incident Response ===
Contributors: cerynth
Tags: security, malware, scanner, hacked, firewall
Requires at least: 6.6
Tested up to: 7.1
Requires PHP: 8.1
Stable tag: 0.6.2
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Other plugins tell you the site was hacked. This one gets you out of it — explained, reversible and verified.

== Description ==

Detection is the part the security market has solved. What follows is the part nobody productised: an hour of forensics across files, database, admin accounts, sessions, cron and traffic — usually at the worst possible moment, often unpaid.

NyaxAgent turns that into one explained, reversible, verified transaction: detect, explain, contain, clean, verify, keep watching.

= What it does =

* Records what changes on your site in a tamper-evident, hash-chained activity journal.
* Verifies WordPress core and repository plugins against their official checksums.
* Finds executable files where none belong, and known web-shell families by signature.
* Correlates separate findings into a single incident with a timeline, instead of a list of unrelated alerts.
* Proposes a containment plan you approve as a whole — every step reversible, with encrypted quarantine and one-click restore.
* Writes an incident report you can hand to the site owner or your client.

= What it will not do =

An honest security tool has to say where it stops looking.

* It is not a network firewall. Requests that never reach PHP are invisible to it.
* It cannot change PHP settings from inside WordPress. When the runtime configuration is dangerous, it says so and marks the finding as not reversible by the agent.
* It never claims a site is clean. The strongest verdict is "no signs of compromise", always printed with the coverage that produced it.
* Against an attacker with root on the server, no WordPress plugin is authoritative.

= Free, and what the subscription adds =

The whole detection and response engine is free and runs entirely on your own server, on as many sites as you like, with no account and no expiry. This is not a trial.

A paid plan does not unlock code that is already on your server. It gives your site access to things that can only happen somewhere else — which is the point: when a site is compromised and offline, anything running on it is worthless.

* An off-site copy of the evidence, so it survives the server it came from.
* An external liveness probe, so you are told when the site stops answering — or when the plugin is removed by an attacker.
* Email and Slack notifications, sent from outside the affected site.
* Signed rule bundles with new detection signatures.
* An AI second opinion on findings the deterministic rules cannot settle. It has no tools and cannot act: it may move a confidence score by at most ±0.25, and the plugin re-validates every answer and rejects it outright if it cites evidence that was not sent.

Plans and prices: https://cerynth.at/nyax

= Languages =

English, German (de_DE, de_AT, de_CH and the formal de_DE_formal). The plugin follows the site language set in Settings → General, or a user's own profile language.

Detector output — finding titles and the reasons behind them — stays in English on purpose. It is evidence text that is hashed and mirrored off-site, and it has to read identically everywhere so a record from one site can be compared with another.

== Installation ==

1. Upload the plugin through Plugins → Add New → Upload Plugin, or install it from the WordPress plugin directory.
2. Activate it. The first scan starts on its own and takes a few minutes on a typical site.
3. Open NyaxAgent in the admin menu to see the verdict and its coverage.

No account, no key and no configuration are required. Everything above runs locally.

To use a paid plan, paste the enrolment token from https://cerynth.at/nyax into NyaxAgent → Settings.

== Frequently Asked Questions ==

= Does NyaxAgent send my files anywhere? =

In Local Mode the only outbound requests are to WordPress.org's own checksum APIs, to verify your core and plugin files — your WordPress version, locale and installed plugin slugs, nothing more. In Connected Mode the site sends findings, file hashes, component versions and a hash-chained summary of its activity journal. File contents are only ever sent if you explicitly enable AI analysis in Settings → Privacy, and then only the excerpt belonging to a finding.

= Does it work alongside Wordfence, Sucuri or a host firewall? =

Yes, and that is the intended setup. Those detect and block. NyaxAgent takes over after the alarm.

= What happens when a subscription ends? =

The site returns to Local Mode. Scanning, integrity checks, the journal, quarantine and manual containment keep working unchanged. Only the off-site parts stop.

= Is my WordPress password or login involved? =

No. The site identifies itself with a key pair generated on your own server during enrolment. No WordPress credential is ever transmitted.

= Which WordPress and PHP versions are supported? =

WordPress 6.6 and newer, PHP 8.1 and newer. The plugin has no runtime Composer dependencies.

== External services ==

NyaxAgent contacts WordPress.org to verify your files, and — only if you subscribe — one service operated by the plugin author. Both are listed below.

= 1. WordPress.org checksum APIs =

**Endpoints:** https://api.wordpress.org/core/checksums/1.0/ and https://downloads.wordpress.org/plugin-checksums/
**Operated by:** the WordPress.org project. Terms: https://wordpress.org/about/privacy/

Used by the integrity check to compare your files against the official published checksums, which is how the plugin can tell a modified core file from an untouched one. This happens in Local Mode as well, because the integrity check is a free local feature.

What is sent: your WordPress version and locale as query parameters, and the slug and version of each installed repository plugin as part of the request path. Nothing else — no file contents, no site URL, no user data. Responses are cached for six hours.

= 2. NyaxAgent Control Plane (only in Connected Mode) =

**Endpoint:** https://api.cerynth.at
**Operated by:** CERYNTH Technologies GmbH, Bahnhofstraße 55, 9020 Klagenfurt am Wörthersee, Austria (Firmenbuch FN 687440t, UID ATU83661707)
**Terms:** https://cerynth.at/nyax
**Privacy policy:** https://cerynth.at/datenschutz

When, and what is sent:

* **On enrolment,** once you paste a token: the site URL, the public half of a key pair generated on your server, and the plugin version. This is what links the site to your subscription.
* **On each heartbeat,** roughly every few minutes while connected: findings (rule id, severity, confidence, affected path), file hashes, installed component versions, and a hash-chained summary of the activity journal. No file contents.
* **When you enable AI analysis** in Settings → Privacy, which is off by default: the excerpt of a file belonging to a finding is additionally sent, so the model can judge it. The excerpt is scrubbed of values that look like secrets before sending. This feature can be switched off again at any time, and the plugin works fully without it.
* **For the external liveness probe,** the service requests a single public URL of your site on a schedule, the same way any visitor would.

Local Mode is the default after installation and contacts this service not at all: no connection is made until you paste an enrolment token. Disconnecting returns the site to Local Mode.

No WordPress password, user password or session token is transmitted to either service, in any mode.

== Screenshots ==

1. The verdict, with the coverage that produced it — including what could not be checked.
2. An incident: separate findings correlated into one timeline.
3. The containment plan, reviewed and approved as a whole before anything runs.
4. The activity journal, hash-chained so removed entries are detectable.

== Changelog ==

= 0.6.2 =
* Fixed: after an update, the build-integrity badge showed the version of the build that was installed *before* the update. On a site updated from an older release it read "Version 0.3.0" under 0.6.1 — a wrong answer in the one place that exists to say which build is installed. The version shown is now always the one that is running.
* Fixed: a stored result from a previous version is no longer used to judge the current one, in either direction. It cannot show green, and it cannot raise an alarm about files it never examined. The honest state after an update is "not verified yet", until it has been.
* New: activating or updating NyaxAgent now verifies the build straight away, at the highest priority, instead of waiting for the next scheduled check. A security indicator that says nothing for an hour after installation is reasonably read as suspicious rather than reassuring.

= 0.6.1 =
* New: every NyaxAgent screen now carries a build-integrity indicator in its header. It says whether the plugin files on this site are the ones we signed and published — green only when the release signature is valid, every file in the signed manifest was found and matched, no unexpected PHP file sits in the plugin directory, and the check is recent.
* A valid signature on its own is never shown as green. The manifest is a file like any other; an attacker able to rewrite the plugin could leave it untouched. The files have to be compared against it, and a check that did not reach every file is reported as inconclusive rather than clean.
* A result that has gone stale turns grey instead of staying green. "It was fine yesterday" is not an answer to "is it fine now".
* "Verify now" runs a fresh check on request. It needs administrator rights and a valid nonce, and it is rate-limited, because the check walks every file in the package.
* The indicator describes installed build integrity, not the safety of the website. It says nothing about WordPress core, your other plugins, your theme or your server — and it states plainly that a fully compromised WordPress can falsify its own interface, including this badge.

= 0.6.0 =
* The firewall now has a screen. You can see whether it is actually blocking requests, monitoring them, or doing nothing — and switch between blocking and monitoring yourself, instead of needing the command line. It will not show "blocking" when enforcement is unavailable, and an upgrade never silently turns blocking on for a site that did not have it.
* Fixed, and this one mattered: requests to the WordPress REST API were not checked against rules written for "any request surface". A site reporting that it was blocking attacks returned 200 to a path-traversal attempt over REST.
* NyaxAgent now looks for PHP payloads stored in the database — in post content, drafts, revisions, custom fields, Elementor data, options, oEmbed caches and metadata rows whose post no longer exists. It reads them; it never runs them. Where a payload names a file it was trying to create, that filename is reported with it. Finding a stored payload is not evidence that it ever ran, and NyaxAgent says so rather than implying otherwise.
* The site now has a record of where it loads JavaScript from, and tells you when a new destination appears. Destinations seen before that record existed are listed as "not reviewed yet" rather than treated as fine — on a site that was already compromised, the injected one is in that list too.
* Theme files are now compared against a reference, with a screen for reviewing what changed. WordPress.org publishes file checksums for WordPress core and for plugins but not for themes, so the comparison is against a reference recorded on your own site. That is said on the screen rather than left to be assumed, and a theme nobody has reviewed is reported as unknown, not as clean.
* Fixed: a refused sign-in could still reach a password check belonging to another authentication plugin — an LDAP, SSO or directory plugin. The sign-in was denied, but the attacker still got a credential check per request, and against a remote directory that is a way to lock the account out at the far end. A refusal now stops the whole chain for that attempt and restores it afterwards, so other authentication plugins keep working.
* Request bodies are now inspected, not only query parameters: form data, JSON, XML, SOAP and XML-RPC. This is detection only for now — a request body legitimately contains code often enough that blocking on it needs more evidence first.
* Fixed: reviewing a theme recorded whatever was on disk at that moment, so a file planted after the screen was drawn could be approved without ever being shown. A review now refuses if the files changed after you looked at them.
* The activity journal no longer calls itself "tamper-evident" when its only copy is on the server it is protecting. It says it is internally consistent, and what that does and does not establish. Connect an account to keep a copy off-site.
* Fixed: NyaxAgent stayed quiet if it could not read its own sign-in counters. It still lets people sign in — a protection that breaks must not lock you out — but it now records that it could not assess the attempt, instead of reporting healthy protection while refusing nothing.

= 0.5.0 =
* Alerts now actually arrive. Paid plans send incident notifications by email through a transactional provider, with retries, and a record of what was delivered and what was not. Previously an email could be reported as sent without anything leaving the building.
* You are now told when a site stops reporting at all — detected from outside the site, so it does not depend on the site being healthy. That is the case the external check exists for, and it could not previously reach anybody.
* Suspending an account, signing everyone out, deleting an account and rotating the site keys now always ask for your password first, in every mode. NyaxAgent will not do any of them on its own.
* NyaxAgent refuses to lock out an account if nobody else could actually sign in afterwards. It checks whether the remaining administrators have a usable password or an address a reset could reach, rather than just counting them — and refuses if it cannot establish that.
* The command line can no longer approve those actions. Quarantine and hardening still work there.
* Fixed: a site served over plain http had its post-containment health check counted as a failure, which rolled the containment back and put a quarantined file back into the web root. A check that cannot run is now reported as "not verified" rather than as "broken".
* Every screen, the approval dialog and the exported report now give the same answer about what a step can undo, with what it cannot restore listed separately.
* The change journal is now bounded: at least seven days, with security events kept regardless of age, the hash chain still verifiable, and any trimming recorded inside the chain itself.
* Fixed: with no vulnerability data source connected, the screen showed a count of zero. It now says plainly that the check did not run.

= 0.4.6 =
* Fixed: the containment plan arrived with "sign out every administrator and editor" already ticked. Nothing that changes who can get into your site, and nothing that cannot be undone, is ever selected for you now — you choose it deliberately.
* Each step now says exactly what undoing it would restore, what it would not, and what that depends on. Suspending an account puts back its role, its password and its application passwords; it does not put back its sessions, and the step says so instead of calling itself reversible.
* Fixed: rotating the site's security keys was described as undoable. It restores wp-config.php; the sessions it signed out are gone, and that is now stated.
* Fixed: an administrator account was described as "a known administrator before the incident" when all that was known is that it existed when NyaxAgent was installed. On a site that was already compromised then, an intruder's account looks identical. Accounts are now described as observed or as confirmed by a person, which are different things, and neither is presented as proof the account belongs there.
* The plan now lists the steps you have selected by name rather than only counting them, shows the risk of your selection rather than of the whole plan, and will not submit a selection you cannot see.
* Before anything runs, the confirmation names every step, its target, its risk and everything about it that cannot be undone, and asks you to acknowledge the irreversible parts separately from entering your password.

= 0.4.5 =
* Fixed: activating NyaxAgent started a full scan of every file on the site before you had seen a single screen. The first scan now waits until you ask for it.
* Fixed: during a scan the screen could show "Scanning…", a live file count and "Scan queued — it starts within a minute." at the same time. Scan status now comes from one place, so the text, the button and the progress bar agree.
* Fixed: findings about a file — including detected web shells — said that what you did could be undone from the WordPress trash. Quarantining a file has nothing to do with the WordPress trash, and putting a web shell back is not a safe suggestion. Each finding now states what, if anything, actually reverses it, and says nothing rather than implying a way back that does not exist.
* A finding whose detector does not state that it can be undone is no longer presented as reversible.

= 0.4.4 =
* Fixed: a scan could fail outright on a site containing a file whose name is not valid UTF-8 — common on older European hosting and on compromised sites. Such names are now stored readably, with the exact original bytes preserved alongside so nothing is lost.
* A single unreadable file can no longer end a scan. The scan finishes and reports how many files it could not examine.
* Fixed: opening the NyaxAgent screen started a full scan nobody had asked for. The first scan now requires pressing the button.
* Fixed: on a site whose scans kept failing, every admin page load queued another scan. Scanning now backs off from the last attempt rather than the last success.

= 0.4.3 =
* Fixed: a full scan could abort before finishing if the site contained an unusually long or malformed plugin entry, and then abort again on every retry. Overview kept reporting "last scan: never" while nothing was ever scanned.
* A single check that fails can no longer end the whole scan. The scan finishes, and says which check it had to skip.
* Overview now distinguishes never scanned, queued, running, completed, completed with gaps, and failed — with the reason when a scan fails. "Last scan" no longer implies a scan succeeded.
* Existing findings stay visible, and are no longer presented as the result of a completed scan when the last scan did not complete.

= 0.4.2 =
* NyaxAgent now tells you when a new version exists. Updates appear in WordPress like any other plugin's, instead of never appearing at all.
* An update is installed only if it is signed by Cerynth's release key. A package that is unsigned, signed by anyone else, or altered after signing is refused and nothing is replaced — the download is not trusted, the signature is.
* Note for existing installations: this only works from 0.4.2 onwards. A site on 0.4.1 or older has to be updated by hand once, after which updates arrive on their own.

= 0.4.1 =
* Reports a PHP version that no longer receives security fixes, or is about to stop. NyaxAgent already showed your PHP version; now it tells you what it means.
* Where a version missed the critical PHP fixes of 21 October 2026, the finding says so explicitly.
* A future release will require PHP 8.3. This version still runs on 8.1 so that sites on older PHP are told before updates stop reaching them.

= 0.4.0 =
* Page backups: take an encrypted copy of a single page on request. It reads the page and never changes it.
* Backup review: see exactly what restoring a page from a backup would change — field by field, including the custom fields, categories and password — before anything is decided.
* Choose between backups: where several usable backups disagree about what a page should say, you pick, and the record says you did.
* Restoring a page is NOT available in this release. The review is complete and the restore is disabled.
* A runtime off switch for content changes, disabled by default.

= 0.3.0 =
* Public release.
* Incident correlation: related findings are grouped into a single incident with a timeline.
* Containment as a reviewable transaction, with encrypted quarantine and restore.
* Signed release manifest; the plugin verifies its own files against it.
* Independent must-use loader, so removing the plugin does not silence it.
* Optional AI second opinion on undecidable findings, off by default.

= 0.1.0 =
* Foundation release: local and connected modes, cryptographic site identity, integrity scan, filesystem detectors, activity journal, admin dashboard.

== Upgrade Notice ==

= 0.4.4 =
Fixes scans failing on sites with unusual filenames, and stops the first scan starting on its
own. Recommended for every installation, especially any where scans have been failing.

= 0.4.3 =
Fixes a scan that could fail silently on damaged sites and always report "last scan: never".
Recommended for every installation.

= 0.4.2 =
Adds self-updating, verified against Cerynth's release signature. Update this one by hand;
from here on NyaxAgent will tell you itself when there is a new version.

= 0.4.1 =
Adds a check for unsupported PHP versions. If this site runs PHP 8.1 or older it will now say
so, and why it matters: those versions did not receive the critical PHP security fixes of
21 October 2026. Restoring a page remains unavailable.

= 0.4.0 =
Adds page backups and backup review. Restoring a page remains unavailable: this release can show
you exactly what a restore would change, and cannot carry it out. Existing data is preserved.

= 0.3.0 =
First public release. Existing local data, quarantine and journal are preserved.
