VYPR
Low severityNVD Advisory· Published Mar 25, 2013· Updated Apr 29, 2026

CVE-2013-1835

CVE-2013-1835

Description

Moodle 2.x through 2.1.10, 2.2.x before 2.2.8, 2.3.x before 2.3.5, and 2.4.x before 2.4.2 allows remote authenticated administrators to obtain sensitive information from the external repositories of arbitrary users by leveraging the login_as feature.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
moodle/moodlePackagist
>= 2.0.0, < 2.2.82.2.8
moodle/moodlePackagist
>= 2.3.0, < 2.3.52.3.5
moodle/moodlePackagist
>= 2.4.0, < 2.4.22.4.2

Affected products

36
  • Moodle/Moodle36 versions
    cpe:2.3:a:moodle:moodle:2.0.0:*:*:*:*:*:*:*+ 35 more
    • cpe:2.3:a:moodle:moodle:2.0.0:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.0.1:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.0.2:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.0.3:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.0.4:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.0.5:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.0.6:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.0.7:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.0.8:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.0.9:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.1.0:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.1.1:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.1.10:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.1.2:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.1.3:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.1.4:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.1.5:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.1.6:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.1.7:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.1.8:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.1.9:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.2.0:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.2.1:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.2.2:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.2.3:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.2.4:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.2.5:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.2.6:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.2.7:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.3.0:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.3.1:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.3.2:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.3.3:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.3.4:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.4.0:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.4.1:*:*:*:*:*:*:*

Patches

3
ded4050f1bb0

MDL-36426 repository: Prevent login_as() users to access

https://github.com/moodle/moodleFrederic MassartFeb 4, 2013via ghsa
2 files changed · +44 9
  • lang/en/repository.php+1 1 modified
    @@ -154,7 +154,7 @@
     $string['nofilesavailable'] = 'No files available';
     $string['nomorefiles'] = 'No more attachments allowed';
     $string['nopathselected'] = 'No destination path select yet (double click tree node to select)';
    -$string['nopermissiontoaccess'] = 'No permission to access this repository';
    +$string['nopermissiontoaccess'] = 'No permission to access this repository.';
     $string['noresult'] = 'No search result';
     $string['norepositoriesavailable'] = 'Sorry, none of your current repositories can return files in the required format.';
     $string['norepositoriesexternalavailable'] = 'Sorry, none of your current repositories can return external files.';
    
  • repository/lib.php+43 8 modified
    @@ -487,6 +487,9 @@ abstract class repository {
         public $returntypes;
         /** @var stdClass repository instance database record */
         public $instance;
    +    /** @var string Type of repository (webdav, google_docs, dropbox, ...). */
    +    public $type;
    +
         /**
          * Constructor
          *
    @@ -519,6 +522,16 @@ public function __construct($repositoryid, $context = SYSCONTEXTID, $options = a
             $this->name = $this->get_name();
             $this->returntypes = $this->supported_returntypes();
             $this->super_called = true;
    +
    +        // Determining the type of repository if not set.
    +        if (empty($this->type)) {
    +            $matches = array();
    +            if (!preg_match("/^repository_(.*)$/", get_class($this), $matches)) {
    +                throw new coding_exception('The class name of a repository should be repository_<typeofrepository>, '.
    +                        'e.g. repository_dropbox');
    +            }
    +            $this->type = $matches[1];
    +        }
         }
     
         /**
    @@ -620,19 +633,41 @@ public static function get_types($visible=null) {
         }
     
         /**
    -     * Checks if user has a capability to view the current repository in current context
    +     * Checks if user has a capability to view the current repository.
          *
    -     * @return bool
    +     * @return bool true when the user can, otherwise throws an exception.
    +     * @throws repository_exception when the user does not meet the requirements.
          */
         public final function check_capability() {
    -        $capability = false;
    -        if (preg_match("/^repository_(.*)$/", get_class($this), $matches)) {
    -            $type = $matches[1];
    -            $capability = has_capability('repository/'.$type.':view', $this->context);
    +        global $USER;
    +
    +        // Ensure that the user can view the repository in the current context.
    +        $can = has_capability('repository/'.$this->type.':view', $this->context);
    +
    +        // Context in which the repository has been created.
    +        $repocontext = context::instance_by_id($this->instance->contextid);
    +
    +        // Prevent access to private repositories when logged in as.
    +        if (session_is_loggedinas()) {
    +            $can = false;
    +        }
    +
    +        // Ensure that the user can view the repository in the context of the repository.
    +        // Ne need to perform the check when already disallowed.
    +        if ($can) {
    +            if ($repocontext->contextlevel == CONTEXT_USER && $repocontext->instanceid != $USER->id) {
    +                // Prevent URL hijack to access someone else's repository.
    +                $can = false;
    +            } else {
    +                $can = has_capability('repository/'.$this->type.':view', $repocontext);
    +            }
             }
    -        if (!$capability) {
    -            throw new repository_exception('nopermissiontoaccess', 'repository');
    +
    +        if ($can) {
    +            return true;
             }
    +
    +        throw new repository_exception('nopermissiontoaccess', 'repository');
         }
     
         /**
    
6153c8040dd6

MDL-36426 repository: Prevent login_as() users to access

https://github.com/moodle/moodleFrederic MassartFeb 4, 2013via ghsa
2 files changed · +44 9
  • lang/en/repository.php+1 1 modified
    @@ -154,7 +154,7 @@
     $string['nofilesavailable'] = 'No files available';
     $string['nomorefiles'] = 'No more attachments allowed';
     $string['nopathselected'] = 'No destination path select yet (double click tree node to select)';
    -$string['nopermissiontoaccess'] = 'No permission to access this repository';
    +$string['nopermissiontoaccess'] = 'No permission to access this repository.';
     $string['noresult'] = 'No search result';
     $string['norepositoriesavailable'] = 'Sorry, none of your current repositories can return files in the required format.';
     $string['norepositoriesexternalavailable'] = 'Sorry, none of your current repositories can return external files.';
    
  • repository/lib.php+43 8 modified
    @@ -487,6 +487,9 @@ abstract class repository {
         public $returntypes;
         /** @var stdClass repository instance database record */
         public $instance;
    +    /** @var string Type of repository (webdav, google_docs, dropbox, ...). */
    +    public $type;
    +
         /**
          * Constructor
          *
    @@ -519,6 +522,16 @@ public function __construct($repositoryid, $context = SYSCONTEXTID, $options = a
             $this->name = $this->get_name();
             $this->returntypes = $this->supported_returntypes();
             $this->super_called = true;
    +
    +        // Determining the type of repository if not set.
    +        if (empty($this->type)) {
    +            $matches = array();
    +            if (!preg_match("/^repository_(.*)$/", get_class($this), $matches)) {
    +                throw new coding_exception('The class name of a repository should be repository_<typeofrepository>, '.
    +                        'e.g. repository_dropbox');
    +            }
    +            $this->type = $matches[1];
    +        }
         }
     
         /**
    @@ -620,19 +633,41 @@ public static function get_types($visible=null) {
         }
     
         /**
    -     * Checks if user has a capability to view the current repository in current context
    +     * Checks if user has a capability to view the current repository.
          *
    -     * @return bool
    +     * @return bool true when the user can, otherwise throws an exception.
    +     * @throws repository_exception when the user does not meet the requirements.
          */
         public final function check_capability() {
    -        $capability = false;
    -        if (preg_match("/^repository_(.*)$/", get_class($this), $matches)) {
    -            $type = $matches[1];
    -            $capability = has_capability('repository/'.$type.':view', $this->context);
    +        global $USER;
    +
    +        // Ensure that the user can view the repository in the current context.
    +        $can = has_capability('repository/'.$this->type.':view', $this->context);
    +
    +        // Context in which the repository has been created.
    +        $repocontext = context::instance_by_id($this->instance->contextid);
    +
    +        // Prevent access to private repositories when logged in as.
    +        if (session_is_loggedinas()) {
    +            $can = false;
    +        }
    +
    +        // Ensure that the user can view the repository in the context of the repository.
    +        // Ne need to perform the check when already disallowed.
    +        if ($can) {
    +            if ($repocontext->contextlevel == CONTEXT_USER && $repocontext->instanceid != $USER->id) {
    +                // Prevent URL hijack to access someone else's repository.
    +                $can = false;
    +            } else {
    +                $can = has_capability('repository/'.$this->type.':view', $repocontext);
    +            }
             }
    -        if (!$capability) {
    -            throw new repository_exception('nopermissiontoaccess', 'repository');
    +
    +        if ($can) {
    +            return true;
             }
    +
    +        throw new repository_exception('nopermissiontoaccess', 'repository');
         }
     
         /**
    
31581ae65df0

MDL-36426 repository: Prevent login_as() users to access private repositories

https://github.com/moodle/moodleFrederic MassartFeb 4, 2013via ghsa
17 files changed · +212 12
  • lang/en/repository.php+1 1 modified
    @@ -158,7 +158,7 @@
     $string['nofilesavailable'] = 'No files available';
     $string['nomorefiles'] = 'No more attachments allowed';
     $string['nopathselected'] = 'No destination path select yet (double click tree node to select)';
    -$string['nopermissiontoaccess'] = 'No permission to access this repository';
    +$string['nopermissiontoaccess'] = 'No permission to access this repository.';
     $string['noresult'] = 'No search result';
     $string['norepositoriesavailable'] = 'Sorry, none of your current repositories can return files in the required format.';
     $string['norepositoriesexternalavailable'] = 'Sorry, none of your current repositories can return external files.';
    
  • repository/coursefiles/lib.php+9 0 modified
    @@ -216,4 +216,13 @@ public function get_reference_file_lifetime($ref) {
             // this should be realtime
             return 0;
         }
    +
    +    /**
    +     * Is this repository accessing private data?
    +     *
    +     * @return bool
    +     */
    +    public function contains_private_data() {
    +        return false;
    +    }
     }
    
  • repository/equella/lib.php+9 0 modified
    @@ -437,4 +437,13 @@ public function get_reference_details($reference, $filestatus = 0) {
                 return get_string('lostsource', 'repository', '');
             }
         }
    +
    +    /**
    +     * Is this repository accessing private data?
    +     *
    +     * @return bool
    +     */
    +    public function contains_private_data() {
    +        return false;
    +    }
     }
    
  • repository/filesystem/lib.php+9 0 modified
    @@ -333,4 +333,13 @@ public function send_file($storedfile, $lifetime=86400 , $filter=0, $forcedownlo
                 send_file_not_found();
             }
         }
    +
    +    /**
    +     * Is this repository accessing private data?
    +     *
    +     * @return bool
    +     */
    +    public function contains_private_data() {
    +        return false;
    +    }
     }
    
  • repository/flickr_public/lib.php+9 0 modified
    @@ -550,4 +550,13 @@ public function supported_returntypes() {
         public function get_file_source_info($photoid) {
             return $this->build_photo_url($photoid);
         }
    +
    +    /**
    +     * Is this repository accessing private data?
    +     *
    +     * @return bool
    +     */
    +    public function contains_private_data() {
    +        return false;
    +    }
     }
    
  • repository/lib.php+79 11 modified
    @@ -487,6 +487,9 @@ abstract class repository {
         public $returntypes;
         /** @var stdClass repository instance database record */
         public $instance;
    +    /** @var string Type of repository (webdav, google_docs, dropbox, ...). Read from $this->get_typename(). */
    +    protected $typename;
    +
         /**
          * Constructor
          *
    @@ -558,6 +561,24 @@ public static function get_repository_by_id($repositoryid, $context, $options =
             }
         }
     
    +    /**
    +     * Returns the type name of the repository.
    +     *
    +     * @return string type name of the repository.
    +     * @since  2.5
    +     */
    +    public function get_typename() {
    +        if (empty($this->typename)) {
    +            $matches = array();
    +            if (!preg_match("/^repository_(.*)$/", get_class($this), $matches)) {
    +                throw new coding_exception('The class name of a repository should be repository_<typeofrepository>, '.
    +                        'e.g. repository_dropbox');
    +            }
    +            $this->typename = $matches[1];
    +        }
    +        return $this->typename;
    +    }
    +
         /**
          * Get a repository type object by a given type name.
          *
    @@ -620,19 +641,43 @@ public static function get_types($visible=null) {
         }
     
         /**
    -     * Checks if user has a capability to view the current repository in current context
    +     * Checks if user has a capability to view the current repository.
          *
    -     * @return bool
    +     * @return bool true when the user can, otherwise throws an exception.
    +     * @throws repository_exception when the user does not meet the requirements.
          */
         public final function check_capability() {
    -        $capability = false;
    -        if (preg_match("/^repository_(.*)$/", get_class($this), $matches)) {
    -            $type = $matches[1];
    -            $capability = has_capability('repository/'.$type.':view', $this->context);
    +        global $USER;
    +
    +        // Ensure that the user can view the repository in the current context.
    +        $can = has_capability('repository/'.$this->get_typename().':view', $this->context);
    +
    +        // Context in which the repository has been created.
    +        $repocontext = context::instance_by_id($this->instance->contextid);
    +
    +        // Prevent access to private repositories when logged in as.
    +        if ($can && session_is_loggedinas()) {
    +            if ($this->contains_private_data() || $repocontext->contextlevel == CONTEXT_USER) {
    +                $can = false;
    +            }
             }
    -        if (!$capability) {
    -            throw new repository_exception('nopermissiontoaccess', 'repository');
    +
    +        // Ensure that the user can view the repository in the context of the repository.
    +        // We need to perform the check when already disallowed.
    +        if ($can) {
    +            if ($repocontext->contextlevel == CONTEXT_USER && $repocontext->instanceid != $USER->id) {
    +                // Prevent URL hijack to access someone else's repository.
    +                $can = false;
    +            } else {
    +                $can = has_capability('repository/'.$this->get_typename().':view', $repocontext);
    +            }
    +        }
    +
    +        if ($can) {
    +            return true;
             }
    +
    +        throw new repository_exception('nopermissiontoaccess', 'repository');
         }
     
         /**
    @@ -1767,13 +1812,36 @@ public function is_visible() {
          */
         public function get_name() {
             global $DB;
    -        if ( $name = $this->instance->name ) {
    +        if ($name = $this->instance->name) {
                 return $name;
             } else {
    -            return get_string('pluginname', 'repository_' . $this->options['type']);
    +            return get_string('pluginname', 'repository_' . $this->get_typename());
             }
         }
     
    +    /**
    +     * Is this repository accessing private data?
    +     *
    +     * This function should return true for the repositories which access external private
    +     * data from a user. This is the case for repositories such as Dropbox, Google Docs or Box.net
    +     * which authenticate the user and then store the auth token.
    +     *
    +     * Of course, many repositories store 'private data', but we only want to set
    +     * contains_private_data() to repositories which are external to Moodle and shouldn't be accessed
    +     * to by the users having the capability to 'login as' someone else. For instance, the repository
    +     * 'Private files' is not considered as private because it's part of Moodle.
    +     *
    +     * You should not set contains_private_data() to true on repositories which allow different types
    +     * of instances as the levels other than 'user' are, by definition, not private. Also
    +     * the user instances will be protected when they need to.
    +     *
    +     * @return boolean True when the repository accesses private external data.
    +     * @since  2.5
    +     */
    +    public function contains_private_data() {
    +        return true;
    +    }
    +
         /**
          * What kind of files will be in this repository?
          *
    @@ -1806,7 +1874,7 @@ final public function get_meta() {
             $meta = new stdClass();
             $meta->id   = $this->id;
             $meta->name = format_string($this->get_name());
    -        $meta->type = $this->options['type'];
    +        $meta->type = $this->get_typename();
             $meta->icon = $OUTPUT->pix_url('icon', 'repository_'.$meta->type)->out(false);
             $meta->supported_types = file_get_typegroup('extension', $this->supported_filetypes());
             $meta->return_types = $this->supported_returntypes();
    
  • repository/local/lib.php+9 0 modified
    @@ -262,4 +262,13 @@ private function get_node_path(file_info $fileinfo) {
                 'name' => $fileinfo->get_visible_name()
             );
         }
    +
    +    /**
    +     * Is this repository accessing private data?
    +     *
    +     * @return bool
    +     */
    +    public function contains_private_data() {
    +        return false;
    +    }
     }
    
  • repository/merlot/lib.php+9 0 modified
    @@ -161,5 +161,14 @@ public function supported_returntypes() {
         public function supported_filetypes() {
             return array('link');
         }
    +
    +    /**
    +     * Is this repository accessing private data?
    +     *
    +     * @return bool
    +     */
    +    public function contains_private_data() {
    +        return false;
    +    }
     }
     
    
  • repository/recent/lib.php+9 0 modified
    @@ -203,4 +203,13 @@ public function file_is_accessible($source) {
         public function has_moodle_files() {
             return true;
         }
    +
    +    /**
    +     * Is this repository accessing private data?
    +     *
    +     * @return bool
    +     */
    +    public function contains_private_data() {
    +        return false;
    +    }
     }
    
  • repository/s3/lib.php+9 0 modified
    @@ -249,4 +249,13 @@ public static function type_config_form($mform, $classname = 'repository') {
         public function supported_returntypes() {
             return FILE_INTERNAL;
         }
    +
    +    /**
    +     * Is this repository accessing private data?
    +     *
    +     * @return bool
    +     */
    +    public function contains_private_data() {
    +        return false;
    +    }
     }
    
  • repository/upgrade.txt+5 0 modified
    @@ -8,6 +8,11 @@ http://docs.moodle.org/dev/Repository_API
     * repository::append_suffix() has been deprecated, use repository::get_unused_filename() if you need
       to get a file name which has not yet been used in the draft area.
     
    +* contains_private_data() is a new method to determine if a user 'logged in as' another user
    +  can access the content of the repository. The default is to return True (no access).
    +
    +* get_typename() returns the type of repository: dropbox, googledocs, etc...
    +
     === 2.4 ===
     
     * copy_to_area() can receive a new parameter called $areamaxbytes which controls the maximum
    
  • repository/upload/lib.php+9 0 modified
    @@ -288,4 +288,13 @@ public function get_listing($path = '', $page = '') {
         public function supported_returntypes() {
             return FILE_INTERNAL;
         }
    +
    +    /**
    +     * Is this repository accessing private data?
    +     *
    +     * @return bool
    +     */
    +    public function contains_private_data() {
    +        return false;
    +    }
     }
    
  • repository/url/lib.php+9 0 modified
    @@ -237,4 +237,13 @@ public function get_file_source_info($url) {
         public function supported_filetypes() {
             return array('web_image');
         }
    +
    +    /**
    +     * Is this repository accessing private data?
    +     *
    +     * @return bool
    +     */
    +    public function contains_private_data() {
    +        return false;
    +    }
     }
    
  • repository/user/lib.php+9 0 modified
    @@ -169,4 +169,13 @@ public function get_reference_file_lifetime($ref) {
             // this should be realtime
             return 0;
         }
    +
    +    /**
    +     * Is this repository accessing private data?
    +     *
    +     * @return bool
    +     */
    +    public function contains_private_data() {
    +        return false;
    +    }
     }
    
  • repository/webdav/lib.php+10 0 modified
    @@ -185,4 +185,14 @@ public static function instance_config_form($mform) {
         public function supported_returntypes() {
             return (FILE_INTERNAL | FILE_EXTERNAL);
         }
    +
    +
    +    /**
    +     * Is this repository accessing private data?
    +     *
    +     * @return bool
    +     */
    +    public function contains_private_data() {
    +        return false;
    +    }
     }
    
  • repository/wikimedia/lib.php+9 0 modified
    @@ -189,4 +189,13 @@ public function supported_returntypes() {
         public function get_file_source_info($url) {
             return $url;
         }
    +
    +    /**
    +     * Is this repository accessing private data?
    +     *
    +     * @return bool
    +     */
    +    public function contains_private_data() {
    +        return false;
    +    }
     }
    
  • repository/youtube/lib.php+9 0 modified
    @@ -202,4 +202,13 @@ public function supported_filetypes() {
         public function supported_returntypes() {
             return FILE_EXTERNAL;
         }
    +
    +    /**
    +     * Is this repository accessing private data?
    +     *
    +     * @return bool
    +     */
    +    public function contains_private_data() {
    +        return false;
    +    }
     }
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

9

News mentions

0

No linked articles in our index yet.