تقييد الوصول إلى الملف - اقرأ فقط من خلال PHP [مغلق

StackOverflow https://stackoverflow.com/questions/3472770

  •  28-09-2019
  •  | 
  •  

سؤال

أنا أستخدم خطة استضافة ويب Godaddy على منصة Windows. لم يكن هذا خياري - يتعلق الأمر بجزء مختلف من الموقع الفعلي باستخدام ASP.NET (ليس أيضًا خياري).

لدي قاعدة بيانات SQL مع مجموعة من الإدخالات مع بعض معلومات العملاء غير الحساسة. المفتاح الأساسي في هذا هو عدد صحيح تلقائي ، ولدي سلسلة من ملفات PDF التي تتطابق مع كل من تلك الأعداد الصحيحة (على سبيل المثال 555.pdf ، 7891.pdf ، إلخ).

هدفي هو تقييد الوصول المباشر إلى هذه الملفات ، أريد أن يضطر المستخدمون إلى الذهاب إلى عملية البحث والتسجيل (PHP) أولاً. في الأصل ، خططت لوضع الملفات فوق مجلد public_html ، لكن Godaddy يرفض أن يعطيني الوصول إلى الجذر بدون خادم مخصص (20 دولارًا شهريًا منها).

الشيء التالي الذي نظرت إليه هو htaccess. كنت سأقوم بتقييد الوصول إلى الملفات إلى البرامج النصية PHP فقط من خلال السماح فقط بالوصول إلى عنوان IP الخاص بالخادم (أو LocalHost/127.0.0.1). لسوء الحظ ، هذا لا يعمل لأن Godaddy لا يعمل على Apache على خوادم Windows.

يمكنني وضع الملفات في النقط في قاعدة البيانات ، لكن هذا يوضح حقًا عندما أحتاج إلى العمل معهم بسرعة (بالإضافة إلى أنني واجهت بعض المتاعب في هذا النهج).

أي اقتراحات لتقييد الوصول إلى الملفات فقط إلى البرنامج النصي PHP (ReadFile ())؟

هل كانت مفيدة؟

المحلول

نظرًا لأنه لا يمكنك وضع الملفات في أي مكان ولكن في دليل public_html الخاص بك ، يجب عليك الذهاب إلى طريقة "الأمان عن طريق الغموض" الخوف/المكروه

  1. قم بإنشاء دليل فرعي محمي عشوائيًا لتخزين الملفات في: public_html/randomarbage

  2. تأكد من أن الدليل غير قابل للتصفح. تعطيل تصفح الدليل (إذا استطعت) ، ووضع مستند افتراضي (index.html؟) هناك أيضًا ، لذلك حتى إذا كان التصفح قيد التشغيل ، فلن تحصل على قائمة الدليل.

  3. لا تقم بتخزين ملفاتك بأسماء قابلة للتخمين. بدلاً من تخزينها بمعرف قاعدة البيانات ، قم بتخزينها باسم مملح+تجزئة بدلاً من ذلك: $crypted_filename = sha1($real_filename . 'some hard-to-guess salt text'); (بالطبع ، اجعل هذا أكثر تعقيدًا إذا كنت بحاجة إلى). تخزين اسم الملف الأصلي في قاعدة البيانات الخاصة بك. لذلك ينتهي بك الأمر بشيء مثل:

    public_html/RANDOMGARBAGE/5bf1fd927dfb8679496a2e6cf00cbe50c1c87145 public_html/RANDOMGARBAGE/7ec1f0eb9119d48eb6a3176ca47380c6496304c8

  4. يقدم الملفات عبر برنامج نصي PHP - لا ترتبط أبدًا باسم ملف الهلسيات مباشرة

    تحميل

الذي يفعل ذلك:

<?php

    $fileID = (int)$_GET['fileID'];

    $crypted_file = sha1($fileID . 'some hard-to-guess salt text');

    $full_path = 'public_html/RANDOMGARBAGE/' . $crypted_file;
    if (is_readable($full_path)) {
         if(user_is_allowed_to_see_this_file()) {
             /// send file to user with readfile()
             header("Content-disposition: attachment; filename=$ORIGINAL_FILENAME");
             readfile($full_path);
         } else {
             die("Permission denied");
         }
    } else {
        /// handle problems here
        die("Uh-oh. Can't find/read file");
    }

وبهذه الطريقة ، لن يرى المستخدم أبدًا ما هو اسم ملف "S00Per Seekrit" الخاص بك ، وسوف يرون فقط متصفحهم ضرب ...php?fileID=37 وابدأ تنزيل secret file.pdf

علاوة على ذلك ، يمكنك أحيانًا إعادة تسمية الدليل الفرعي الخاص إلى شيء آخر على أساس منتظم ، وكذلك تغيير نص الملح (الذي يتطلب منك بعد ذلك تحديث جميع أسماء الملفات مع قيم SHA1 الجديدة).

نصائح أخرى

يمكنك ببساطة إخفاءهم. إنه أمر أمان ، ولكن يبدو أنه أفضل خيارك إذا لم تتمكن من إبعادهم عن الجذر على الويب ، أو إيجاد طريقة لإخبار الخادم بعدم تقديمها مباشرة.

لذا التمسهم في بعض الدليل المسمى بشكل عشوائي:

asd8b8asd8327bh/123.pdf
asd8b8asd8327bh/124.pdf
asd8b8asd8327bh/125.pdf
...

ثم اكتب لنفسك نصًا صغيرًا من PHP الذي سيرسل الرؤوس المناسبة ، وتمرير محتويات الملف من خلال.

فمثلا:

<?PHP
//pdf.php
$id = $_GET['id'];

//make sure nobody is doing anything sneaky. is_numeric() might do the trick if the IDs are always integers.
if (!some_validation_passes($id)){
  die();
}
<?php

header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="'.$id.'.pdf"');
readfile('asd8b8asd8327bh'.$id.'pdf');

الآن ، ما سبق ليس أفضل من مجرد خدمة الملفات مباشرة (حتى الآن) ، حيث لا يزال بإمكان الأشخاص زيادة معلمة المعرف في سلسلة الاستعلام.

لكن يجب أن تكون قادرًا على معرفة كيفية التعامل مع التفويض بسهولة.

نظرًا لأن PHP يستخدم أذونات مستخدم خادم الويب ، فلا توجد طريقة لتقييد الوصول إلى الملفات دون:

  • وضعهم خارج docroot
  • تغيير تكوين خادم الويب لعدم السماح بالوصول إلى تلك الملفات
  • تغيير الملف بحيث يتم تفسيره بواسطة خادم الويب ، وبالتالي إخفاء محتوياته

وضعهم في قاعدة بيانات يعتبر خارج docroot. بالنسبة للخيار الثالث ، يمكنك جعل ملفات PDFS PHP ، ولكن بصراحة ، سيكون ذلك معقدًا جدًا.

أنصحك بالاتصال بـ Godaddy ومعرفة ما إذا كان لديهم طريقة لتكوين أذونات ملفات لكل دليل.

اجعل شبكة مجلد لا يمكن الوصول إليها عبر CHMOD. سيظل PHP قادرًا على تضمين/طلب ما هو موجود على الخادم ، لكن المستخدمين لن يتمكنوا من الانتقال إلى الملفات على الإطلاق.

مثال: تم تعيين هذا على 770 ، يمكن لمستخدم ومجموعة القراءة/الكتابة/التنفيذ ، لا يمكن للآخرون فعل أي شيء.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top