WordPress.org

Make WordPress Core


Ignore:
Timestamp:
04/30/2018 08:08:37 PM (2 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-admin/includes/file.php

    r43045 r43046  
    20002000 */
    20012001function wp_privacy_generate_personal_data_export_file( $request_id ) {
    2002     // Maybe make this a cron job instead.
    2003     wp_privacy_delete_old_export_files();
    2004 
    20052002    if ( ! class_exists( 'ZipArchive' ) ) {
    20062003        wp_send_json_error( __( 'Unable to generate export file. ZipArchive not available.' ) );
     
    21632160    }
    21642161
    2165 /* translators: Do not translate LINK, EMAIL, SITENAME, SITEURL: those are placeholders. */
     2162    /** This filter is documented in wp-admin/includes/file.php */
     2163    $expiration      = apply_filters( 'wp_privacy_export_expiration', 3 * DAY_IN_SECONDS );
     2164    $expiration_date = date_i18n( get_option( 'date_format' ), time() + $expiration );
     2165
     2166/* translators: Do not translate EXPIRATION, LINK, EMAIL, SITENAME, SITEURL: those are placeholders. */
    21662167$email_text = __(
    21672168'Howdy,
    21682169
    21692170Your request for an export of personal data has been completed. You may
    2170 download your personal data by clicking on the link below. This link is
    2171 good for the next 3 days.
     2171download your personal data by clicking on the link below. For privacy
     2172and security, we will automatically delete the file on ###EXPIRATION###,
     2173so please download it before then.
    21722174
    21732175###LINK###
     
    21842186     *
    21852187     * The following strings have a special meaning and will get replaced dynamically:
     2188     * ###EXPIRATION###         The date when the URL will be automatically deleted.
    21862189     * ###LINK###               URL of the personal data export file for the user.
    21872190     * ###EMAIL###              The email we are sending to.
     
    22012204    $site_url = network_home_url();
    22022205
     2206    $content = str_replace( '###EXPIRATION###', $expiration_date, $content );
    22032207    $content = str_replace( '###LINK###', esc_url_raw( $export_file_url ), $content );
    22042208    $content = str_replace( '###EMAIL###', $email_address, $content );
     
    23452349    return $response;
    23462350}
    2347 
    2348 /**
    2349  * Cleans up export files older than three days old.
    2350  *
    2351  * @since 4.9.6
    2352  */
    2353 function wp_privacy_delete_old_export_files() {
    2354     $upload_dir   = wp_upload_dir();
    2355     $exports_dir  = trailingslashit( $upload_dir['basedir'] . '/exports' );
    2356     $export_files = list_files( $exports_dir );
    2357 
    2358     foreach( (array) $export_files as $export_file ) {
    2359         $file_age_in_seconds = time() - filemtime( $export_file );
    2360 
    2361         if ( 3 * DAY_IN_SECONDS < $file_age_in_seconds ) {
    2362             @unlink( $export_file );
    2363         }
    2364     }
    2365 }
Note: See TracChangeset for help on using the changeset viewer.