• Resolved podpirate

    (@podpirate)


    Shalom,
    I am working on a WordPress Multisite environment with some hundred blogs each of which is maintained by another blog admin. One cannot assume, that everybody in the network knows what he or she is doing.

    Your plugin would be the perfect solution to get the media library straight (having the right spirit behind it as well). What’s currently keeping me from using it, is the Upload Settings tab. Every (untrusted) blog admin would be allowed to enable arbitrary file uploads.

    I would wish for an option to disable certain settings on code level. I think a filter like mla_settings_tablist
    would be the easiest way to achieve this.

    Would you agree to implement such a feature?
    (Could implement the filter myself and send you a pull request on GitHub if you like it that way.)

    https://wordpress.org/plugins/media-library-assistant/

Viewing 6 replies - 1 through 6 (of 6 total)
  • Plugin Author David Lingren

    (@dglingren)

    Thanks for your interest in the plugin and for this suggestion. I will give some thought to adding filters along the lines you suggest, but if restricting upload types is your only concern I have some good news. MLA uses the WordPress upload_mimes filter to supply upload types. For multisite installs WordPress already supports an additional filter you can use to restrict the list returned by MLA through upload_mimes. Here is some documentation from the MLA source code (media-library-assistant/includes/class-mla-mime-types.php):

    /**
     * Retrieve list of allowed MIME types and file extensions; use this filter to remove types
     *
     * Called from /wp-includes/functions.php, function get_allowed_mime_types(). That function
     * is called from /wp-includes/formatting.php function sanitize_file_name() and from
     * /wp-includes/functions.php, function wp_check_filetype(). wp_check_filetype returns only one
     * MIME type for a given file extension, so the file extension should/must be a unique key.
     *
     * This filter is also hooked by /wp-includes/ms-functions.php and processed in function
     * check_upload_mimes(), which "is used to filter that list against the filetype whitelist
     * provided by Multisite Super Admins at wp-admin/network/settings.php." Multisite installs must
     * respect this restriction, so any list we produce will be passed thru that function if it exists.
     *
     * This function is defined as public because it's a filter.
     *
     * @since 1.40
     *
     * @param	array	Mime types keyed by the file extension regex corresponding to those types
     * @param	mixed	User ID (integer) or object for checking against 'unfiltered_html' capability
     *
     * @return	array	Updated allowed MIME types
     */

    Does that solve your immediate issue?

    For the proposed filter, do you have any thoughts or guidance on how the WordPress Roles and Capabilities would be a part of the solution?

    Thread Starter podpirate

    (@podpirate)

    Thanks for the quick reply.
    I am now able to shrink down the allowed upload types back to the whitelisted file extensions. The security issue is now boiled down to a usability issue, which is a big gain.
    Anyway, there is still a little tweak. You used 0x7ffffff for filter priority. I guess you want to make sure, that your filter is the last one applied to upload_mimes list. On a 64bit system I can simply set my own filter priority to 0x80000000. On a stone-age 32bit system this won’t work (0x7fffffff is the highest possible value for a signed integer).

    Concerning filtering options tabs:
    I see two strategies, on how to avoid PHP uploads.
    The first on one would be quite simple, with no roles or capabilites involved. In includes/class-mla-settings.php just get the tablist through a private method instead of storing it in a class var. Like this:

    private function get_mla_options_tablist( ){
            $tablist = $mla_tablist = array(
                'general' => array( 'title' => __ ( 'General', 'media-library-assistant' ), 'render' => '_compose_general_tab' ),
                'view' => array( 'title' => __ ( 'Views', 'media-library-assistant' ), 'render' => '_compose_view_tab' ),
                'upload' => array( 'title' => __ ( 'Uploads', 'media-library-assistant' ), 'render' => '_compose_upload_tab' ),
                'mla_gallery' => array( 'title' => __ ( 'MLA Gallery', 'media-library-assistant' ), 'render' => '_compose_mla_gallery_tab' ),
                'custom_field' => array( 'title' => __ ( 'Custom Fields', 'media-library-assistant' ), 'render' => '_compose_custom_field_tab' ),
                'iptc_exif' => array( 'title' => 'IPTC/EXIF', 'render' => '_compose_iptc_exif_tab' ),
                'documentation' => array( 'title' => __ ( 'Documentation', 'media-library-assistant' ), 'render' => '_compose_documentation_tab' )
            );
            return apply_filters('mla_options_tabs',$tablist);
        }

    Everywhere you reference self::$tablist use self::get_mla_options_tablist() instead. In the _save_[tab]_settings methods check if the corresponding tab is present in the array returned by MLASettings::get_mla_options_tablist()

    For a coder it would be easy to write a mu-plugin, that simply does an unset($tablist['upload']) on the tablist. For you (just an idea…) it would open an opportunity to add a network settings with options like “Allow Blog admins to customize allowed MIME types”.

    Second approach would be to enable MIME Customization only to those who can alter PHP code on the server anyway (and therefore should know what they are doing). In WordPress this is expressed by the edit_plugins and edit_themes capability. I multisite only network admins have these capablities.
    This snippet should do the job:

    if ( current_user_can( 'edit_plugins' ) || current_user_can( 'edit_themes' ) ) {
            self::$tablist['uploads'] = array( /* whatever... */ );
        }

    Plugin Author David Lingren

    (@dglingren)

    Thank you for your update and for taking the time to think through and write up your ideas on implementation. I have restructured the code along the lines you suggested, implemented a new filter to modify the tab list and added an example to the mla-mapping-hooks-example.php.txt file in /media-library-assistant/examples. I will update and resolve this topic when the next version goes out.

    I decided against the Roles and Capabilities idea because it seems like overkill for the time being.

    The 0x7fffffff filter priority was deliberate. I wanted a value high enough to run after other plugins so I could capture additional MIME types they added to the WordPress list. I use the results to initialize MLA’s list the first time MLA is run. After that anything produced by other plugins is replaced by MLA’s list.

    I know that higher values are possible; it’s not a security measure, it’s a pragmatic choice. Perhaps I should use 0x7ffffffe to give stone-age 32bit systems an opportunity to override my filter 😉

    Thanks again for your help with this issue and for your interest in the plugin.

    Thread Starter podpirate

    (@podpirate)

    Thanks a lot, and keep up the good work!
    Looking forward to the next Update,
    joern

    Plugin Author David Lingren

    (@dglingren)

    I have released MLA version 1.82, which includes the new filter for modifying the Settings/Media Library Assistant tabs list. Let me know if you have any problems with it or further questions/suggestions on this topic. Thanks again for raising the issue, for your encouragement and for your interest in the plugin.

    Thread Starter podpirate

    (@podpirate)

    Hi David,
    Thank you very much for the Update.
    I already set up everything in my project, and everthing looks just fine.

    Just in case somebody else is running into the same issue like me (and stumbles upon this thread by accident), here’s my code that keeps upload MIME types under control of network admins:

    // put in a php file living in wp-content/mu-plugins/
    
    // always use WP MIME types
    function mla_restrict_mime($mime) {
    	// return WP's own whitelist
    	return check_upload_mimes( $mime );
    }
    // We need very very high filter priority here, to make sure filter is applied after MLA applies it's own filter.
    // (Notice: wont work on 32bit systems. Get a new server folks)
    add_filter('upload_mimes' , 'mla_restrict_mime' , 0x80000000 );
    
    // Hide Mime options tab.
    function mla_hide_upload_options( $tabs ){
    	// disable upload tab
    	unset($tabs['upload']);
    	return $tabs;
    }
    add_filter('mla_get_options_tablist','mla_hide_upload_options');
Viewing 6 replies - 1 through 6 (of 6 total)
  • The topic ‘Security question: Upload settings in WP Multisite with untrusted blog admins’ is closed to new replies.