web-dev-qa-db-fra.com

Gestion des pièces jointes de tuyaux de courrier électronique et détection des types de fichiers non pris en charge

Je travaille sur un plugin qui utilise Email Piping. Lorsqu'un e-mail est traité, je souhaite que toutes les pièces jointes de l'e-mail soient ajoutées à la médiathèque WordPress.

J'utilise actuellement wp_insert_attachment, wp_generate_attachment_metadata et wp_update_attachment_metadata qui fonctionne correctement. Toutefois, l'utilisation de ces fonctions permet d'ajouter n'importe quel fichier joint à un courrier électronique à la WP Médiathèque. Ce qui me préoccupe, c’est que cela pourrait donner aux gens la possibilité de joindre des fichiers malveillants auxquels on pourrait facilement accéder et les utiliser à des fins malveillantes.

En tant que tel, ce que je voudrais faire est que lorsque la gestion des pièces jointes puisse identifier si la pièce jointe est un type de fichier pris en charge. J'ai enquêté sur wp_check_filetype, wp_check_filetype_and_ext et get_allowed_mime_types que je peux utiliser pour confirmer la sécurité d'un fichier, mais à moins d'avoir oublié quelque chose, je ne vois pas comment passer un fichier via une fonction pour confirmer s'il s'agit d'un type de fichier pris en charge.

Si je peux identifier les fichiers qui ne sont pas pris en charge, je peux créer un fichier Zip contenant ces fichiers à télécharger plutôt que le fichier brut, qui dans mon livre devrait fermer le trou de sécurité visible. Je le fais pour les fichiers téléchargés via un formulaire. Les fichiers pris en charge avec media_handle_upload et ceux qui ne le sont pas sont traités via PHP, ajoutés à un fichier Zip puis attachés à l'aide de wp_insert_attachment, wp_generate_attachment_metadata et wp_update_attachment_metadata.

Toute aide serait grandement appréciée.

$upload_dir = wp_upload_dir();
$tmp_pathfile = '/home/user/public_html/wp-content/uploads/tmp_file.js';
$tmp_filename = 'tmp_file.js';
$filetype = wp_check_filetype( $tmp_pathfile );
if ( is file allowed for WordPress Media Library ) { // This is where I want to check if the file is supported by the WordPress Media Library
    $data = array(
        'guid' => $upload_dir['url'] . '/' . $tmp_filename,
        'post_title' => $tmp_filename,
        'post_content' => '',
        'post_status' => 'inherit',
        'post_mime_type' => $filetype['type']
    );
    $theID = wp_insert_attachment( $data, $tmp_pathfile );
    $attach_data = wp_generate_attachment_metadata( $theID, $tmp_pathfile );
    wp_update_attachment_metadata( $theID, $attach_data );
} else { // File not supported by the WordPress Media Library
    $Zip_pathfile = $tmp_pathfile . '.Zip';
    while ( file_exists( $Zip_file ) ) {
        $Zip_file = $tmp_pathfile . '_' . time() . '.Zip';
    }
    $Zip = new ZipArchive();
    if ( $Zip->open( $Zip_file, ZipArchive::CREATE ) ) {
        $Zip->addFile( $tmp_pathfile, $tmp_filename );
        $Zip->close();
        $filetype = wp_check_filetype( $Zip_file );
        $data = array(
            'guid'           => $Zip_file, 
            'post_mime_type' => $filetype['type'],
            'post_title'     => basename( $Zip_file ),
            'post_content'   => '',
            'post_status'    => 'inherit'
        );
        $theID = wp_insert_attachment( $data, $Zip_file );
        $attach_data = wp_generate_attachment_metadata( $theID, $Zip_file );
        wp_update_attachment_metadata( $theID, $attach_data );
        unlink( $tmp_pathfile);
    }
}
2
David Clough

Ok, semble-t-il, j'étais sur la bonne voie ... Je n'ai toujours pas trouvé de fonction WordPress qui réponde à mes besoins, mais le plus proche que j'ai trouvé est d'utiliser la fonction get_allowed_mime_types.

J'ai créé la fonction suivante qui vérifie si le fichier se trouve dans le tableau get_allowed_mime_types et, le cas échéant, renvoie true (fichier traité à l'aide de wp_insert_attachment, wp_generate_attachment_metadata et wp_update_attachment_metadata) ou false (fichier compressé puis traité à l'aide de wp_insert_attachment, wp_generate_attachment_metadata et wp_update_attachment_metadata).

function is_upload_allowed( $file ) {
    $filetype = wp_check_filetype( $file );
    $file_ext = $filetype['ext'];
    $mimes = get_allowed_mime_types();
    foreach ( $mimes as $type => $mime ) {
        if ( strpos( $type, $file_ext ) !== false ) {
            return true;
        }
    }
    return false;
}

Donc, mon code mis à jour ressemble à ceci:

$upload_dir = wp_upload_dir();
$tmp_pathfile = '/home/user/public_html/wp-content/uploads/tmp_file.js';
$tmp_filename = 'tmp_file.js';
$filetype = wp_check_filetype( $tmp_pathfile );
if ( is_upload_allowed( tmp_pathfile ) ) { // This is where I want to check if the file is supported by the WordPress Media Library
    $data = array(
        'guid' => $upload_dir['url'] . '/' . $tmp_filename,
        'post_title' => $tmp_filename,
        'post_content' => '',
        'post_status' => 'inherit',
        'post_mime_type' => $filetype['type']
    );
    $theID = wp_insert_attachment( $data, $tmp_pathfile );
    $attach_data = wp_generate_attachment_metadata( $theID, $tmp_pathfile );
    wp_update_attachment_metadata( $theID, $attach_data );
} else { // File not supported by the WordPress Media Library
    $Zip_pathfile = $tmp_pathfile . '.Zip';
    while ( file_exists( $Zip_file ) ) {
        $Zip_file = $tmp_pathfile . '_' . time() . '.Zip';
    }
    $Zip = new ZipArchive();
    if ( $Zip->open( $Zip_file, ZipArchive::CREATE ) ) {
        $Zip->addFile( $tmp_pathfile, $tmp_filename );
        $Zip->close();
        $filetype = wp_check_filetype( $Zip_file );
        $data = array(
            'guid'           => $Zip_file, 
            'post_mime_type' => $filetype['type'],
            'post_title'     => basename( $Zip_file ),
            'post_content'   => '',
            'post_status'    => 'inherit'
        );
        $theID = wp_insert_attachment( $data, $Zip_file );
        $attach_data = wp_generate_attachment_metadata( $theID, $Zip_file );
        wp_update_attachment_metadata( $theID, $attach_data );
        unlink( $tmp_pathfile);
    }
}

Cela fonctionne, je serais toujours heureux d’entendre s’il existe une fonction WordPress intégrée qui remplit les mêmes fonctions que la fonction is_upload_allowed que j’ai créée.

1
David Clough