Make WordPress Core


Ignore:
Timestamp:
02/26/2023 03:17:45 PM (3 years ago)
Author:
SergeyBiryukov
Message:

Upgrade/Install: Introduce WP_Automatic_Updater::is_allowed_dir() method.

As part of determining whether to perform automatic updates, WordPress checks if it is running within a version-controlled environment, recursively looking up the filesystem to the top of the drive, looking for a Subversion, Git, Mercurial, or Bazaar directory, erring on the side of detecting a VCS checkout somewhere.

This commit avoids a PHP warning if the open_basedir directive is in use and any of the directories checked in the process are not allowed:

is_dir(): open_basedir restriction in effect. File(/.git) is not within the allowed path(s)

Follow-up to [25421], [25700], [25764], [25835], [25859].

Props costdev, markjaquith, meyegui, dd32, arnolp, robin-labadie, hellofromTonya, afragen, pbiron, SergeyBiryukov.
Fixes #42619.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/class-wp-automatic-updater.php

    r55411 r55425  
    5858
    5959        /**
     60         * Checks whether access to a given directory is allowed.
     61         *
     62         * This is used when detecting version control checkouts. Takes into account
     63         * the PHP `open_basedir` restrictions, so that WordPress does not try to access
     64         * directories it is not allowed to.
     65         *
     66         * @since 6.2.0
     67         *
     68         * @param string $dir The directory to check.
     69         * @return bool True if access to the directory is allowed, false otherwise.
     70         */
     71        public function is_allowed_dir( $dir ) {
     72                if ( is_string( $dir ) ) {
     73                        $dir = trim( $dir );
     74                }
     75
     76                if ( ! is_string( $dir ) || '' === $dir ) {
     77                        _doing_it_wrong(
     78                                __METHOD__,
     79                                sprintf(
     80                                        /* translators: %s: The "$dir" argument. */
     81                                        __( 'The "%s" argument must be a non-empty string.' ),
     82                                        '$dir'
     83                                ),
     84                                '6.2.0'
     85                        );
     86
     87                        return false;
     88                }
     89
     90                $open_basedir = ini_get( 'open_basedir' );
     91
     92                if ( empty( $open_basedir ) ) {
     93                        return true;
     94                }
     95
     96                $open_basedir_list = explode( PATH_SEPARATOR, $open_basedir );
     97
     98                foreach ( $open_basedir_list as $basedir ) {
     99                        if ( '' !== trim( $basedir ) && str_starts_with( $dir, $basedir ) ) {
     100                                return true;
     101                        }
     102                }
     103
     104                return false;
     105        }
     106
     107        /**
    60108         * Checks for version control checkouts.
    61109         *
     
    103151                foreach ( $vcs_dirs as $vcs_dir ) {
    104152                        foreach ( $check_dirs as $check_dir ) {
    105                                 $checkout = @is_dir( rtrim( $check_dir, '\\/' ) . "/$vcs_dir" );
     153                                if ( ! $this->is_allowed_dir( $check_dir ) ) {
     154                                        continue;
     155                                }
     156
     157                                $checkout = is_dir( rtrim( $check_dir, '\\/' ) . "/$vcs_dir" );
    106158                                if ( $checkout ) {
    107159                                        break 2;
Note: See TracChangeset for help on using the changeset viewer.