{"id":371222,"date":"2026-10-04T08:23:49","date_gmt":"2026-10-04T08:23:49","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/backupyoursite\/"},"modified":"2026-10-04T08:23:15","modified_gmt":"2026-10-04T08:23:15","slug":"backupyoursite","status":"publish","type":"plugin","link":"https:\/\/mri.wordpress.org\/plugins\/backupyoursite\/","author":23568614,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.1.1","stable_tag":"1.1.1","tested":"7.1.2","requires":"6.0","requires_php":"7.4","requires_plugins":null,"header_name":"BackupYourSite","header_author":"BackupYourSite","header_description":"Scheduled backups of your files and database to your own server \u2014 with one-click restore. An optional cloud destination can store a verified offsite copy.","assets_banners_color":"9b88d1","last_updated":"2026-10-04 08:23:15","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/backupyoursite.com\/wordpress-plugin\/","header_author_uri":"https:\/\/backupyoursite.com\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":69,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.1.1":{"tag":"1.1.1","author":"nurotech","date":"2026-10-04 08:23:15","revision":3727170}},"upgrade_notice":{"1.1.1":"<p>Security: wp-config.php is no longer put into a backup that leaves your server. Internal names\nare now prefixed; your settings, history and cloud connection carry over automatically.<\/p>","1.0.9":"<p>Important if you use cloud storage: a failed upload could leave you with no offsite copy while\nthe backup still reported as complete. Uploads are now retried and destinations are\nindependent. Recommended for everyone.<\/p>","1.0.8":"<p>Fixes an unrestorable cloud backup: after connecting cloud storage the first cloud backup\ncould be an incremental with no full backup behind it. Recommended for everyone using cloud\nstorage.<\/p>","1.0.7":"<p>Changes the default full-backup interval for new installs to every 25 backups. Your own\nsetting is untouched if you have ever saved the settings page.<\/p>","1.0.6":"<p>If you have been seeing &quot;your backup files are publicly downloadable&quot; on an nginx host, this\nrelease fixes it during the upgrade, by itself. No wp-config.php edit and no support ticket.\nRecommended for everyone.<\/p>","1.0.5":"<p>Clears the false &quot;backups are publicly downloadable&quot; warning left behind by the 1.0.4 upgrade.\nRecommended for everyone who updated to 1.0.4.<\/p>","1.0.2":"<p>Plugin Check compliance fixes (i18n, translators comment). No functional change \u2014 safe to update.<\/p>","1.0.1":"<p>Cloud upload and restore now run against the live BackupYourSite service. Restore reports\nreal progress and real error reasons. Recommended for anyone using cloud storage.<\/p>"},"ratings":[],"assets_icons":{"icon-256x256.png":{"filename":"icon-256x256.png","revision":3727082,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-772x250.png":{"filename":"banner-772x250.png","revision":3727081,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.1.1"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3727083,"resolution":"1","location":"assets","locale":"","width":2880,"height":2302},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3727160,"resolution":"2","location":"assets","locale":"","width":2880,"height":2586},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3727157,"resolution":"3","location":"assets","locale":"","width":2880,"height":3404},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3727084,"resolution":"4","location":"assets","locale":"","width":2880,"height":3042},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3727100,"resolution":"5","location":"assets","locale":"","width":2880,"height":760}},"screenshots":{"1":"The Backups screen \u2014 backup history with size, file count and destination for every stored backup.","2":"A backup running \u2014 live progress, phase and step count while it works in small resumable steps.","3":"The Settings screen \u2014 schedule, what to include, volume size, incremental mode and retention.","4":"The restore panel \u2014 choose files\/database\/both, take a pre-restore snapshot, and confirm.","5":"The Account screen \u2014 optional BackupYourSite cloud storage, connected, with plan and quota."}},"plugin_section":[],"plugin_tags":[151,10718,4155,152,265189],"plugin_category":[59],"plugin_contributors":[],"plugin_business_model":[],"class_list":["post-371222","plugin","type-plugin","status-publish","hentry","plugin_tags-backup","plugin_tags-database-backup","plugin_tags-migration","plugin_tags-restore","plugin_tags-scheduled-backup","plugin_category-utilities-and-tools","plugin_committers-nurotech"],"banners":{"banner":"https:\/\/ps.w.org\/backupyoursite\/assets\/banner-772x250.png?rev=3727081","banner_2x":false,"banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/backupyoursite\/assets\/icon-256x256.png?rev=3727082","icon_2x":"https:\/\/ps.w.org\/backupyoursite\/assets\/icon-256x256.png?rev=3727082","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/backupyoursite\/assets\/screenshot-1.png?rev=3727083","caption":"The Backups screen \u2014 backup history with size, file count and destination for every stored backup."},{"src":"https:\/\/ps.w.org\/backupyoursite\/assets\/screenshot-2.png?rev=3727160","caption":"A backup running \u2014 live progress, phase and step count while it works in small resumable steps."},{"src":"https:\/\/ps.w.org\/backupyoursite\/assets\/screenshot-3.png?rev=3727157","caption":"The Settings screen \u2014 schedule, what to include, volume size, incremental mode and retention."},{"src":"https:\/\/ps.w.org\/backupyoursite\/assets\/screenshot-4.png?rev=3727084","caption":"The restore panel \u2014 choose files\/database\/both, take a pre-restore snapshot, and confirm."},{"src":"https:\/\/ps.w.org\/backupyoursite\/assets\/screenshot-5.png?rev=3727100","caption":"The Account screen \u2014 optional BackupYourSite cloud storage, connected, with plan and quota."}],"raw_content":"<!--section=description-->\n<p>BackupYourSite is a WordPress backup plugin that backs up your files and database on a\nschedule, stores the archives on your own server, and restores them again from the WordPress\nadmin in one click. An optional cloud destination adds a verified offsite copy when you want\none \u2014 everything else works with no account at all.<\/p>\n\n<p>It is built for cheap, limited hosting. The backup runs in small steps rather than one long\nrequest, so a short PHP time limit or a small memory limit slows it down instead of breaking\nit. If a step is killed, the next one carries on from where it stopped.<\/p>\n\n<p><strong>Core backup features<\/strong><\/p>\n\n<ul>\n<li>Daily, weekly or manual scheduled backups of files and database.<\/li>\n<li>A real database dump written by PHP \u2014 no <code>mysqldump<\/code>, no shell access needed.<\/li>\n<li>Archives split into size-limited zip volumes so nothing has to be handled in one piece.<\/li>\n<li>Incremental backups measured against the last full backup, so restoring never needs more\nthan two backups.<\/li>\n<li>Every backup is verified before it counts: the archives are integrity-checked, the\ndatabase dump must end with its completion marker, and every file the plugin promised to\narchive must actually be in the archive. A backup that does not pass is marked incomplete,\nand old backups are never deleted after a run that was not clean.<\/li>\n<li>One-click restore of files, database, or both \u2014 with a snapshot of the current site taken\nfirst.<\/li>\n<li>One retention setting: delete backups older than N days. The most recent working backup is\nnever deleted, and nothing is ever deleted after a backup that did not finish cleanly.<\/li>\n<li>Failure emails if a scheduled backup does not complete.<\/li>\n<\/ul>\n\n<p><strong>Optional: offsite cloud backup<\/strong><\/p>\n\n<p>Backups kept on the same server share that server's fate. If you want an offsite copy, you\ncan connect a BackupYourSite account on the Account screen and add \"Cloud\" as a destination.\nThis is entirely optional \u2014 every feature above works without an account, and the plugin\nmakes no connection to our service until you paste a connection code yourself.<\/p>\n\n<p>Your <code>wp-config.php<\/code> is never included in an archive that is uploaded to a cloud destination,\nso your WordPress authentication keys, salts and database credentials stay on your own server.\nSee \"External Services\" and the FAQ below for exactly what is sent and when.<\/p>\n\n<p><strong>What it does not do<\/strong><\/p>\n\n<ul>\n<li>It cannot restore a site that no longer runs. This plugin lives inside WordPress; if\nWordPress cannot start \u2014 a white screen, a fatal error, a database connection error, a\nsuspended account \u2014 the plugin cannot start either. For that case, download the archive\nfrom the Backups screen and restore it through your hosting control panel.<\/li>\n<li>Backups stored on this server share this server's fate. They protect you from mistakes,\nbad updates and corruption. They do not protect you from losing the server.<\/li>\n<li>Multisite is not supported yet.<\/li>\n<\/ul>\n\n<p><strong>Who this is for<\/strong><\/p>\n\n<p>Anyone who wants scheduled WordPress backups and a real one-click restore without shell\naccess or a <code>mysqldump<\/code>-capable host: small business sites, agencies managing client sites on\nbudget hosting, and anyone planning to migrate a WordPress site and wanting a verified,\nrestorable copy of it first.<\/p>\n\n<h3>External Services<\/h3>\n\n<p>This plugin works completely on its own and makes no outbound connection by default. No\naccount is required, and nothing leaves your server unless you deliberately connect one.<\/p>\n\n<p><strong>Requests to your own site (always, no account needed)<\/strong><\/p>\n\n<ul>\n<li>A short request back to this site's own <code>admin-ajax.php<\/code> to continue a running backup.<\/li>\n<li>A request to this site's own backup folder to test whether the web server would let a\nstranger download your backups.<\/li>\n<\/ul>\n\n<p>Both of these stay on your own server and are not an external service.<\/p>\n\n<p><strong>BackupYourSite cloud storage (optional, off until you connect it)<\/strong><\/p>\n\n<p>If \u2014 and only if \u2014 you create a BackupYourSite account and paste a connection code into the\nplugin's Account screen, the plugin talks to the BackupYourSite backup service at\n    https:\/\/app.backupyoursite.com, operated by BackupYourSite.<\/p>\n\n<p>What is sent, and when:<\/p>\n\n<ul>\n<li><strong>When you press Connect:<\/strong> the connection code you pasted, this site's home URL, this\nsite's name, and the plugin version. The service returns a token scoped to this site only.<\/li>\n<li><strong>When a backup runs with \"Cloud\" selected as a destination:<\/strong> the backup archives\nthemselves are uploaded in parts. Those archives contain your site files and a full copy of\nyour database, which includes user accounts, email addresses, orders, comments and any other\npersonal data your site stores. A SHA-256 checksum and the archive file names and sizes are\nsent with each part. <code>wp-config.php<\/code> and the other site configuration files listed in the\nFAQ below are deliberately left out of any archive that goes to a cloud destination, so your\nWordPress authentication keys and salts are never uploaded.<\/li>\n<li><strong>When you open the Account screen or press Refresh:<\/strong> a request asking for your plan name\nand storage quota. The service records this as a liveness ping.<\/li>\n<li><strong>When you restore from a cloud backup:<\/strong> a request for a time-limited download URL, then\nthe download of the archive volumes.<\/li>\n<li><strong>When you delete a cloud backup or disconnect the site:<\/strong> the backup set identifier, or a\ndisconnect request for this site's token.<\/li>\n<\/ul>\n\n<p>Nothing is sent before you connect. No usage statistics, telemetry or analytics are ever\nsent, connected or not. Your account password is never asked for and never stored.<\/p>\n\n<p>Service terms: https:\/\/backupyoursite.com\/terms\/\nPrivacy policy: https:\/\/backupyoursite.com\/privacy\/<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin to <code>wp-content\/plugins\/backupyoursite<\/code> and activate it.<\/li>\n<li>Open <strong>BackupYourSite<\/strong> in the admin menu and press <strong>Back up now<\/strong>.<\/li>\n<li>Check the <strong>Are your backups reachable from the web?<\/strong> result on that screen. If it says\nyes, fix it before relying on the plugin \u2014 the archives contain your whole database.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"where%20are%20my%20backups%20stored%3F\"><h3>Where are my backups stored?<\/h3><\/dt>\n<dd><p>In <code>wp-content\/uploads\/backupyoursite\/archives\/<\/code>. Each backup gets its own folder with a\nrandom name, and the folder is protected by an <code>index.php<\/code> stub, an <code>.htaccess<\/code> rule and a\n    web.config rule. The plugin also tests, over HTTP, whether those rules actually work on\nyour server, and warns you loudly if they do not.<\/p><\/dd>\n<dt id=\"how%20do%20i%20restore%20a%20wordpress%20backup%3F\"><h3>How do I restore a WordPress backup?<\/h3><\/dt>\n<dd><p>Open <strong>BackupYourSite \u2192 Restore<\/strong>, pick the backup to restore from, choose files, database, or\nboth, and confirm. The plugin takes a snapshot of the current site first, then restores in\nsmall steps and reports progress as it works.<\/p><\/dd>\n<dt id=\"can%20i%20use%20this%20plugin%20to%20migrate%20a%20wordpress%20site%3F\"><h3>Can I use this plugin to migrate a WordPress site?<\/h3><\/dt>\n<dd><p>Take a backup on the old site, download or transfer the archive, install BackupYourSite on the\nnew site, and restore it there. The database dump and file archive are both verified before\nthey count as a usable backup, so a migration starts from a backup you know is intact.<\/p><\/dd>\n<dt id=\"my%20site%20gets%20very%20little%20traffic.%20will%20the%20backup%20still%20run%3F\"><h3>My site gets very little traffic. Will the backup still run?<\/h3><\/dt>\n<dd><p>WordPress's built-in scheduler only runs when someone visits the site, so it may not. The\nSettings screen shows a cron line you can paste into your hosting control panel to fix that.<\/p><\/dd>\n<dt id=\"can%20it%20restore%20my%20site%20if%20it%20is%20completely%20broken%3F\"><h3>Can it restore my site if it is completely broken?<\/h3><\/dt>\n<dd><p>No. See \"What it does not do\" above. Download the archive and restore it through your host.<\/p><\/dd>\n<dt id=\"do%20i%20need%20a%20backupyoursite%20account%3F\"><h3>Do I need a BackupYourSite account?<\/h3><\/dt>\n<dd><p>No. Everything the plugin does \u2014 scheduled backups, incremental backups, verification,\nretention, restore \u2014 works with no account and with no connection to us. An account only\nadds the optional offsite cloud destination. Until you connect one, the plugin makes no\nrequest to any external service at all.<\/p><\/dd>\n<dt id=\"is%20wp-config.php%20included%20in%20my%20backups%3F\"><h3>Is wp-config.php included in my backups?<\/h3><\/dt>\n<dd><p>Not in any backup that leaves your server. As soon as a backup run has an off-server\ndestination selected, the plugin leaves these files out of the archive it builds:<\/p>\n\n<ul>\n<li><code>wp-config.php<\/code><\/li>\n<li>any <code>wp-config-*.php<\/code> variant your host or staging setup uses (except the core\n  wp-config-sample.php, which holds only placeholders)<\/li>\n<li><code>wp-salt.php<\/code> and <code>wp-salts.php<\/code><\/li>\n<li><code>.env<\/code><\/li>\n<\/ul>\n\n<p>That is deliberate. <code>wp-config.php<\/code> holds your WordPress authentication keys and salts, which\nsign this site's login cookies and nonces, plus your database credentials \u2014 and none of that\nshould be sitting on somebody else's storage. One archive is built per run and sent to every\ndestination you selected, so the exclusion applies to the whole run as soon as any destination\nis off-server. A backup run with only \"This server\" selected still includes these files,\nbecause nothing leaves your server.<\/p>\n\n<p>Nothing a restore needs is lost. Restoring happens inside a working WordPress that already has\nits own <code>wp-config.php<\/code>, which the plugin never overwrites. A site being rebuilt from nothing\ngets a fresh <code>wp-config.php<\/code> with fresh salts from the WordPress installer, which is the safer\noutcome anyway \u2014 reusing the salts of a site you have just lost would keep every old session\nsignable.<\/p><\/dd>\n<dt id=\"what%20is%20sent%20to%20backupyoursite.com%20if%20i%20do%20connect%20an%20account%3F\"><h3>What is sent to backupyoursite.com if I do connect an account?<\/h3><\/dt>\n<dd><p>Your backup archives, which contain your files (minus the configuration files listed above)\nand your whole database. The full list is in the \"External Services\" section above. No\ntelemetry or usage statistics are ever sent.<\/p><\/dd>\n<dt id=\"is%20the%20database%20dump%20consistent%3F\"><h3>Is the database dump consistent?<\/h3><\/dt>\n<dd><p>Per table, yes. Across the whole database, no \u2014 the dump runs across many requests, so rows\nwritten between two tables being dumped are captured at different moments. This is a real\nlimitation of any backup that runs inside PHP without shell access.<\/p><\/dd>\n<dt id=\"does%20this%20plugin%20work%20on%20cheap%20or%20limited%20hosting%3F\"><h3>Does this plugin work on cheap or limited hosting?<\/h3><\/dt>\n<dd><p>Yes \u2014 that is what it is built for. The backup runs in small steps instead of one long\nrequest, so a short PHP time limit or low memory limit slows it down rather than breaking it,\nand a killed step is simply resumed on the next one.<\/p><\/dd>\n<dt id=\"does%20this%20support%20wordpress%20multisite%3F\"><h3>Does this support WordPress multisite?<\/h3><\/dt>\n<dd><p>Not yet.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.1.1<\/h4>\n\n<ul>\n<li>Security: <code>wp-config.php<\/code> is no longer included in a backup archive that leaves your server.\nIt holds your WordPress authentication keys and salts and your database credentials, and\nuploading it put those on storage you do not control. <code>wp-config-*.php<\/code> variants,\n  wp-salt.php, <code>wp-salts.php<\/code> and <code>.env<\/code> are excluded in the same way. Backups that stay on\nyour own server are unchanged. See the FAQ for why nothing a restore needs is lost.<\/li>\n<li>Every internal name the plugin uses is now prefixed <code>bysbackup<\/code> \u2014 its options, database\ntables, scheduled task, hooks and admin page addresses. Your settings, schedule, backup\nhistory, stored backups and cloud connection are carried over automatically on the first\nload after the update; there is nothing to reconnect and nothing to set up again.<\/li>\n<li>Backups written by earlier versions stay restorable.<\/li>\n<\/ul>\n\n<h4>1.0.9<\/h4>\n\n<ul>\n<li>Fixed: with both \"This server\" and \"BackupYourSite cloud storage\" ticked, a backup could be\nstored on the server only, with nothing at all going to the cloud \u2014 and still report\n\"Backup complete\". A single failed upload request (a dropped connection, a brief server\nerror, one part rejected) made the plugin abandon the whole offsite copy for that backup,\npermanently, because the part-upload was never retried. It is now retried, and an upload\ninterrupted for a reason that passes is resumed on the next pass instead of being thrown\naway.<\/li>\n<li>Fixed: a part that failed its checksum was skipped instead of being sent again, so the cloud\ncopy could be finalised with a piece missing from it. Every part is now re-sent until the\nserver confirms it.<\/li>\n<li>Fixed: destinations are now independent. A destination that fails no longer stops the others\nfrom being written to, and no longer fails the whole backup \u2014 if your backup folder cannot\nbe written to, the cloud copy still happens, and the other way round. A backup only fails\noutright when nothing could be stored anywhere.<\/li>\n<li>Fixed: a backup that did not reach one of your chosen destinations is reported as such \u2014\non the Dashboard, on the Settings screen (per destination), in the log, and by email. It is\nno longer counted as a clean run, and old backups are no longer deleted on the strength of\none. A destination that missed a backup is also correctly treated as not having it, so the\nnext backup to it is a full one.<\/li>\n<li>Fixed: a destination you had ticked could be silently un-ticked by saving the Settings page\nwhile it happened to be unavailable (for example a cloud account mid-reconnect).<\/li>\n<li>Fixed: the Settings screen could show \"The folder could not be created or is not writable.\"\ndirectly underneath the backup folder actually in use and working normally. That message is\nabout a folder outside your website that could not be used, and now says so.<\/li>\n<\/ul>\n\n<h4>1.0.8<\/h4>\n\n<ul>\n<li>Fixed: connecting cloud storage after you had already been backing up locally could put an\nincremental backup in the cloud with no full backup behind it \u2014 which is not restorable on\nits own. The plugin decided full-versus-incremental by looking only at your local backups,\nso a brand-new cloud destination inherited a baseline it did not have a copy of. Whether a\nfull backup already exists is now asked of every destination a backup is being written to,\nseparately; if any of them does not have one, that run takes a full backup. This also covers\na cloud copy that was pruned, deleted, or never finished uploading.<\/li>\n<li>If you are affected, the next scheduled or manual backup after this update takes a full\nbackup by itself \u2014 no action needed. Any incremental already sitting in the cloud without a\nfull behind it is now labelled \"No full backup behind it\" under Stored backups, so it is not\nmistaken for a working backup.<\/li>\n<\/ul>\n\n<h4>1.0.7<\/h4>\n\n<ul>\n<li>New installs now take a fresh full backup every 25 backups instead of every 7. On a daily\nschedule that is one full a month rather than one a week, so far less is re-uploaded and\nre-stored for the same protection \u2014 each incremental is still measured against the last\nfull, so a restore still needs only two backups. Sites that have already saved their\nsettings keep whatever number they chose; change it under Incremental backups.<\/li>\n<\/ul>\n\n<h4>1.0.6<\/h4>\n\n<ul>\n<li>The \"your backup files are publicly downloadable\" warning now fixes itself instead of\nasking you to. On servers that ignore <code>.htaccess<\/code> \u2014 nginx, and Apache with\n  AllowOverride None \u2014 rewriting those files could never have worked, so the plugin used\nto print the warning and leave the archives sitting at a URL that answered 200 until\nsomeone read it, edited wp-config.php over SFTP, or opened a support ticket. It now works\nthrough the remedies itself and re-tests after each one: it makes the archives readable\nonly by your own account (decisive wherever the web server is a different user from PHP,\nwhich is the usual layout on exactly those hosts), and failing that it moves your backups\nout of the website folder altogether, where no web address can reach them.<\/li>\n<li>New button, \"Move my backups out of the website\" \u2014 one click, on any host where PHP may\nwrite above your website root. It moves what is already stored and remembers the new\nlocation itself, so <strong>BYSBACKUP_BACKUP_DIR in wp-config.php is no longer needed<\/strong> for this. The\nconstant still works and still wins, as the escape hatch for layouts nothing can infer.<\/li>\n<li>Two candidate folders outside the website are now tried instead of one, so panels that\nplace the account home directory an extra level above the web root are handled.<\/li>\n<li>Where a host allows none of the above \u2014 it serves the folder, ignores every rule, runs the\nweb server as the PHP user, and confines PHP to the website \u2014 the storage folder is renamed\nto carry 32 random characters, on top of the 16 every backup set already carries. The\ndashboard says plainly that this is an unguessable address and not protection, rather than\nreporting the problem as fixed.<\/li>\n<li>Archives are clamped to owner-only as each one lands, not on a later sweep.<\/li>\n<li>Fixed: the warning led with \"add a BYSBACKUP_BACKUP_DIR constant to wp-config.php\" even on the\nmany sites where a button could do it. It now names the button, and only falls back to\nnaming your host when this server genuinely permits nothing else.<\/li>\n<\/ul>\n\n<h4>1.0.5<\/h4>\n\n<ul>\n<li>Fixed the \"your backup files are publicly downloadable\" warning staying on screen after\n1.0.4 had already repaired the folder. 1.0.4 rewrote the protection files during the upgrade\nbut never re-tested them, so the warning from before the repair was what you kept reading.\nThe upgrade now re-tests, and an install that already upgraded re-tests itself once.<\/li>\n<li>When the stored result carries no recorded cause, the warning no longer claims your server\nignores .htaccess. That advice was shown on servers that honour it perfectly well.<\/li>\n<\/ul>\n\n<h4>1.0.4<\/h4>\n\n<ul>\n<li>Fixed a security bug that could leave the backup folder publicly downloadable. The\nprotection files (<code>.htaccess<\/code>, <code>web.config<\/code>, <code>index.php<\/code>) were only written when absent,\nso a file that existed but was empty or half-written \u2014 a truncating \"cleanup\" plugin, an\ninterrupted write, a host migration that copied names but not contents \u2014 passed the\ncheck while denying nothing. The folder was then open, and because the file existed it\nwas never repaired: the \"your backups are publicly downloadable\" warning fired forever\nand told the user to contact their host about something the plugin could fix itself.\nProtection is now verified by content, not by existence, and repaired automatically on\nevery backup run. A partial write is deleted rather than left in place.<\/li>\n<li>The exposure self-test now rewrites and re-verifies the deny rules and retests before\nreporting anything, so a repairable folder is simply repaired and never warned about.\nOnly an exposure that survives a verified repair is reported.<\/li>\n<li>The exposure warning and email now distinguish the two real causes and give the right\nadvice for each: a server that ignores <code>.htaccess<\/code> (usual on nginx), versus protection\nfiles the plugin could not write. Both now point at the <code>BYSBACKUP_BACKUP_DIR<\/code> constant, which\nmoves backups outside the website entirely.<\/li>\n<li>Every backup run now re-verifies the deny rules across the whole storage folder, including\nthe folders of backups taken earlier. Previously a run only guarded the folders it created\nitself, so a set from an earlier run whose protection had since been damaged stayed that\nway \u2014 and it holds the same wp-config.php and database as a fresh one. Activating or\nupdating the plugin repairs the whole tree too.<\/li>\n<li>The storage folder is now guarded at the moment it is created, closing the short window\nbetween creating it and protecting it on first activation.<\/li>\n<\/ul>\n\n<h4>1.0.3<\/h4>\n\n<ul>\n<li>Fixed a real data-integrity bug: <code>fwrite()<\/code> return values were unchecked at four\nchunked-copy sites (split-file reassembly and zip-entry extraction during restore, and\nthe staged-file-list writer). A disk-full or short write mid-copy could silently produce\na truncated file that the restore then treated as successful. All four now check the\nreturn value and fail the restore loudly (with a clear \"disk full or write error\"\nmessage) instead of continuing with a corrupt result.<\/li>\n<li>Replaced 62 bare <code>\/\/ phpcs:ignore<\/code> comments and a further ~30 category-only \/\nunreasoned ones (<code>\/\/ phpcs:ignore WordPress.DB<\/code>, <code>WordPress.Security.NonceVerification<\/code>,\n  Generic.CodeAnalysis.EmptyStatement) with specific sniff names and reviewed\njustifications, or removed them where nothing was actually being suppressed. A bare\nignore silences every sniff on that line, so these lines were never actually examined by\nthe previous Plugin Check pass; each was independently re-verified with the ignore\nstripped. No other real issue surfaced besides the fwrite bug above.<\/li>\n<li>No other functional\/behavioural change to backup or restore.<\/li>\n<\/ul>\n\n<h4>1.0.2<\/h4>\n\n<ul>\n<li>WordPress Plugin Check compliance pass: fixed a missing translators comment, removed the\nnow-redundant load_plugin_textdomain() call (translations for WordPress.org-hosted plugins\nload automatically since WP 4.6) and the stale Domain Path header, and added scoped, reviewed\njustification comments (with matching notes in this readme's reviewer section) for the direct\nfile-streaming calls a backup\/restore engine needs and the table-identifier SQL that\n$wpdb-&gt;prepare() cannot parameterize. No functional\/behavioural change to backup or restore.<\/li>\n<\/ul>\n\n<h4>1.0.1<\/h4>\n\n<ul>\n<li>Cloud upload and restore now run against the live BackupYourSite backend, not a\ncontract mock.<\/li>\n<li>Fixed a cloud-restore bug where an already-downloaded volume was fetched again on\nevery step; downloaded volumes are now cached and their size verified before use.<\/li>\n<li>A failed restore now reports the real reason instead of a generic failure message.<\/li>\n<li>Restore now reports step-by-step progress in the admin while it runs.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>First release: scheduled backups, incremental backups, verification, local storage with\nexposure self-check, retention, restore with pre-restore snapshot.<\/li>\n<\/ul>","raw_excerpt":"Scheduled, verified WordPress backups to your own server, with one-click restore.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/mri.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/371222","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mri.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/mri.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/mri.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=371222"}],"author":[{"embeddable":true,"href":"https:\/\/mri.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/nurotech"}],"wp:attachment":[{"href":"https:\/\/mri.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=371222"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/mri.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=371222"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/mri.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=371222"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/mri.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=371222"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/mri.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=371222"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/mri.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=371222"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}