Make WordPress Core


Ignore:
Timestamp:
04/30/2018 08:08:37 PM (7 years ago)
Author:
iandunn
Message:

Privacy: Add cron to delete expired export files to protect privacy.

The primary means of protecting the files is the CSPRN appended to the filename, but there is no reason to keep the files after the data subject has downloaded them, so deleting them provides an additional layer of protection. Previously this was done from wp_privacy_generate_personal_data_export_file(), but that does not guarantee that it will be run regularly, and on smaller sites that could result in export files being exposed for much longer than necessary.

wp_privacy_delete_old_export_files() was moved to a front end file, so that it can be called from cron.php.

This introduces the wp_privacy_export_expiration filter, which allows plugins to customize how long the exports are kept before being deleted.

index.html was added to the $exclusions parameter of list_files() to make sure that it isn't deleted. If it were, then poorly-configured servers would allow the directory to be traversed, exposing all of the exported files.

Props iandunn, desrosj.
See #43546.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/functions.php

    r43016 r43046  
    62586258    update_option( '_wp_privacy_text_change_check', 'check' );
    62596259}
     6260
     6261/**
     6262 * Schedule a `WP_Cron` job to delete expired export files.
     6263 *
     6264 * @since 4.9.6
     6265 */
     6266function wp_schedule_delete_old_privacy_export_files() {
     6267    if ( ! wp_next_scheduled( 'wp_privacy_delete_old_export_files' ) ) {
     6268        wp_schedule_event( time(), 'hourly', 'wp_privacy_delete_old_export_files' );
     6269    }
     6270}
     6271
     6272/**
     6273 * Cleans up export files older than three days old.
     6274 *
     6275 * The export files are stored in `wp-content/uploads`, and are therefore publicly
     6276 * accessible. A CSPRN is appended to the filename to mitigate the risk of an
     6277 * unauthorized person downloading the file, but it is still possible. Deleting
     6278 * the file after the data subject has had a chance to delete it adds an additional
     6279 * layer of protection.
     6280 *
     6281 * @since 4.9.6
     6282 */
     6283function wp_privacy_delete_old_export_files() {
     6284    $upload_dir   = wp_upload_dir();
     6285    $exports_dir  = trailingslashit( $upload_dir['basedir'] . '/exports' );
     6286    $export_files = list_files( $exports_dir, 100, array( 'index.html' ) );
     6287
     6288    /**
     6289     * Filters the lifetime, in seconds, of a personal data export file.
     6290     *
     6291     * By default, the lifetime is 3 days. Once the file reaches that age, it will automatically
     6292     * be deleted by a cron job.
     6293     *
     6294     * @since 4.9.6
     6295     *
     6296     * @param int $expiration The expiration age of the export, in seconds.
     6297     */
     6298    $expiration = apply_filters( 'wp_privacy_export_expiration', 3 * DAY_IN_SECONDS );
     6299
     6300    foreach ( (array) $export_files as $export_file ) {
     6301        $file_age_in_seconds = time() - filemtime( $export_file );
     6302
     6303        if ( $expiration < $file_age_in_seconds ) {
     6304            unlink( $export_file );
     6305        }
     6306    }
     6307}
Note: See TracChangeset for help on using the changeset viewer.