2009-09-04 13 views
5

Mam stronę, na której poszczególne strony mogą wymagać pewnych plików javascript lub CSS podłączonych do ich głowic. Próbuję zachować wszystko, co jest klientem, jeśli chodzi o zarządzanie tym procesem, zamiast wchodzić na FTP i sortować wszystko w kodzie, więc muszę mieć możliwość przesyłania plików css i js.Drupal Filefield nie będzie przesyłać plików javascript?

Mam uruchomione pole CCK i działa z plikami css, ale odmawia załadowania plików .js. Wydaje się natomiast, aby zobaczyć co Js jak „.js.txt”, a następnie na serwerze jako thisismyfile.js.txt

nie jest idealny pojawi się plik ...

Czy ktoś wie jak to obejść . Czy jest to problem typu MIME z Drupalem lub serwerem, czy też Drupal został skonfigurowany tak, aby uniknąć wysyłania skryptów i ataków hakerskich n00b.

Po przesłaniu plików zamierzam użyć trybu PHP na stronie lub węźle, aby wywołać drupal_add_css i drupal_add_js.

+0

Przypuszczam, że jest to zabezpieczenie. –

Odpowiedz

5

Patrząc na funkcję field_file_save_file() w field_file.inc z modułu FileField można znaleźć następujący fragment

// 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'; 
} 

Więc tak, jest to „rzecz bezpieczeństwa”, jak Jeremy domyślić.

Może łatka, która jest łatwa w celu uzyskania natychmiastowej "poprawki", ale to usunie tę, w przeciwnym razie użyteczną kontrolę bezpieczeństwa dla wszystkich pól plików używanych na stronie.

Dlatego bardziej szczegółowe obejście może być lepszym rozwiązaniem. Ponieważ chcesz mimo to dodawać pliki poprzez wywołania drupal_add_js() z kodu, możesz równie dobrze zmienić nazwę, dodając jakąś weryfikację, aby upewnić się, że możesz "zaufać" temu plikowi (np. Kto go przesłał, cokolwiek).


Edit: opcji dotyczących zmiany nazwy (i alternatywy) podczas wywoływania drupal_add_js():

  • Do zmiany nazwy pliku, patrzeć w funkcji file_move(). Problem polegałby na tym, że nie zaktualizuje odpowiadającego wpisu w tabeli plików, więc musiałbyś to również zrobić, gdyby operacja przenoszenia się powiodła. (Pole plików po prostu zapisuje "fid" odpowiedniego wpisu w tabeli plików, więc musisz go tam znaleźć przez "fid" i zmienić wpisy "filename", "filepath" i "filemime" zgodnie z twoją nazwą/move)
  • Alternatywnie można po prostu załadować zawartość pliku * .js.txt i dodać ten ciąg za pomocą opcji "w linii" pod numerem drupal_add_js(). Byłoby to mniej "eleganckie" i mogłoby być uderzeniem wydajności, ale jeśli nie są to ważne kryteria w twoim konkretnym przypadku, oznacza to mniej kłopotów.
  • Jeszcze jedna opcja to właśnie przekazująca plik * .js.txt do postaci drupal_add_js(), ignorując "niewłaściwe" rozszerzenie. Krótki test lokalny pokazał, że to działa (przynajmniej w firefoxie). Może to być rozwiązanie "najmniejszego wysiłku", ale wymagałoby to dodatkowych testów dotyczących różnych zachowań przeglądarki dotyczących używania "błędnie nazwanych" plików js.
+0

-1, co stanowiłoby zagrożenie dla bezpieczeństwa. – googletorp

+2

Ahem, tak, oczywiście (i wyraźnie wspomniano!) - dlatego właśnie umieściłem kurs "inicjał" i zaleciłem bardziej szczegółowe podejście. Będę edytować, aby to wyjaśnić. –

+0

Świetne, dzięki! Jak już wspomniałem powyżej, rejestracja zostanie wyłączona, a tylko konta administracyjne będą mogły przesyłać pliki, więc ryzyko bezpieczeństwa jest takie, jakie chcę podjąć. Pozdrowienia za wskazanie mi kodu: D – MrFidge

2

Dopuszczenie Drupal do przesyłania plików javascript byłoby zagrożeniem bezpieczeństwa, dlatego też nie pozwala na to, ale zamiast tego dodaje rozszerzenie .txt.Powodem jest to, że pliki js są wykonywalne wraz z php, pl, py, cgi, asp. Jeśli więc Drupal mógłby przesłać te pliki na serwer, złodzieje mogliby załadować plik i uruchomić go, robiąc różne nieprzyjemne rzeczy na swoim serwerze, w zasadzie wszystko jest możliwe. Najlepiej byłoby znaleźć inny sposób przesyłania plików, które są bezpieczne.

+1

Rzecz polega na tym, że jeśli ktokolwiek włamie się do moich haseł administracyjnych, będę miał więcej zmartwień niż "mogą przesłać skrypt". Usuwanie mojej bazy danych na przykład .. Strona nie będzie otwarta dla zwykłych użytkowników, aby się zarejestrować lub zrobić cokolwiek, rejestracja zostanie wyłączona. – MrFidge

+0

Jeśli zhakują ci przepustkę administratora, mogą trafić tylko na jedną stronę, jeśli załadują i wykonają plik js, mogą usunąć cały serwer, zmienić hasło roota i "wyprzedzić" serwer. Tak jak powiedziałem, mogą zrobić prawie wszystko. Oznacza to, że mogą zrobić wszystko, co javascript, co jest dużo, ponieważ jest to język programowania. – googletorp

0

Drupal również "munges" pliki javascript. Aby uniemożliwić Drupalowi automatyczne dodawanie podkreśleń do nazwy pliku, istnieje ukryta zmienna, która jest sprawdzana zanim nazwa pliku zostanie "zmanipulowana".

Ustawienie zmiennej na 1 rozwiązuje problem dla mnie (wraz ze zmianą REGEX w includes/file.inc).

Nienawidzę rąbania, ale wydaje mi się to kiepskim projektem. Pliki JavaScript nie są skryptami po stronie serwera, takimi jak php, py, pl, cgi i asp.

Możesz użyć dozwolonych ustawień rozszerzeń plików, aby zapobiec przesyłaniu skryptów php i innych po stronie serwera.

np

variable_set ('allow_insecure_uploads', 1);

Patrz: http://api.drupal.org/api/function/file_munge_filename/6

+0

Tak, właśnie o to się boję! W końcu mój problem rozwiązał się, ponieważ liczba użytkowników, którzy musieli skonfigurować i przesłać skrypty, a którzy nie mieli dostępu do FTP, była zerowa! – MrFidge

0

Więc js przesyłania plików do katalogu plików jest prawie niemożliwe.

Nawet jeśli uda ci się załadować czysto pliki .js, pliki te zostaną usunięte po wyczyszczeniu pamięci podręcznej.

Wszystkie pliki js znajdujące się wewnątrz katalogu plików zostaną usunięte za każdym razem, gdy zostanie uruchomiona funkcja drupal_clear_js_cache().

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

Więc Drupal widzi js pliki mieszkających w katalogu jako tymczasowego wysyłania plików.

Teraz rozumiem, dlaczego dołączają ".txt", ma to zapobiec ich usunięciu po wyczyszczeniu pamięci podręcznej.

Chyba jako kompromis, będę tylko ładować pliki .js ręcznie (przez FTP) do folderu/misc. :(

1

miałem podobną potrzebę, i znalazł sposób, aby ominąć zabezpieczenia przez pierwszą zmianę wartości zmiennej „allow_insecure_uploads” uruchamiając poniższy wiersz kodu w hook_install:

variable_set('allow_insecure_uploads', 1); 

potem w moduł dodać tę funkcję

/** 
* 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); 
} 

Co to robi to w hook_insert nazywają to sprawdza, czy plik ma rozszerzenie „.js.txt”. Jeśli robi to kopiuje je do nowej lokalizacji i zmienia jego nazwę. jest to po kontroli bezpieczeństwa, więc jest ok. nie sądzę, że trzeba się martwić o C ból jasne usuwanie plików js tak długo, jak nie umieścić je w katalogu files/js. Stworzyć swój własny katalog dla modułu ty i powinno być OK.

2

I w obliczu tej sytuacji, kiedy chciałem, aby umożliwić js plik należy przesłać jak (bez .txt i „application/javascript” typMIME) dla konkretnej dziedzinie. Również, nie chciał zmienić Drupal rdzeń ... oczywiście.

Musiałem więc utworzyć moduł implementujący hook_file_presave(). Działa to również w przypadku Multiupload File Widget, ponieważ jego hak jest na file_save().

Należy pamiętać, że trzeba zastąpić MYMODULE_NAME i MYFIELD_NAME według własnych wartości.

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, to jest dokładnie to, czego potrzebowałem. Dzięki! –

Powiązane problemy