summaryrefslogtreecommitdiff
path: root/modules/blogapi/blogapi.module
diff options
context:
space:
mode:
authorAngie Byron <webchick@24967.no-reply.drupal.org>2008-10-12 02:58:23 +0000
committerAngie Byron <webchick@24967.no-reply.drupal.org>2008-10-12 02:58:23 +0000
commit145e1ced25627632255a0891bb8130d4c2ef6491 (patch)
tree33abae7f8a4e1c5d56fbfe99f5ca8e0c63eeb2b0 /modules/blogapi/blogapi.module
parentacd5e95200790938c2b6b5042972100d47847a68 (diff)
downloadbrdo-145e1ced25627632255a0891bb8130d4c2ef6491.tar.gz
brdo-145e1ced25627632255a0891bb8130d4c2ef6491.tar.bz2
#319467: SA-2008-47 (#295053): Arbitrary file uploads in Blog API.
Diffstat (limited to 'modules/blogapi/blogapi.module')
-rw-r--r--modules/blogapi/blogapi.module131
1 files changed, 129 insertions, 2 deletions
diff --git a/modules/blogapi/blogapi.module b/modules/blogapi/blogapi.module
index ed1e337e2..554245f56 100644
--- a/modules/blogapi/blogapi.module
+++ b/modules/blogapi/blogapi.module
@@ -419,19 +419,66 @@ function blogapi_metaweblog_new_media_object($blogid, $username, $password, $fil
return blogapi_error($user);
}
+ $usersize = 0;
+ $uploadsize = 0;
+
+ $roles = array_intersect(user_roles(FALSE, 'administer content with blog api'), $user->roles);
+
+ foreach ($roles as $rid => $name) {
+ $extensions .= ' ' . strtolower(variable_get("blogapi_extensions_$rid", variable_get('blogapi_extensions_default', 'jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp')));
+ $usersize = max($usersize, variable_get("blogapi_usersize_$rid", variable_get('blogapi_usersize_default', 1)) * 1024 * 1024);
+ $uploadsize = max($uploadsize, variable_get("blogapi_uploadsize_$rid", variable_get('blogapi_uploadsize_default', 1)) * 1024 * 1024);
+ }
+
+ $filesize = strlen($file['bits']);
+
+ if ($filesize > $uploadsize) {
+ return blogapi_error(t('It is not possible to upload the file, because it exceeded the maximum filesize of @maxsize.', array('@maxsize' => format_size($uploadsize))));
+ }
+
+ if (_blogapi_space_used($user->uid) + $filesize > $usersize) {
+ return blogapi_error(t('The file can not be attached to this post, because the disk quota of @quota has been reached.', array('@quota' => format_size($usersize))));
+ }
+
+ // Only allow files with whitelisted extensions and convert remaining dots to
+ // underscores to prevent attacks via non-terminal executable extensions with
+ // files such as exploit.php.jpg.
+
+ $whitelist = array_unique(explode(' ', trim($extensions)));
+
$name = basename($file['name']);
+
+ if ($extension_position = strrpos($name, '.')) {
+ $filename = drupal_substr($name, 0, $extension_position);
+ $final_extension = drupal_substr($name, $extension_position + 1);
+
+ if (!in_array(strtolower($final_extension), $whitelist)) {
+ return blogapi_error(t('It is not possible to upload the file, because it is only possible to upload files with the following extensions: @extensions', array('@extensions' => implode(' ', $whitelist))));
+ }
+
+ $filename = str_replace('.', '_', $filename);
+ $filename .= '.' . $final_extension;
+ }
+
$data = $file['bits'];
if (!$data) {
return blogapi_error(t('No file sent.'));
}
- if (!$filepath = file_unmanaged_save_data($data, $name)) {
+ if (!$file = file_unmanaged_save_data($data, $filename)) {
return blogapi_error(t('Error storing file.'));
}
+ $row = new stdClass();
+ $row->uid = $user->uid;
+ $row->filepath = $file;
+ $row->filesize = $filesize;
+
+ drupal_write_record('blogapi_files', $row);
+
// Return the successful result.
- return array('url' => file_create_url($filepath), 'struct');
+ return array('url' => file_create_url($file), 'struct');
}
/**
* Blogging API callback. Returns a list of the taxonomy terms that can be
@@ -683,6 +730,81 @@ function blogapi_admin_settings() {
'#description' => t('Select the content types available to external blogging clients via Blog API. If supported, each enabled content type will be displayed as a separate "blog" by the external client.')
);
+ $blogapi_extensions_default = variable_get('blogapi_extensions_default', 'jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp');
+ $blogapi_uploadsize_default = variable_get('blogapi_uploadsize_default', 1);
+ $blogapi_usersize_default = variable_get('blogapi_usersize_default', 1);
+
+ $form['settings_general'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('File settings'),
+ '#collapsible' => TRUE,
+ );
+
+ $form['settings_general']['blogapi_extensions_default'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Default permitted file extensions'),
+ '#default_value' => $blogapi_extensions_default,
+ '#maxlength' => 255,
+ '#description' => t('Default extensions that users can upload. Separate extensions with a space and do not include the leading dot.'),
+ );
+
+ $form['settings_general']['blogapi_uploadsize_default'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Default maximum file size per upload'),
+ '#default_value' => $blogapi_uploadsize_default,
+ '#size' => 5,
+ '#maxlength' => 5,
+ '#description' => t('The default maximum file size a user can upload.'),
+ '#field_suffix' => t('MB')
+ );
+
+ $form['settings_general']['blogapi_usersize_default'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Default total file size per user'),
+ '#default_value' => $blogapi_usersize_default,
+ '#size' => 5,
+ '#maxlength' => 5,
+ '#description' => t('The default maximum size of all files a user can have on the site.'),
+ '#field_suffix' => t('MB')
+ );
+
+ $form['settings_general']['upload_max_size'] = array('#value' => '<p>'. t('Your PHP settings limit the maximum file size per upload to %size.', array('%size' => format_size(file_upload_max_size()))).'</p>');
+
+ $roles = user_roles(FALSE, 'administer content with blog api');
+ $form['roles'] = array('#type' => 'value', '#value' => $roles);
+
+ foreach ($roles as $rid => $role) {
+ $form['settings_role_' . $rid] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Settings for @role', array('@role' => $role)),
+ '#collapsible' => TRUE,
+ '#collapsed' => TRUE,
+ );
+ $form['settings_role_' . $rid]['blogapi_extensions_' . $rid] = array(
+ '#type' => 'textfield',
+ '#title' => t('Permitted file extensions'),
+ '#default_value' => variable_get('blogapi_extensions_' . $rid, $blogapi_extensions_default),
+ '#maxlength' => 255,
+ '#description' => t('Extensions that users in this role can upload. Separate extensions with a space and do not include the leading dot.'),
+ );
+ $form['settings_role_' . $rid]['blogapi_uploadsize_' . $rid] = array(
+ '#type' => 'textfield',
+ '#title' => t('Maximum file size per upload'),
+ '#default_value' => variable_get('blogapi_uploadsize_' . $rid, $blogapi_uploadsize_default),
+ '#size' => 5,
+ '#maxlength' => 5,
+ '#description' => t('The maximum size of a file a user can upload (in megabytes).'),
+ );
+ $form['settings_role_' . $rid]['blogapi_usersize_' . $rid] = array(
+ '#type' => 'textfield',
+ '#title' => t('Total file size per user'),
+ '#default_value' => variable_get('blogapi_usersize_' . $rid, $blogapi_usersize_default),
+ '#size' => 5,
+ '#maxlength' => 5,
+ '#description' => t('The maximum size of all files a user can have on the site (in megabytes).'),
+ );
+ }
+
return system_settings_form($form);
}
@@ -845,3 +967,8 @@ function _blogapi_get_node_types() {
return $types;
}
+
+function _blogapi_space_used($uid) {
+ return db_query('SELECT SUM(filesize) FROM {blogapi_files} f WHERE f.uid = :uid', array(':uid' => $uid))->fetchField();
+}
+