2009-09-04 32 views
5

Tôi có một trang web nơi các trang riêng lẻ có thể yêu cầu một số tệp javascript hoặc CSS được nối vào đầu của chúng. Tôi đang cố gắng để giữ cho mọi thứ phía khách hàng khi nói đến quản lý quá trình này, thay vì nhận được trên FTP và phân loại tất cả mọi thứ trong mã vì vậy tôi cần để có thể tải lên các tập tin css và js.Drupal Filefield sẽ không tải lên các tệp javascript?

Tôi đã thiết lập và chạy tệp CCK và nó hoạt động với các tệp css, nhưng nó từ chối tải lên tệp .js. Nó thay vì dường như xem mỗi .js là ".js.txt" và sau đó là tập tin xuất hiện trên máy chủ như thisismyfile.js.txt

Không lý tưởng ...

Có ai biết làm thế nào để làm việc xung quanh này . Đây có phải là vấn đề về loại mime với Drupal hay máy chủ, hay là Drupal được thiết lập để tránh việc tải lên tập lệnh và tấn công hack n00b.

Khi các tệp được tải lên, tôi định sử dụng chế độ PHP trên trang hoặc nút để gọi drupal_add_cssdrupal_add_js.

+0

Khi đoán đó là điều bảo mật. –

Trả lời

5

Nhìn vào field_file_save_file() chức năng trong field_file.inc từ mô-đun filefield, bạn có thể tìm thấy những đoạn sau

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

Vì vậy, có, đó là một 'an ninh điều', như Jeremy đoán.

Bạn có thể vá RegEx để sửa ngay lập tức, nhưng điều đó sẽ xóa hoàn toàn kiểm tra bảo mật hữu ích này cho tất cả các trường tệp được sử dụng trên trang web.

Vì vậy, cách giải quyết cụ thể hơn có thể là cách tiếp cận tốt hơn. Vì bạn muốn thêm các tệp qua drupal_add_js() cuộc gọi từ mã anyways, bạn cũng có thể thực hiện đổi tên ở đó, thêm một số loại xác minh để đảm bảo bạn có thể 'tin tưởng' tệp (ví dụ: ai đã tải lên tệp đó, bất kỳ điều gì).


Edit: tùy chọn Về để đổi tên (và thay thế) khi gọi drupal_add_js():

  • Đối đổi tên tập tin, nhìn vào file_move() chức năng. Một vấn đề với điều này sẽ được rằng nó sẽ không cập nhật các mục tương ứng trong bảng tập tin, vì vậy bạn sẽ phải làm điều đó cũng có, nếu hoạt động di chuyển thành công. (Trường tệp chỉ lưu trữ 'fid' của mục tương ứng trong bảng tệp, vì vậy bạn cần tìm nó ở đó bằng 'fid' và thay đổi các mục nhập 'filename', 'filepath' và 'filemime' theo tên của bạn/move)
  • Ngoài ra, bạn chỉ có thể tải nội dung của tệp * .js.txt và thêm chuỗi đó với tùy chọn 'nội tuyến' là drupal_add_js(). Điều này sẽ ít 'thanh lịch' và có thể là một hit hiệu suất, nhưng nếu đó không phải là tiêu chí quan trọng trong trường hợp cụ thể của bạn, thì sẽ ít rắc rối hơn.
  • Một tùy chọn khác sẽ là chỉ cần chuyển tệp * .js.txt như là drupal_add_js(), bỏ qua phần mở rộng 'sai'. Một thử nghiệm địa phương ngắn cho thấy rằng công trình này (ít nhất là trong firefox). Đây có thể là giải pháp 'ít nỗ lực nhất', nhưng sẽ cần một số thử nghiệm bổ sung liên quan đến hành vi trình duyệt khác nhau liên quan đến việc sử dụng tệp js 'bị đặt tên sai'.
+0

-1 sẽ là một nguy cơ bảo mật. – googletorp

+2

Ahem, vâng, rõ ràng (và được đề cập một cách rõ ràng!) - đó là lý do tại sao tôi đặt _could_ in nghiêng và đề xuất một cách tiếp cận cụ thể hơn. Tôi sẽ chỉnh sửa để làm rõ điều này. –

+0

Tuyệt vời, cảm ơn! Như tôi đã nói ở trên, đăng ký sẽ bị vô hiệu hóa và chỉ tài khoản quản trị mới có thể tải tệp lên, vì vậy rủi ro bảo mật là một trong những điều tôi sẵn sàng thực hiện. Chúc mừng vì đã chỉ cho tôi mã số: D – MrFidge

2

Cho phép Drupal tải lên tệp javascript sẽ là một nguy cơ bảo mật, đó cũng là lý do tại sao nó không cho phép bạn làm điều đó, nhưng thay vào đó gắn thêm phần mở rộng .txt.Lý do là các tệp js có thể thực thi cùng với php, pl, py, cgi, asp. Vì vậy, nếu Drupal có thể tải các tệp đó lên máy chủ, có thể những người làm ác sẽ tải lên một tệp và chạy nó làm mọi thứ khó chịu trên máy chủ của bạn, về cơ bản mọi thứ đều có thể. Điều tốt nhất là tìm cách tải lên các tệp khác an toàn.

+1

Thing là - nếu bất cứ ai hack mật khẩu quản trị của tôi, tôi sẽ lo lắng nhiều hơn "họ có thể tải lên một tập lệnh". Xóa cơ sở dữ liệu của tôi chẳng hạn .. Trang web sẽ không mở cho người dùng chung để đăng ký hoặc làm bất cứ điều gì, đăng ký sẽ bị vô hiệu hóa. – MrFidge

+0

Nếu họ hack bạn quản trị vượt qua họ chỉ có thể nhấn một trang web, nếu họ tải lên và thực thi một tập tin js, họ có thể xóa toàn bộ máy chủ, thay đổi mật khẩu gốc và 'vượt qua' máy chủ. Như tôi đã nói họ có thể làm hầu hết mọi thứ. Đó là họ có thể làm bất cứ điều gì javascript có thể đó là rất nhiều vì nó là một ngôn ngữ lập trình. – googletorp

0

Drupal cũng "chèn" tệp javascript. Để ngăn không cho Drupal tự động thêm dấu gạch dưới vào tên tệp, có một biến ẩn được kiểm tra trước khi tên tệp được "mung".

Đặt biến thành 1 giải quyết vấn đề cho tôi (cùng với thay đổi REGEX trong bao gồm/tệp.inc).

Tôi ghét lõi hacking, nhưng điều này có vẻ như là một thiết kế kém cho tôi. Các tệp Javascript không phải là các tập lệnh phía máy chủ như php, py, pl, cgi và asp.

Bạn có thể sử dụng cài đặt tiện ích mở rộng tệp được phép để ngăn không cho tải lên php và các đoạn mã phía máy chủ khác.

ví dụ:

variable_set ('allow_insecure_uploads', 1);

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

+0

Vâng đó là về nó tôi sợ! Cuối cùng, vấn đề của tôi đã giải quyết chính nó khi số lượng người dùng cần thiết để cấu hình và tải lên các tập lệnh và những người không có quyền truy cập FTP là số không! – MrFidge

0

Vì vậy, tải lên .js file vào thư mục file là khá nhiều không thể.

Thậm chí nếu bạn quản lý để tải các tệp .js được sạch sẽ, các tệp này sẽ bị xóa khi bộ nhớ cache bị xóa.

Bất kỳ tệp js nào nằm trong thư mục tệp sẽ bị xóa bất cứ khi nào hàm drupal_clear_js_cache() được thực hiện.

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

Vì vậy, Drupal thấy .js file sống trong thư mục tập tin tải lên là tạm thời.

Bây giờ tôi hiểu lý do tại sao chúng được thêm ".txt", nó là để ngăn chặn chúng bị xóa khi bộ nhớ cache bị xóa.

Để thỏa hiệp, tôi đoán tôi sẽ chỉ tải lên các tệp .js theo cách thủ công (qua FTP) vào thư mục/misc. :(

1

Tôi đã có một nhu cầu tương tự, và tìm thấy một cách để có được xung quanh an ninh bằng cách đầu tiên thay đổi giá trị biến 'allow_insecure_uploads' bằng cách chạy dòng mã này trong hook_install của bạn:

variable_set('allow_insecure_uploads', 1); 

Sau đó, trong một mô-đun bổ sung chức năng này

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

Điều này không là trong hook_insert gọi nó kiểm tra nếu một tập tin có phần mở rộng ".js.txt". Nếu nó có phải nó sao chép nó vào một vị trí mới và đổi tên nó. Đây là sau khi kiểm tra an ninh để ok của nó.Tôi không nghĩ rằng bạn cần phải lo lắng về c xóa rõ ràng các tập tin js của bạn miễn là bạn không đặt chúng trong thư mục files/js. Tạo thư mục của riêng bạn cho bạn module và bạn nên ok.

2

Tôi phải đối mặt với tình huống này khi tôi muốn cho phép tệp .js tải lên như (không có .txt và với 'ứng dụng/javascript' mimetype) cho một trường cụ thể. Ngoài ra, tôi không muốn thay đổi lõi Drupal ... tất nhiên.

Vì vậy, tôi cần tạo một mô-đun triển khai hook_file_presave(). Điều này cũng làm việc cho Multiupload File Widget, vì móc của nó là trên file_save().

Lưu ý rằng bạn sẽ phải thay thế MYMODULE_NAMEMYFIELD_NAME bằng các giá trị của riêng bạn.

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, đây chính xác là những gì tôi cần. Cảm ơn! –

Các vấn đề liên quan