[wp-trac] [WordPress Trac] #44886: Race condition in REST API, can cause data loss

WordPress Trac noreply at wordpress.org
Tue Sep 4 03:58:13 UTC 2018


#44886: Race condition in REST API, can cause data loss
--------------------------+-----------------------------
 Reporter:  rldk          |      Owner:  (none)
     Type:  defect (bug)  |     Status:  new
 Priority:  normal        |  Milestone:  Awaiting Review
Component:  REST API      |    Version:  4.9.8
 Severity:  major         |   Keywords:
  Focuses:  rest-api      |
--------------------------+-----------------------------
 If, while a client is downloading a collection from the REST API, a\\
 second client does something that should remove from that collection\\
 a record which the first client has already downloaded, the REST API\\
 will remove some *'''other'''* record from the first client’s collection
 in\\
 order to make the total number of downloaded records be accurate.

 For the demonstration below, the race condition is made repeatable by\\
 having both clients pause at exactly the right (i.e. wrong!) moment.

 Summary of the demonstration:
 1. The site holds “Important Post 1” through “Important Post 12”.
 2. Someone accidentally publishes “My test post”.
 3. An automated client begins downloading all posts (e.g. for backup, or
 syndication).
 4. Someone deletes “My test post”.
 5. The automated client finishes downloading.
 6. Later, when someone needs the downloaded dataset, “Important Post 3”
 is\\
    missing, just because someone deleted “My test post” during the
 download.

 This bug was reported downstream at [https://bugs.debian.org/898309].

 To demonstrate:

 (Files attached to this report are prefixed with “~/Downloads/” below.)

 = Installing and configuring the server software:

 This isn’t meant to be secure; don’t expose it on a public IP address!

 {{{
 # cat /etc/issue.net
 Debian GNU/Linux 9
 # mkdir ~/wprestrace-server
 # cd ~/wprestrace-server
 # cp -a ~/Downloads/basic-auth.tar.gz .
 # wget https://wordpress.org/wordpress-4.9.8.tar.gz
   [...]
 # wget https://www.apachefriends.org/xampp-files/7.2.9/xampp-
 linux-x64-7.2.9-0-installer.run
   [...]
 # chmod +x xampp-linux-x64-7.2.9-0-installer.run
 # ./xampp-linux-x64-7.2.9-0-installer.run
 }}}

 (accept defaults, install, launch)\\
 Manage Servers > MySQL Database > Start

 {{{
 # cd /opt/lampp/htdocs
 # tar xpzf ~/wprestrace-server/wordpress-4.9.8.tar.gz
 # mv wordpress wp
 # tar xpzf ~/wprestrace-server/basic-auth.tar.gz -C wp/wp-content/plugins
 # chown -R daemon:daemon wp
 #
 }}}

 browse to http://localhost/phpmyadmin/\\
 Databases\\
 Database name: root_wp\\
 Collation: utf8_unicode_ci\\
 Create

 browse to http://localhost/wp/\\
 Continue\\
 Let’s go! \\
 Database Name: root_wp\\
 Username: root\\
 Password:\\
 Submit\\
 Run the installation\\
 Site Title: tempsite\\
 Username: username\\
 Password: password\\
 Install WordPress\\
 Log In\\
 Plugins > Installed Plugins > JSON Basic Authentication > Activate

 Done installing and configuring the server software.

 = Installing and configuring the client software:

 {{{
 # mkdir ~/wprestrace-client
 # cd ~/wprestrace-client
 # cp -a ~/Downloads/WpRestRacePopulate.js .
 # cp -a ~/Downloads/WpRestRaceDownloadAll.js .
 # cp -a ~/Downloads/WpRestRaceTestPost.js .
 # wget https://deb.nodesource.com/setup_8.x
   [...]
 # chmod +x setup_8.x
 # ./setup_8.x
   [...]
 # apt-get install nodejs
   [...]
 # node -v
 v8.11.4
 # npm install -g wpapi
 + wpapi at 1.1.2
 added 33 packages in 2.636s
 #
 }}}

 Done installing and configuring the client software.

 = Reproducing the race condition:

 {{{
 # cd ~/wprestrace-client
 # export NODE_PATH=$(npm root -g)
 #
 # node WpRestRacePopulate.js username password http://localhost/wp/wp-json
 Created "Important Post 1".
 Created "Important Post 2".
 Created "Important Post 3".
 Created "Important Post 4".
 Created "Important Post 5".
 Created "Important Post 6".
 Created "Important Post 7".
 Created "Important Post 8".
 Created "Important Post 9".
 Created "Important Post 10".
 Created "Important Post 11".
 Created "Important Post 12".
 #
 }}}

 Open another terminal emulator.\\
 When asked to press Enter below, don’t do it yet!

 {{{
 # cd ~/wprestrace-client
 # export NODE_PATH=$(npm root -g)
 #
 # node WpRestRaceTestPost.js username password http://localhost/wp/wp-json
 Created "My test post".  Press Enter to delete it.
 }}}

 Go back to the original terminal emulator.\\
 When asked to press Enter below, don’t do it yet!

 {{{
 # node WpRestRaceDownloadAll.js username password http://localhost/wp/wp-
 json
 Downloading all posts:
     Downloaded "My test post".
     Downloaded "Important Post 12".
     Downloaded "Important Post 11".
     Downloaded "Important Post 10".
     Downloaded "Important Post 9".
     Downloaded "Important Post 8".
     Downloaded "Important Post 7".
     Downloaded "Important Post 6".
     Downloaded "Important Post 5".
     Downloaded "Important Post 4".
 Press Enter to continue.
 }}}

 Go back to the second terminal emulator, and press Enter.\\
 The command and output (including what you already saw) are:

 {{{
 # node WpRestRaceTestPost.js username password http://localhost/wp/wp-json
 Created "My test post".  Press Enter to delete it.
 Deleted "My test post".
 #
 }}}

 Go back to the original terminal emulator, and press Enter.\\
 The command and output (including what you already saw) are:

 {{{
 # node WpRestRaceDownloadAll.js username password http://localhost/wp/wp-
 json
 Downloading all posts:
     Downloaded "My test post".
     Downloaded "Important Post 12".
     Downloaded "Important Post 11".
     Downloaded "Important Post 10".
     Downloaded "Important Post 9".
     Downloaded "Important Post 8".
     Downloaded "Important Post 7".
     Downloaded "Important Post 6".
     Downloaded "Important Post 5".
     Downloaded "Important Post 4".
 Press Enter to continue.
     Downloaded "Important Post 2".
     Downloaded "Important Post 1".
     Downloaded "Hello world!".
 Finished downloading all posts:
     My test post
     Important Post 12
     Important Post 11
     Important Post 10
     Important Post 9
     Important Post 8
     Important Post 7
     Important Post 6
     Important Post 5
     Important Post 4
     Important Post 2
     Important Post 1
     Hello world!
 End of listing.
 #
 }}}

 The DownloadAll client thinks that it successfully downloaded all posts,\\
 but it never received “Important Post 3”!

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/44886>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list