Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

allow access to certain folder/files only for some users

I have a Weblication which provides access to certain pages only to some users. Now there are some files linked on these pages. If someone has the URL everyone can access these files (in this case the search engines). This should be changed! How can I protect such a directory? I thought about two possibilites:

  • htaccess: Enter username + password every time a new user is created -> not suitable for that type of project (would also need a second login)
  • download.php?file=xxx: Don't know how to include such one on all Links in Weblication (static pages)

Are there any other possibilities?

like image 769
testing Avatar asked Oct 23 '22 22:10

testing


2 Answers

Taken and translated from this link (but is only available in the WaybackMachine).

Personalised output with the help of mod_rewrite

With the help of the function wCheckPermissionViewFile php files can be personalized. It is sufficient to perform the permission check in the header of a file to suppress the output. If other file types should be personalised (e.g. ZIP, PDF, ...), wPermission.cgi or a custom php file can be used.

To save the editor some work for writing wPermission.cgi before every personalised link to a binary file, instead the Apache module mod_rewrite can be used. With this it is possible to convert every accessed link before execution. For example you could define that wPermission.cgi is in front of each webserver call. The direct execution could also be redirected with the help of a php file (no wPermission.cgi necessary).

Example of a .htaccess file via check from Perl (wPermission.cgi)

#Alle Dateien mit angegebener Endung über wPermission.cgi aufrufen.
RewriteEngine on
RewriteCond %{REQUEST_URI} .pdf$ [NC,OR]
RewriteCond %{REQUEST_URI} .doc$ [NC,OR]
RewriteCond %{REQUEST_URI} .xls$ [NC,OR]
RewriteCond %{REQUEST_URI} .ppt$ [NC,OR]
RewriteCond %{REQUEST_URI} .pps$ [NC,OR]
RewriteCond %{REQUEST_URI} .zip$ [NC,OR]
RewriteCond %{REQUEST_URI} .jpg$ [NC,OR]
RewriteCond %{REQUEST_URI} .jpeg$ [NC,OR]
RewriteCond %{REQUEST_URI} .png$ [NC,OR]
RewriteCond %{REQUEST_URI} .gif$ [NC]
RewriteRule (.*) /cgi-bin/wPermission.cgi?file=/de/dokumente/$1

Example of a .htacces file via check from PHP (e.g. download.php, see below)

#Alle Dateien mit angegebener Endung über die angegebene PHP-Datei aufrufen.
RewriteEngine on
RewriteCond %{REQUEST_URI} .pdf$ [NC,OR]
RewriteCond %{REQUEST_URI} .doc$ [NC,OR]
RewriteCond %{REQUEST_URI} .xls$ [NC,OR]
RewriteCond %{REQUEST_URI} .ppt$ [NC,OR]
RewriteCond %{REQUEST_URI} .pps$ [NC,OR]
RewriteCond %{REQUEST_URI} .zip$ [NC,OR]
RewriteCond %{REQUEST_URI} .jpg$ [NC,OR]
RewriteCond %{REQUEST_URI} .jpeg$ [NC,OR]
RewriteCond %{REQUEST_URI} .png$ [NC,OR]
RewriteCond %{REQUEST_URI} .gif$ [NC]
RewriteRule (.*) /de/download.php?path=/de/dokumente/$1

Explanation

If you would like to personalise all PDF and ZIP files within the directory /de/dokumente without changing the links, you could put a .htaccess file into that directory. In this file the redirect rules are defined.

The rules can be extended with arbitrary file extensions, NC stands for non case sensitive. Be aware that the rules are also inherited onto sub directories.

The binary files itself have to be checked in and provided with the according personalisation.

If you would like to check if the file is in a valid publishing time period (e.g. online or offline), then do the check before the permission check via PHP API wIsOnline.

Example: download.php for the implementation ".htacces file via check from PHP (e.g. download.php)"

<?php

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Dieses Skript erzwingt den Download von Dokumenten. PDF, DOC, XLS und PPT Dokumente werden je nach Browser angezeigt.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// Einlesen der Weblication(r) 4.x API:
require_once ($_SERVER["DOCUMENT_ROOT"]."/weblication/lib/WAPI/WAPI.inc");

$filenameRel = str_replace("..", "", $_GET['path']);
$filename    = $_SERVER['DOCUMENT_ROOT'].$filenameRel;

if(preg_match("/\.\w+$/", $filename) && !preg_match("/\.(php|php5|php4|xml|xsl|cgi|pl)$/", $filename) && !preg_match("/\/weblication\//", $filename) &&  file_exists( $filename ) ){
  if(wCheckPermissionViewFile($filenameRel) == 1){
    header("Pragma: no-cache");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: private", false);
    if(preg_match("/\.pdf/i", $filenameRel)){
      header("Content-Type: application/pdf");
    }
    else if(preg_match("/\.doc/i", $filenameRel)){
      header("Content-Type: application/msword");
    }
    else if(preg_match("/\.xls/i", $filenameRel)){
      header("Content-Type: application/msexcel");
    }
    else if(preg_match("/\.ppt/i", $filenameRel)){
      header("Content-Type: application/mspowerpoint");
    }
    else if(preg_match("/\.pps/i", $filenameRel)){
      header("Content-Type: application/mspowerpoint");
    }
    else if(preg_match("/\.jpg/i", $filenameRel)){
      header("Content-Type: image/jpg");
    }
    else if(preg_match("/\.jpeg/i", $filenameRel)){
      header("Content-Type: image/jpeg");
    }
    else if(preg_match("/\.png/i", $filenameRel)){
      header("Content-Type: image/png");
    }
    else if(preg_match("/\.gif/i", $filenameRel)){
      header("Content-Type: image/gif");
    }
    else{
      header("Content-Type: application/force-download");
      header("Content-Disposition: attachment; filename=\"".basename($filename)."\";" );
      header("Content-Transfer-Encoding: binary");
      header("Content-Length: ".filesize($filename));
    }
    readfile($filename);
  }
  else{
    print "Permission Denied!";
  }
}
else {
  print 'Sorry, wrong path or file does not exist on the server!';
  print '<br/><a href="javascript:history.back();">back</a>';
}
exit;

?> 

For newer versions of Weblication this link could help. It is in German, because the manufacturers main language is German.

like image 81
testing Avatar answered Oct 27 '22 09:10

testing


You could store all of your file in a non public directory and then write a page (much like you say with download.php?file=xxx) that checks the user has permission to access the file and then output to the browser.

Edit:

As you are using a CMS, I would presume that the user has a nice GUI that they can click to choose the file they wish to insert/link to? If this is the case, you could probably find the code that it uses to create the link and then prepend http://www.whatever.com/download.php?file= to the filename which would then route the download through your script.

like image 42
vimist Avatar answered Oct 27 '22 11:10

vimist