{"id":397740,"date":"2026-11-06T10:40:32","date_gmt":"2026-11-06T10:40:32","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/after-hack-checklist\/"},"modified":"2026-11-06T10:40:17","modified_gmt":"2026-11-06T10:40:17","slug":"aftersweep","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/aftersweep\/","author":23585415,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.1.0","stable_tag":"0.1.0","tested":"7.1.4","requires":"6.8","requires_php":"7.4","requires_plugins":null,"header_name":"Aftersweep \u2013 After-Hack Checklist","header_author":"timaub","header_description":"Read-only checklist after a hacked WordPress site was repaired: lists what differs from the official references, what to identify, and what was not looked at.","assets_banners_color":"313f58","last_updated":"2026-11-06 10:40:17","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/timaub.fr\/after-hack-checklist\/","header_author_uri":"https:\/\/timaub.fr\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":138,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.1.0":{"tag":"0.1.0","author":"timaub","date":"2026-11-06 10:40:17","revision":3787696}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3787687,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3787687,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3787687,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3787687,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["0.1.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3787687,"resolution":"1","location":"assets","locale":"","width":1280,"height":340},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3788015,"resolution":"2","location":"assets","locale":"","width":1280,"height":1621},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3788015,"resolution":"3","location":"assets","locale":"","width":1280,"height":369},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3787687,"resolution":"4","location":"assets","locale":"","width":1280,"height":567}},"screenshots":{"1":"Tools &gt; Aftersweep before the first check: reference date, checksum download checkbox with what it sends, and the \"Run the check\" button.","2":"A report on a test site with planted hacks: the counts at the top, then the first controls, each finding with its level, object, what it was compared to and what you can check.","3":"The \"Not looked at\" section: what the check did not compare or read, and why.","4":"The optional Pro add-on: \"Changed since the snapshot\" lists the files, administrator accounts and options added or modified since the reference snapshot."}},"plugin_section":[],"plugin_tags":[8533,153575,7900,18591,600],"plugin_category":[54],"plugin_contributors":[287499],"plugin_business_model":[],"class_list":["post-397740","plugin","type-plugin","status-publish","hentry","plugin_tags-audit","plugin_tags-checksums","plugin_tags-hacked","plugin_tags-read-only","plugin_tags-security","plugin_category-security-and-spam-protection","plugin_contributors-timaub","plugin_committers-timaub"],"banners":{"banner":"https:\/\/ps.w.org\/aftersweep\/assets\/banner-772x250.png?rev=3787687","banner_2x":"https:\/\/ps.w.org\/aftersweep\/assets\/banner-1544x500.png?rev=3787687","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/aftersweep\/assets\/icon-128x128.png?rev=3787687","icon_2x":"https:\/\/ps.w.org\/aftersweep\/assets\/icon-256x256.png?rev=3787687","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/aftersweep\/assets\/screenshot-1.png?rev=3787687","caption":"Tools &gt; Aftersweep before the first check: reference date, checksum download checkbox with what it sends, and the \"Run the check\" button."},{"src":"https:\/\/ps.w.org\/aftersweep\/assets\/screenshot-2.png?rev=3788015","caption":"A report on a test site with planted hacks: the counts at the top, then the first controls, each finding with its level, object, what it was compared to and what you can check."},{"src":"https:\/\/ps.w.org\/aftersweep\/assets\/screenshot-3.png?rev=3788015","caption":"The \"Not looked at\" section: what the check did not compare or read, and why."},{"src":"https:\/\/ps.w.org\/aftersweep\/assets\/screenshot-4.png?rev=3787687","caption":"The optional Pro add-on: \"Changed since the snapshot\" lists the files, administrator accounts and options added or modified since the reference snapshot."}],"raw_content":"<!--section=description-->\n<p>Your site was hacked. You ran a scanner, deleted what it reported, and now you wonder what else to look at. Aftersweep \u2013 After-Hack Checklist goes through ten places where a hack usually leaves traces and tells you, item by item, what it found and what it compared it to. It also tells you what it did not look at.<\/p>\n\n<p>It never says \"your site is fine\". It lists findings, each with a level:<\/p>\n\n<ul>\n<li><strong>Anomaly<\/strong>: a proven difference from a reference (a core file whose checksum differs from WordPress.org's, a PHP file in the uploads folder).<\/li>\n<li><strong>Suspect<\/strong>: a pattern often left by hacks that also has legitimate uses (a script in a widget option, an administrator created after your reference date).<\/li>\n<li><strong>To identify<\/strong>: something you have to recognise yourself (a must-use plugin, a drop-in, a page modified since your reference date).<\/li>\n<\/ul>\n\n<p>At the top of the report: \"N anomalies, N suspects, N to identify, N points not looked at\". For each finding, the report says what you can check by hand or show to your host.<\/p>\n\n<p>The plugin changes nothing on your site. It does not delete, move or edit any file, user, content or setting. It only writes its own options and transients (names starting with <code>ahcl_<\/code>).<\/p>\n\n<h4>The ten checks<\/h4>\n\n<ol>\n<li><strong>WordPress core<\/strong>: files in the root, <code>wp-admin\/<\/code> and <code>wp-includes\/<\/code> compared to the official checksums of your WordPress version and package language; unknown files in <code>wp-admin\/<\/code> and <code>wp-includes\/<\/code>; extra PHP files in the root; suspicious code in <code>wp-config.php<\/code>.<\/li>\n<li><strong>Plugins<\/strong>: each plugin from WordPress.org compared to the checksums WordPress.org publishes for its version; PHP files that are not in those checksums.<\/li>\n<li><strong>Uploads<\/strong>: PHP files in <code>wp-content\/uploads\/<\/code> (including names like <code>photo.php.jpg<\/code>), files that start with PHP code whatever their extension, <code>.htaccess<\/code> and <code>.user.ini<\/code> files.<\/li>\n<li><strong>Must-use plugins and drop-ins<\/strong>: every file in <code>mu-plugins\/<\/code> and every drop-in, with its header, size and date; other PHP files at the top of <code>wp-content\/<\/code>.<\/li>\n<li><strong>Administrators<\/strong>: users with administrator-level capabilities, those created after your reference date, capabilities granted outside the role, administrator rights given to a user ID that does not exist.<\/li>\n<li><strong>.htaccess and PHP settings<\/strong>: redirects to another site, rules that show a different page to search engines or bots, rules that make non-PHP files run as PHP, <code>auto_prepend_file<\/code> and <code>auto_append_file<\/code>, external error pages.<\/li>\n<li><strong>Content<\/strong>: posts and pages created or modified since your reference date, and content containing scripts, external iframes or encoded JavaScript.<\/li>\n<li><strong>Scheduled tasks (cron)<\/strong>: tasks whose code lives in the uploads folder or outside WordPress and your active plugins and theme, tasks with encoded arguments, tasks with no code attached.<\/li>\n<li><strong>Settings<\/strong>: site and home addresses, open registration with a powerful default role, active plugins that WordPress cannot find, scripts stored in autoloaded options, widgets and theme settings.<\/li>\n<li><strong>Not looked at<\/strong>: always present, never empty (see below).<\/li>\n<\/ol>\n\n<h4>What it does not look at<\/h4>\n\n<p>The report always ends with this list, so you know where it stopped:<\/p>\n\n<ul>\n<li>Themes: WordPress.org publishes no checksums for themes.<\/li>\n<li>Plugins with no published checksums (premium plugins, plugins not or no longer on WordPress.org, versions without checksums), each one named.<\/li>\n<li>Core and plugin files when checksums could not be downloaded, with the reason (box not ticked, network error, no checksums for your version or language).<\/li>\n<li>Database tables that do not belong to WordPress.<\/li>\n<li>Comments.<\/li>\n<li>Files outside the WordPress folder.<\/li>\n<li>Server configuration (nginx, your hosting panel).<\/li>\n<li>Other sites on the same hosting account.<\/li>\n<li>Other sites of a multisite network: only the main site is read.<\/li>\n<li>When a role was changed: WordPress does not record it.<\/li>\n<li>The limits of the pass: unreadable files (counted, the first 50 listed), files over 5 MB not read, folders not walked through.<\/li>\n<li>Files over 32 MB at the site root, in <code>wp-admin<\/code>, <code>wp-includes<\/code> and the plugin folders: not compared to the checksums (counted, the first 50 listed).<\/li>\n<li>Folders of <code>wp-content<\/code> that no check covers (<code>languages<\/code>, <code>cache<\/code>, <code>upgrade<\/code>, backup folders...): each one that holds PHP files is listed with its number of PHP files.<\/li>\n<li>Folders at the site root that are not part of WordPress: their PHP files are not compared to anything. Each folder is listed as \"to identify\" with its number of PHP files; a PHP file in <code>.well-known<\/code> or <code>cgi-bin<\/code> is reported as suspicious.<\/li>\n<\/ul>\n\n<h4>Checksums from WordPress.org: off until you tick the box<\/h4>\n\n<p>Checks 1 and 2 need the checksums published by WordPress.org. The plugin downloads them only if you tick \"Download the checksums from api.wordpress.org and downloads.wordpress.org\" next to the \"Run the check\" button. The box is unticked the first time; your choice is remembered. Unticked, checks 1 and 2 are listed under \"not looked at\". Details in the FAQ and in the Privacy section.<\/p>\n\n<h4>Privacy<\/h4>\n\n<ul>\n<li>No tracking, no analytics, no data sent to the plugin author.<\/li>\n<li>External requests only if you tick the checksum box, and only to api.wordpress.org and downloads.wordpress.org (see the FAQ for what they receive).<\/li>\n<li>The plugin stores only its own data: the state of the current pass, the last report (both not autoloaded), your checkbox choice, and the downloaded checksums for 24 hours. The last report contains file paths, usernames, post titles and short extracts of the suspicious values found on your site; it stays in your database.<\/li>\n<li>Only users who can manage options (<code>manage_options<\/code>; on multisite, network administrators) can open the page.<\/li>\n<\/ul>\n\n<h4>Pro add-on<\/h4>\n\n<p>An optional, separate Pro plugin adds a reference snapshot with a \"changed since\" section, scheduled re-checks by e-mail, and a printable HTML export. This free plugin is complete on its own: nothing in it is time-limited or locked. Details: https:\/\/timaub.fr\/after-hack-checklist\/<\/p>\n\n<h4>Fran\u00e7ais<\/h4>\n\n<p>Votre site a \u00e9t\u00e9 pirat\u00e9. Vous avez pass\u00e9 un scanner, supprim\u00e9 ce qu'il signalait, et vous ne savez pas quoi regarder d'autre. Aftersweep \u2013 After-Hack Checklist passe en revue dix endroits o\u00f9 un piratage laisse d'habitude des traces. Pour chaque point, il dit ce qu'il a trouv\u00e9 et \u00e0 quoi il l'a compar\u00e9, puis ce qu'il n'a pas regard\u00e9.<\/p>\n\n<p>Il ne conclut jamais que tout va bien. Chaque constat a un niveau : <strong>anomalie<\/strong> (\u00e9cart prouv\u00e9 \u00e0 une r\u00e9f\u00e9rence, par exemple un fichier du c\u0153ur dont la somme de contr\u00f4le diff\u00e8re de celle de WordPress.org), <strong>suspect<\/strong> (motif fr\u00e9quent dans les piratages mais qui a aussi des usages normaux, par exemple un script dans un widget), <strong>\u00e0 identifier<\/strong> (\u00e9l\u00e9ment que vous seul pouvez reconna\u00eetre, par exemple un mu-plugin ou une page modifi\u00e9e depuis la date choisie). Pour chaque constat, le rapport indique ce que vous pouvez v\u00e9rifier \u00e0 la main ou montrer \u00e0 votre h\u00e9bergeur.<\/p>\n\n<p>Les dix contr\u00f4les : fichiers du c\u0153ur compar\u00e9s aux sommes officielles et <code>wp-config.php<\/code> ; extensions de WordPress.org compar\u00e9es \u00e0 leurs sommes ; fichiers PHP dans <code>uploads<\/code> ; mu-plugins et drop-ins ; administrateurs et comptes cr\u00e9\u00e9s depuis la date choisie ; r\u00e8gles <code>.htaccess<\/code> et r\u00e9glages PHP ; contenus cr\u00e9\u00e9s ou modifi\u00e9s depuis cette date, scripts dans les contenus ; t\u00e2ches planifi\u00e9es ; adresses du site, inscription, extensions actives, scripts dans les options ; et la liste de ce qui n'a pas \u00e9t\u00e9 regard\u00e9.<\/p>\n\n<p>Non regard\u00e9 : les th\u00e8mes (WordPress.org ne publie pas de sommes pour eux), les extensions sans sommes publi\u00e9es (nomm\u00e9es une \u00e0 une), les tables hors WordPress, les commentaires, les fichiers hors du dossier de WordPress, la configuration du serveur, les autres sites de l'h\u00e9bergement et du r\u00e9seau, la date des changements de r\u00f4le, les fichiers illisibles ou de plus de 5 Mo, les fichiers de plus de 32 Mo \u00e0 la racine, dans <code>wp-admin<\/code>, <code>wp-includes<\/code> et les extensions (non compar\u00e9s aux sommes, list\u00e9s). Les dossiers de <code>wp-content<\/code> qu'aucun contr\u00f4le ne couvre (<code>languages<\/code>, <code>cache<\/code>, <code>upgrade<\/code>, sauvegardes...) sont list\u00e9s avec leur nombre de fichiers PHP quand ils en contiennent. Les fichiers PHP d'un dossier de la racine qui n'appartient pas \u00e0 WordPress ne sont compar\u00e9s \u00e0 rien : le dossier est list\u00e9 \u00ab \u00e0 identifier \u00bb avec leur nombre, et un fichier PHP dans <code>.well-known<\/code> ou <code>cgi-bin<\/code> est signal\u00e9 suspect.<\/p>\n\n<p>Le plugin ne modifie rien : aucun fichier, compte, contenu ni r\u00e9glage. Il n'\u00e9crit que ses propres options (<code>ahcl_*<\/code>). Les sommes de contr\u00f4le ne sont t\u00e9l\u00e9charg\u00e9es depuis api.wordpress.org et downloads.wordpress.org que si vous cochez la case pr\u00e9vue, d\u00e9coch\u00e9e au premier passage. L'interface est en fran\u00e7ais quand le site est en fran\u00e7ais.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>In Plugins &gt; Add New, search for \"Aftersweep\", then install and activate it. Or upload the <code>aftersweep<\/code> folder to <code>\/wp-content\/plugins\/<\/code> and activate it in Plugins.<\/li>\n<li>Open Tools &gt; Aftersweep.<\/li>\n<li>Set the reference date: the day before you think the hack started (default: 30 days ago).<\/li>\n<li>Tick the checksum box if you accept the requests to WordPress.org, then click \"Run the check\". The page works in short steps and shows its progress; leave it open until the report appears.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20it%20change%20anything%20on%20my%20site%3F\"><h3>Does it change anything on my site?<\/h3><\/dt>\n<dd><p>No. It reads files, users, content, settings and scheduled tasks, and writes nothing but its own options and transients (<code>ahcl_*<\/code>). To act on a finding, you do it yourself, by FTP, in the WordPress admin, or with your host.<\/p><\/dd>\n<dt id=\"will%20it%20tell%20me%20the%20hack%20is%20gone%3F\"><h3>Will it tell me the hack is gone?<\/h3><\/dt>\n<dd><p>No. It tells you what it found in the places it looked, how sure each finding is, and where it did not look. An empty list of anomalies means only that these ten checks found no proven difference.<\/p><\/dd>\n<dt id=\"does%20it%20contact%20external%20servers%3F\"><h3>Does it contact external servers?<\/h3><\/dt>\n<dd><p>Only if you tick \"Download the checksums from api.wordpress.org and downloads.wordpress.org\". The box is unticked the first time the page opens. When it is ticked, during a check:<\/p>\n\n<ul>\n<li>api.wordpress.org receives one request for the core checksums, with your WordPress version and package language;<\/li>\n<li>downloads.wordpress.org receives one request per installed plugin, with the plugin's folder name and version;<\/li>\n<li>for a plugin without published checksums, api.wordpress.org receives one more request with its folder name, to tell \"this version has no checksums\" from \"this plugin is not on WordPress.org\".<\/li>\n<\/ul>\n\n<p>The requests go through the WordPress HTTP API, which by default sends your WordPress version and your site address in its User-Agent header; WordPress.org also sees your server's IP address. WordPress.org's privacy policy: https:\/\/wordpress.org\/about\/privacy\/. Answers are kept 24 hours in transients, so a second check the same day sends no new request. Unticked, nothing leaves your site and checks 1 and 2 are listed under \"not looked at\".<\/p><\/dd>\n<dt id=\"why%20are%20my%20themes%20not%20checked%3F\"><h3>Why are my themes not checked?<\/h3><\/dt>\n<dd><p>WordPress.org does not publish checksums for themes, so there is no official reference to compare them to. Themes are listed under \"not looked at\". The uploads, <code>.htaccess<\/code>, content and settings checks still apply to the whole site.<\/p><\/dd>\n<dt id=\"a%20plugin%20is%20listed%20as%20%22not%20looked%20at%22.%20is%20it%20modified%3F\"><h3>A plugin is listed as \"not looked at\". Is it modified?<\/h3><\/dt>\n<dd><p>The plugin cannot say. Premium plugins, plugins that are not or no longer on WordPress.org, and some versions have no published checksums. The report names each of them and says which case applies. Compare them yourself with a fresh copy from their author.<\/p><\/dd>\n<dt id=\"what%20is%20the%20reference%20date%20for%3F\"><h3>What is the reference date for?<\/h3><\/dt>\n<dd><p>WordPress does not record when a role was changed. The date you give marks \"recent\": administrators created after it and content created or modified after it are listed. Pick the day before you think the hack started; if you do not know, keep the default (30 days ago) or go further back.<\/p><\/dd>\n<dt id=\"i%20already%20ran%20a%20malware%20scanner.%20what%20does%20this%20add%3F\"><h3>I already ran a malware scanner. What does this add?<\/h3><\/dt>\n<dd><p>This plugin has no malware signatures. It compares files to WordPress.org's checksums and lists what you have to recognise: administrator accounts, must-use plugins, drop-ins, recent content, scheduled tasks, rewrite rules and settings. It does not replace a scanner or your host's help; it gives you a list to go through after your cleanup.<\/p><\/dd>\n<dt id=\"my%20host%20is%20a%20shared%20hosting%20plan.%20will%20the%20check%20time%20out%3F\"><h3>My host is a shared hosting plan. Will the check time out?<\/h3><\/dt>\n<dd><p>Each request works for about 10 seconds, then the page sends the next one. If the page is closed or the connection drops, open it again and choose \"Resume\" or \"Start over\". Only one check runs at a time.<\/p><\/dd>\n<dt id=\"does%20it%20work%20on%20multisite%3F\"><h3>Does it work on multisite?<\/h3><\/dt>\n<dd><p>On a network, only network administrators can open it, and it reads the main site only. The other sites of the network are listed under \"not looked at\".<\/p><\/dd>\n<dt id=\"is%20it%20in%20french%3F\"><h3>Is it in French?<\/h3><\/dt>\n<dd><p>Strings are written in English. A complete French translation will be submitted on translate.wordpress.org; once approved there, WordPress installs it on sites set to French.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.1.0<\/h4>\n\n<ul>\n<li>First release: ten read-only checks (core and plugin checksums, uploads, mu-plugins and drop-ins, administrators, .htaccess and PHP settings, content, cron, settings, not looked at), three finding levels, reference date, checksum download only after an opt-in checkbox, work in short steps with resume, last report kept, French translation.<\/li>\n<\/ul>","raw_excerpt":"For after your cleanup of a hacked site: a read-only list of what still looks wrong, and of what the plugin did not look at.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/397740","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=397740"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/timaub"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=397740"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=397740"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=397740"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=397740"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=397740"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=397740"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}