2009-09-04 4 views
5

У меня есть сайт, на котором отдельные страницы могут потребовать, чтобы некоторые javascript или CSS-файлы попадали в их головы. Я стараюсь держать все на стороне клиента, когда дело доходит до управления этим процессом, вместо того, чтобы попасть на FTP и сортировать все в коде, поэтому мне нужно иметь возможность загружать файлы css и js.Drupal Filefield не будет загружать файлы javascript?

У меня есть файловое поле CCK и работает, и оно работает с css-файлами, но оно отказывается загружать файлы .js. Вместо этого он, кажется, смотреть каждые .js как «.js.txt», а затем на сервере как thisismyfile.js.txt

Не идеальный файл выглядит ...

Кто-нибудь знает, как обойти эту проблему , Является ли это проблемой типа mime с Drupal или сервером, или Drupal настроен для того, чтобы избежать загрузки скриптов и хакерских атак n00b.

После загрузки файлов я намереваюсь использовать режим PHP на странице или узле для вызова drupal_add_css и drupal_add_js.

+0

Угадайте, это вещь безопасности. –

ответ

5

Глядя на field_file_save_file() функции в field_file.inc от модуля FileField, вы можете найти следующий фрагмент

// Rename potentially executable files, to help prevent exploits. 
if (preg_match('/\.(php|pl|py|cgi|asp|js)$/i', $file->filename) && (substr($file->filename, -4) != '.txt')) { 
    $file->filemime = 'text/plain'; 
    $file->filepath .= '.txt'; 
    $file->filename .= '.txt'; 
} 

Так что да, это «безопасность вещь», как догадалась Джереми.

может патч, который RegEx для немедленного исправления, но который полностью удалит эту полезную проверку безопасности для всех файловых полей, используемых на сайте.

Таким образом, более конкретный обходной путь может быть лучшим подходом. Так как вы хотите добавить файлы через drupal_add_js() звонки с кода в любом случае, вы также можете переименовать их, добавив какую-то проверку, чтобы убедиться, что вы можете «доверять» файлу (например, кто его загрузил, что угодно).


Edit: опции, касающиеся переименования (и варианты) при вызове drupal_add_js():

  • Для переименования файла, смотрите в функцию file_move(). Проблема с этим состояла бы в том, что он не будет обновлять соответствующую запись в таблице файлов, поэтому вам также нужно будет это сделать, если операция перемещения завершилась успешно. (Файловое поле просто хранит «fid» соответствующей записи в таблице файлов, поэтому вам нужно найти его там «fid» и изменить записи «filename», «filepath» и «filemime» в соответствии с вашим переименованием/move)
  • В качестве альтернативы вы можете просто загрузить содержимое файла * .js.txt и добавить эту строку с опцией 'inline' от drupal_add_js(). Это было бы менее «элегантно» и могло бы быть хитом производительности, но если это не важные критерии в вашем конкретном случае, это меньше проблем.
  • Еще одним вариантом будет , просто передающий файл * .js.txt как есть drupal_add_js(), игнорируя «неправильное» расширение. Короткий локальный тест показал, что это работает (по крайней мере, в firefox). Это может быть решением «наименьшего усилия», но потребуется некоторое дополнительное тестирование в отношении поведения браузера в отношении использования «misnamed» js-файлов.
+0

-1, что будет представлять угрозу безопасности. – googletorp

+2

Ах, да, очевидно (и упоминается явно!) - вот почему я положил _could_ курсивом и рекомендовал более конкретный подход. Я отредактирую, чтобы прояснить это. –

+0

Отлично, спасибо! Как я сказал выше, регистрация будет отключена, и только учетные записи администратора смогут загружать файлы, поэтому риск для безопасности - это тот, который я готов принять. Приветствия, указывающие мне на код: D – MrFidge

2

Предоставление Drupal для загрузки файлов javascript будет представлять угрозу безопасности, а также поэтому не позволяет вам это делать, а вместо этого добавляет расширение .txt.Причина в том, что js-файлы исполняются вместе с php, pl, py, cgi, asp. Поэтому, если Drupal может загрузить эти файлы на сервер, злоумышленники смогут загрузить файл и запустить его, делая всевозможные неприятные вещи на вашем сервере, в принципе все возможно. Лучше всего было бы найти другой способ загрузки файлов, которые являются безопасными.

+1

Вещь - если кто-то взломает мои пароли администрирования, я буду больше беспокоиться, чем «они могут загрузить сценарий». Например, удалите мою базу данных. Сайт не будет открыт для обычных пользователей, чтобы зарегистрироваться или сделать что-либо, регистрация будет отключена. – MrFidge

+0

Если они взломают ваш админ-пропуск, они могут попасть только на один сайт, если они загружают и запускают файл js, они могут удалять весь сервер, изменять пароль root и «обгонять» сервер. Как я уже сказал, они могут делать почти все. То есть они могут делать все, что есть javascript, что очень много, поскольку это язык программирования. – googletorp

0

Drupal также "munges" javascript файлы. Чтобы запретить Drupal автоматически добавлять символы подчеркивания к имени файла, есть скрытая переменная, которая проверяется до того, как имя файла «munged».

Установка переменной в 1 решает проблему для меня (наряду с изменением REGEX в include/file.inc).

Ненавижу хакерское ядро, но для меня это кажется плохим дизайном. Файлы Javascript не являются серверными сценариями, такими как php, py, pl, cgi и asp.

Вы можете использовать настройки разрешенных файлов, чтобы запретить загрузку php и других серверных сценариев.

например:

variable_set ('allow_insecure_uploads', 1);

См: http://api.drupal.org/api/function/file_munge_filename/6

+0

Да, это из-за этого я боюсь! В конце концов, моя проблема решена, так как количество пользователей, которым нужно было настраивать и загружать скрипты и у кого не было FTP-доступа, было нулевым! – MrFidge

0

Так загрузки .js файлы в директорию файлов практически невозможно.

Даже если вам удастся загрузить файлы .js, эти файлы будут удалены при очистке кеша.

Любые файлы js, которые находятся внутри каталога файлов, будут удаляться всякий раз, когда выполняется функция drupal_clear_js_cache().

http://api.drupal.org/api/function/drupal_clear_js_cache/6

Так Drupal видит .js файлы, живущие в каталоге загрузки файлов в качестве временного.

Теперь я понимаю, почему они добавляют «.txt», чтобы предотвратить их удаление при очистке кеша.

Как компромисс, я думаю, что я просто загружу файлы .js вручную (через FTP) в папку/misc. :(

1

У меня была подобная необходимость, и нашли способ обойти безопасности при первом изменении значения переменной «allow_insecure_uploads», запустив эту строку кода в hook_install:

variable_set('allow_insecure_uploads', 1); 

Тогда в модуль добавить эту функцию

/** 
* Implementation of FileField's hook_file_insert(). 
*/ 
function MODULE_NAME_file_insert(&$file) { 
    //look for files with the extenstion .js.txt and rename them to just .js 
    if(substr($file->filename, -7) == '.js.txt'){ 
    $file_path = $file->filepath; 
    $new_file_path = substr($file_path, 0, strlen($file_path)-4); 
    file_move($file_path, $new_file_path); 

    $file->filepath = $file_path; 
    $file->filename = substr($file->filename, 0, strlen($file->filename)-4); 
    $file->filemime = file_get_mimetype($file->filename); 
    $file->destination = $file->filepath; 
    $file->status = FILE_STATUS_TEMPORARY; 
    drupal_write_record('files', $file); 
} 

Что это делает в hook_insert называют это проверяет, если файл имеет расширение «.js.txt». Если это не копирует его на новое место и переименовывает его. Это после проверки безопасности, так что это нормально. Я не думаю, что вам нужно беспокоиться о c если вы не поместите их в каталог files/js. Создайте свой собственный каталог для своего модуля, и вы должны быть в порядке.

2

Я столкнулся с такой ситуацией, когда захотел разрешить загрузку файла .js как есть (без .txt и с mimetype приложения/javascript) для определенного поля. Кроме того, я не хотел менять Drupal core ... конечно.

Так что мне нужно было создать модуль, реализующий hook_file_presave(). Это также работает для виджета Multiupload File Widget, так как его крючок находится на file_save().

Обратите внимание, что вам придется заменить MYMODULE_NAME и MYFIELD_NAME своими собственными значениями.

function MYMODULE_NAME_file_presave($file) { 

    // Bypass secure file extension for .js for field_additional_js field only 
    if((isset($file->source) && strpos($file->source, "MYFIELD_NAME") !== FALSE) && substr($file->filename, strlen($file->filename) - 7) == ".js.txt") { 

     // Define new uri and save previous 
     $original_uri = $file->uri; 
     $new_uri = substr($file->destination, null, -4); 

     // Alter file object 
     $file->filemime = 'application/javascript'; 
     $file->filename = substr($file->filename, null, -4); 
     $file->destination = file_destination($new_uri, FILE_EXISTS_RENAME); 
     $file->uri = $file->destination; 

     // Move fil (to remove .txt) 
     file_unmanaged_move($original_uri, $file->destination); 

     // Display message that says that 
     drupal_set_message(t('Security bypassed for .js for this specific field (%f).', array('%f' => $file->filename))); 
    } 
} 
+0

+100, это именно то, что мне нужно. Благодаря! –

 Смежные вопросы

  • Нет связанных вопросов^_^