Question

J'utilise un plan d'hébergement web GoDaddy sur une plate-forme Windows. Cela n'a pas été mon choix - il doit faire avec une autre partie du site réel en utilisant ASP.NET (pas non plus mon choix).

J'ai une base de données SQL avec un tas d'entrées avec des informations client non sensibles. La clé primaire sur c'est un entier AutoIncrement, et j'ai une série de fichiers PDF qui correspondent à chacun de ces entiers (par exemple 555.pdf, 7891.pdf, etc).

Mon but est de restreindre l'accès direct à ces fichiers, je veux les utilisateurs d'avoir à passer par un processus de recherche et de connexion (PHP) en premier. Au départ, je comptais mettre les fichiers au-dessus du dossier public_html, mais GoDaddy refuse de me donner un accès root sans un serveur dédié (20 $ par mois d'eux).

La prochaine chose que je regardais en était HTACCESS. J'allais restreindre l'accès aux fichiers aux seuls scripts PHP en ne permettant l'accès à l'adresse IP (ou localhost / 127.0.0.1) du serveur. Malheureusement, cela ne fonctionne pas parce que GoDaddy ne fonctionne pas Apache sur ses serveurs Windows.

Je pourrais mettre les fichiers dans la base de données BLOB, mais cela devient malpropre vraiment quand je dois travailler avec eux rapidement (plus j'ai eu des problèmes avec cette approche).

Toutes les suggestions pour restreindre l'accès aux fichiers uniquement à un script PHP (readfile ())?

Était-ce utile?

La solution

Puisque vous ne pouvez pas mettre les fichiers partout, mais dans votre répertoire public_html, vous devrez aller pour la peur / haï méthode « sécurité par l'obscurité »

  1. Créer un sous-répertoire nommé de façon aléatoire pour stocker les fichiers dans: public_html / RANDOMGARBAGE

  2. Assurez-vous que le répertoire n'est pas browseable. Désactiver la navigation du répertoire (si vous le pouvez), et de mettre un document par défaut (index.html?) Là aussi, même si la navigation est activée, vous ne recevrez pas le répertoire liste.

  3. Ne pas stocker vos fichiers avec des noms devinables. Au lieu de les stocker avec l'ID de base de données, les stocker avec un nom salé + haché au lieu: $crypted_filename = sha1($real_filename . 'some hard-to-guess salt text'); (bien sûr, rendre plus complexe si vous avez besoin). Conservez le nom du fichier d'origine dans votre base de données. Donc, vous vous retrouvez avec quelque chose comme:

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

  4. Servir les fichiers via un script PHP - jamais un lien vers le fichier directement haché

    Télécharger

qui fait alors:

<?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");
    }

De cette façon, l'utilisateur ne verra jamais ce que votre « s00per seekrit » nom de fichier est, ils vont tout simplement voir leur succès du navigateur ...php?fileID=37 et lancer un téléchargement de secret file.pdf

En plus de cela, vous pouvez parfois renommer le sous-répertoire spécial pour quelque chose d'autre sur une base régulière, ainsi que modifier le texte du sel (ce qui nécessite alors vous mettez à jour tous les noms de fichiers hachés avec les nouvelles valeurs de SHA1).

Autres conseils

Vous pouvez simplement les cacher. C'est la sécurité par l'obscurité, mais il semble que votre meilleure option si vous ne pouvez pas non plus les garder hors de la racine web, ou trouver un moyen de dire au serveur de ne pas les servir directement.

Alors les coller dans un répertoire au hasard nommé:

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

Alors vous écrire un petit script PHP qui envoie les en-têtes appropriés et passer le contenu du fichier par.

par exemple:

<?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');

Maintenant, ce qui précède est vraiment pas mieux que de servir les fichiers directement (encore), puisque les gens peuvent encore augmenter le paramètre id dans la chaîne de requête.

Mais vous devriez être en mesure de comprendre comment gérer assez facilement l'autorisation.

Parce que PHP utilise les autorisations de l'utilisateur du serveur web, il n'y a aucun moyen de restreindre l'accès aux fichiers sans soit:

  • Les placer en dehors du docroot
  • Modification de la configuration du serveur Web pour l'accès à ces fichiers disallow
  • Modification du fichier de sorte qu'il sera interprété par le serveur Web, cachant ainsi son contenu

les mettre dans un compte de base de données en dehors de la docroot. Pour la troisième option, vous pouvez faire les fichiers PDF des fichiers PHP, mais honnêtement, ce serait assez alambiqué.

Je vous recommandons de contacter GoDaddy et voir si elles ont une certaine façon de configurer les autorisations de fichiers par répertoire.

Faire un inaccessable Web de dossier via chmod. PHP sera toujours en mesure d'inclure / require tout ce qui est sur le serveur, mais les utilisateurs ne pourront accéder aux fichiers jamais.

Exemple: Ceci est réglé sur 770, IE utilisateur et groupe peuvent en lecture / écriture / exécution, Autre ne peut rien faire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top