webForumDet fria alternativet

skydda filer

5 svar · 440 visningar · startad av Tulork

TulorkMedlem sedan aug. 2004903 inlägg
#1

Jag är intresserad utav olika sätt/förslag för att skydda filer i webbroten för att förhindra http://adress/mapp/fil.fil

Så här funkar vårt system just nu:

Vi kan skapa ett användarkonto där vi igenom ett administrativgränssnitt kan ladda upp filer till specifikt konto. Filerna landar i olika kategorier beroende på vad man valt när man uploadade. Man kan sedan logga in på de olika kontona och ladda ner de olika filerna i dem olika kategorierna.

Vid upload av filer läggs filnamn och ID på den vi uploadade till samt kategori, vid inloggning så länkar vi filerna genom att jämnföra ID på filen och ID på sessionen och lägger till filnamnet i länkningen som är hämtat i databasen.

Filerna ligger blandade i en mappstruktur i webbroten..alltså inte speciellt säkert om man vet vad filerna heter. Just nu har vi indexfiler i varje mapp så att man inte kan surfa in i mappen...inte den bästa lösningen men det är temporärt eftersom vi utvecklar fortfarande.

Mina frågor är:

Hur lätt är det att ta reda på vilka filer som finns i mapparna, även om man inte kan surfa in i mappen och se dem? Kan vi på något sätt med htaccess förhindra detta utan att påverka vårt system?

Vi vet att det kanske går att lägga dem utanför webbroten, men då måste hela vårt system antagligen byggas om och dessutom har vi ingen aning om hur vi ska fixa länkningen om filerna ligger utanför.

slutsats: hjälp :birp

egxezexMedlem sedan jan. 200786 inlägg
#2

Jag passar på att fråga i samma tråd..
Skulle gärna vilja veta hur man länkar till filer utanför webroten.. Har sökt lite och funderar på om readfile() skulle vara nåt, men jag har ingen aning om hur den funkar.
Någon som kan komma med ett kodexempel hur man länkar till en mapp t.ex /usr/local/tmp/filer

mUTANTMedlem sedan mars 200533 inlägg
#3

Att lägga filer utanför rooten är extremt lätt, och att pusha ut filen utanför rooten till användaren är lätt och smidigt det också.

Det man använder sig av är headers. Ett enkelt downloadscript kan se ut såhär:

$url = DIR_SAFE_FILES . $filename;

där DIR_SAFE_FILES är en konstant med dir namnet, under windows t.ex C:/inetpub/mysite/files/ + filnamnet som vi förmodligen hämtar från någon db.

Du kan lägga in extra checkar som: if (file_exists($url)) {
för att vara helt säker på att besökaren/kunden fått det han ska ha.

PHP's egna readfile funktion går att använda men den slöar ner mina transfers från 1,500kb/s till 245kb/s vilket inte är acceptabelt... så använder en hemsnickrad funktion:

function readfile_chunked($filename, $retbytes=true) {
$chunksize = 1*(1024*1024); // how many bytes per chunk
$buffer = '';
$cnt = 0;

$handle = fopen($filename, 'rb');
if ($handle === false) {
return false;
}

while (!feof($handle)) {
$buffer = fread($handle, $chunksize);
echo $buffer;
ob_flush();
flush();
if ($retbytes) {
$cnt += strlen($buffer);
}
}
$status = fclose($handle);

if ($retbytes && $status) {
return $cnt; // return num. bytes delivered like readfile() does
}
return $status;
}

Nu till magin:

/* Send the requested file with header(). */
header("Content-Description: File Transfer");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".basename($url)."\";");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($url));
set_time_limit(0);
$sebytes = readfile_chunked($url, true) or die("File not found.");

Vi ändrar helt enkelt response headern för sidan, vilket resulterar i en download ruta/save as.

Ni kan senare använda $sebytes variablen för att verifiera att kunden fått hem hela filen, vid fullständig download håller $sebytes hela filens size, vid avbruten/misslyckad returerar den 0.

TulorkMedlem sedan aug. 2004903 inlägg
#4

hmm verkar intressant. Men jag e osäker på hur jag ska modifieradet vi redan har. Varning, det är relativt mkt kod, men ajg uppskattar verkligen hjälp!

Detta är upload delen:

<?php
ob_start();
session_start();
include "../setts/variabler.php";

// Kolla om inloggad = sessionen satt
if (!isset($_SESSION['sess_userlevel']) || $_SESSION['sess_userlevel'] != "admin") {

  header("refresh: 5;url=../konto.php");

  echo "Du har inte behörighet till den här sidan";
  exit;
}
?>
<html>
<head>
<link rel=StyleSheet href="../setts/style.css" TYPE="text/css">
</head>
<body class="back">
<?php
include "../setts/conn.php"; // Databasanslutningen

if (isset ($_GET['RefID'])){

$queryn = "SELECT user FROM $mem_table WHERE id ='$RefID' ";
$resultn = mysql_query($queryn) or die('Query failed: Du har kanske inte valt någon annvändare...' . mysql_error());

$line = mysql_fetch_array($resultn, MYSQL_ASSOC);
// Printing results in HTML
echo "Du redigerar användaren: $line[user]<br><br>";
echo "<strong>OBS!</strong> stora filer kan ta lång tid att skicka! Vänta på tills uppladdningen är klar innan du byter sida"; 

// Free resultset
mysql_free_result($resultn);
} 

if (isset($_FILES['uplfile'])) {
	

	// Kontrollera att det angavs en fil
	if(empty($_FILES['uplfile']['name']))
		die('<br><br><STRONG>Ingen fil har valts</STRONG>');

	// Kontrollera storleken
	if($_FILES['uplfile']['size'] > $maxsize)
		die('<br><br><STRONG>Filen du valde är för stor. Maxstorleken är '.(string)($maxsize/1024/1024).' MB.</STRONG>');

	// Kontrollera filtypen
	$types = explode(',', $filetypes);
	$file = explode('.', $_FILES['uplfile']['name']);
	$extension = $file[sizeof($file)-1];
	if(!in_array(strtolower($extension), $types))
		die('<br><br><STRONG>Du har en felaktig filtyp. Endast .jpg,gif,png,doc,zip,ppt,txt,pdf är tillåtet!</STRONG>');
	

	// Generera unikt filnamn
 	$bokstav = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6');
//  	$thefile = $_FILES['uplfile']['name'];
					
	$img = $bokstav[rand(0, count($bokstav)-1)];
	
//  	if (file_exists($upload_dir_mark.$thefile) || ($upload_dir_purc.$thefile) || ($upload_dir_deve.$thefile) || ($upload_dir_news.$thefile)) {
// 		$thefile = $img.$thefile;
// 	}
	
	

	if (isset($_POST['komment'])) {
		
		if ($_POST['kategori']=='marketing' && $line[user] != NEWSLETTER){
		
			$thefile = 'Marketing_'.$_FILES['uplfile']['name'];

			if (file_exists($upload_dir_mark.$thefile)) {
		 		$thefile = $img.'_'.$thefile;
			}

			$query1 = "INSERT INTO UserFiles (filename, RefID, Kommentar, Kategori, Date) VALUES ('$thefile','$RefID','$komment3','marketing', $date)";
			mysql_query($query1) or die('Query failed-Marketing problem!' . mysql_error());
		
			if (is_uploaded_file($_FILES['uplfile']['tmp_name']) && move_uploaded_file($_FILES['uplfile']['tmp_name'],$upload_dir_mark.$thefile)) {
				
				echo"<br><strong><p class=\"warning\">Success!</strong><p>";
				echo "<br>Filen <strong>$thefile</strong> har nu laddats upp till användaren <strong>$line[user]</strong> <br> med kommentaren: <strong>$komment3 </strong>";

			}

		}	
	
		if ($_POST['kategori']=='purchase' && $line[user] != NEWSLETTER){
		
			$thefile = 'Purchase_'.$_FILES['uplfile']['name'];
	
			if (file_exists($upload_dir_purc.$thefile)) {
		 		$thefile = $img.'_'.$thefile;
			}
			
			$query2 = "INSERT INTO UserFiles (filename, RefID, Kommentar, Kategori, Date) VALUES ('$thefile','$RefID','$komment3','purchase', $date)";
			mysql_query($query2) or die('Query failed-Purchase problem!' . mysql_error());
						
			if (is_uploaded_file($_FILES['uplfile']['tmp_name']) && move_uploaded_file($_FILES['uplfile']['tmp_name'],$upload_dir_purc.$thefile)) {
				
				echo"<br><strong><p class=\"warning\">Success!</strong><p>";
				echo "<br>Filen <strong>$thefile</strong> har nu laddats upp till användaren <strong>$line[user]</strong> <br> med kommentaren: <strong>$komment3 </strong>";

			}
		}	

		if ($_POST['kategori']=='development' && $line[user] != NEWSLETTER){
		
			$thefile = 'Development_'.$_FILES['uplfile']['name'];

			if (file_exists($upload_dir_deve.$thefile)) {
		 		$thefile = $img.'_'.$thefile;
			}

			$query3 = "INSERT INTO UserFiles (filename, RefID, Kommentar, Kategori, Date) VALUES ('$thefile','$RefID','$komment3','development', $date)";
			mysql_query($query3) or die('Query failed-Development problem!' . mysql_error());
			
			if (is_uploaded_file($_FILES['uplfile']['tmp_name']) && move_uploaded_file($_FILES['uplfile']['tmp_name'],$upload_dir_deve.$thefile)) {
				
				echo"<br><strong><p class=\"warning\">Success!</strong><p>";
				echo "<br>Filen <strong>$thefile</strong> har nu laddats upp till användaren <strong>$line[user]</strong> <br> med kommentaren: <strong>$komment3 </strong>";

			}
		}

			

		if ($_POST['submit'] && $line[user] == NEWSLETTER){
				
			$thefile = 'Development_'.$_FILES['uplfile']['name'];

			if (file_exists($upload_dir_news.$thefile)) {
		 		$thefile = $img.'_'.$thefile;
			}

			$query4 = "INSERT INTO UserFiles (filename, RefID, Kommentar, Kategori, Date) VALUES ('$thefile','all','$komment3','newsletter', $date)";
			mysql_query($query4) or die('Query failed-Newsletter problem!' . mysql_error());
				
			if (is_uploaded_file($_FILES['uplfile']['tmp_name']) && move_uploaded_file($_FILES['uplfile']['tmp_name'],$upload_dir_news.$thefile)) {
				echo"<br><strong><p class=\"warning\">Success!</strong><p>";
				echo "<br>Filen <strong>$thefile</strong> har nu laddats upp till  <strong>alla</strong> <br> med kommentaren: <strong>$komment3 </strong>";
			}
		}

	}

	if (!$_POST['kategori'] && $line[user] != NEWSLETTER){
		echo"<br><br><strong><p class=\"warning\">Du har inte valt någon kategori. Filen laddades INTE upp!</strong><p>";
	}
	} 

  ?>
	
	
	<form action="<?php echo $_SERVER['PHP_SELF'] ."?RefID=".$_GET['RefID'],"&komment=".$_POST['komment'],"&kategori=".$_POST['kategori']; ?>"  method="post" enctype="multipart/form-data">
	<p>Fil:<p>
	<input type="file" name="uplfile"><br>
	<p>Kommentar:<p>
	<input type="text" name="komment"><br>

<?php if($line[user] != NEWSLETTER){
?>
	Välj under vilken kategori filen  ska laddas:<br>
	
	<input type="radio" name="kategori" value="marketing">Marketing<br>
	
	<input type="radio" name="kategori" value="purchase">Purchase<br>
	
	<input type="radio" name="kategori" value="development">Development<br>
<?}
?>	
	<!--<input type="radio" name="kategori" value="newsletter">Newsletter<br><br>-->
	<input type="submit" name="submit" value="Ladda upp filen"><br>
	</form>
	<br>
	
	
		
	
  <?php

ob_end_flush();
?>

</body>
</html>
TulorkMedlem sedan aug. 2004903 inlägg
#5

Detta är delen som visar filerna (konto delen)

<?php
ob_start();
session_start();
// Kolla om inloggad = sessionen satt
if (!isset($_SESSION['sess_user'])){
  header("Location: index.php");
  exit;
}
if (isset($_GET['logout'])){
  session_unset();
  session_destroy();
  header("Location: index.php");
  exit;
}
?>
<html>
<head>
<link rel=StyleSheet href="setts/style.css" TYPE="text/css">
<script language="JavaScript" type="text/JavaScript">
<!--
function MM_swapImgRestore() { //v3.0
var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;
}

function MM_preloadImages() { //v3.0
var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
   var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
   if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
}

function MM_findObj(n, d) { //v4.01
var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
   d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
if(!x && d.getElementById) x=d.getElementById(n); return x;
}

function MM_swapImage() { //v3.0
var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
  if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
}
//-->
</script> 

</head>
<body class="back" onLoad="MM_preloadImages('bilder/butts/mark2.jpg','bilder/butts/news2.jpg','bilder/butts/devel2.jpg','bilder/butts/purch2.jpg')">
<table border="0" align="center" width="100%">
<tr>
<td align="center">
<a href="konto.php?Kategori=Marketing" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('Marketing','','bilder/butts/mark2.jpg',1)"><img src="bilder/butts/mark.jpg"  name="Marketing"  border="0"></a>
<a href="konto.php?Kategori=Purchase" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('Purchase','','bilder/butts/purch2.jpg',1)"><img src="bilder/butts/purch.jpg"  name="Purchase"  border="0"></a>
<a href="konto.php?Kategori=Development" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('Development','','bilder/butts/devel2.jpg',1)"><img src="bilder/butts/devel.jpg"  name="Development" border="0"></a>
<a href="konto.php?Kategori=Newsletter" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('newsletter','','bilder/butts/news2.jpg',1)"><img src="bilder/butts/news.jpg"  name="newsletter" border="0"></a><br><br>

</td>
</tr>
</table>

<?
include "setts/conn.php"; // Databasanslutningen
include "setts/variabler.php";

$query6 = "SELECT * FROM $mem_table WHERE ID = $refID";
$result6 = mysql_query($query6) or die('Query failed: ' . mysql_error());
$Usern = mysql_fetch_array($result6, MYSQL_ASSOC);

if(!$_GET['Kategori']){
echo "<strong><u>::Welcome</strong> ";
echo $Usern['user'];
echo "</u><br><br>You have successfully gained access to sensecos filearea.<br>";
echo "Here you can browse your files by clicking on one of the images above.";
echo "<br><br><strong>::How does it work?</strong><br>";
echo "Above this text you can see different images, by holding your mouse over an image<br>
      you will see what every image reprents.Choose your category you wish to view and click<br>
      on it with your mouse. Now you will see every file available in that category and by clicking<br>
      the filename, you can download the file.<br><br>
      To come back to this page, simply use the <strong>Home</strong> button listen above the files<br><br>
      when you want to leave this site, make sure you use the <strong>Log out</strong> funktion in the bottom right corner.<br>
      This is to prevent unauthorized persones gaining access to your files.
      ";

}

//#####################################################
//Hämtar filnamnet som valdes vid inläggning av filen##
//#####################################################

	if ($_GET['Kategori'] == "Marketing"){
			
		$kat = 'marketing';
	}
	if ($_GET['Kategori'] == "Purchase"){
		
		$kat = 'purchase';
	}
	if ($_GET['Kategori'] == "Development"){
			
		$kat = 'development';
	}
	if ($_GET['Kategori'] == "Newsletter"){
		
		$kat = 'newsletter';
	}

	if ($_GET['Kategori']){	
		echo "<table align=\"center\">\n"; 
		echo "<td class=\"text3\"><strong>Files</strong></td>"; 
		echo "<td class=\"text3\"><strong>Comments</strong></td>";
		echo "<td class=\"text3\"><strong>Date</strong></td>"; 
		echo "</tr>"; 

		
	

$query2 = "SELECT id, Filename, Kommentar, Kategori, Date FROM $file_table WHERE RefID = 'all' && Kategori = '$kat' || RefID = '$refID' && Kategori = '$kat' ORDER BY 'Date' DESC, 'id' DESC";
$result2 = mysql_query($query2) or die('Query failed: ' . mysql_error());

while($resultRow = mysql_fetch_array($result2, MYSQL_ASSOC)) {
// För lite extra säkerhet så kollar vi att filen finns i verkligheten också
if(file_exists($uploadFolder."/".$resultRow['fileName']))
?>
<tr> 

<td class="text"><img src="setts/img/folder.gif" width="10" hight="10"> <a target="blank" href="<?php echo "download/$kat/".$resultRow['Filename']."" ?>  "> <?php echo $resultRow[Filename]?></a></td> 
<td class="text"><?php echo $resultRow[Kommentar]?></td> 
<td class="text"><?php echo $resultRow[Date]?></td>
</tr> 

<?

}
echo "<a href=\"konto.php?RefID='$refID'\">Home</a>\n";
/*echo "$kat";*/ 
//-----------------
?>
<p> test </p>
<?

//--------------

}
ob_end_flush();
?>
</body>
</html>

När vi laggt upp filerna ser det ut ungefär så här i databasen:

 
 ID        Filename                        RefID   Kommentar   Kategori         Datum
| 6522 | n_Marketing_haha.JPG  | 92    | jjkl                | marketing     | 20070328 |
| 6508 | asdasd.JPG                    | all    | hgjghj           | newsletter    | 20070328 |
| 6504 | asdasd.JPG                    | all    | asfasfasfff    | Purchase      | 20070328 |
| 6505 | asdasd.JPG                    | all    | nedfldfaer    | Development| 20070328 |
TulorkMedlem sedan aug. 2004903 inlägg
#6

Det är nu löst. Vill tacka så hemskt mycket för exemplet du gav oss mUTANT, med hjälp utav det kunde vi modifiera det vi hade och integrera det med viss förändring.

Nu uploadas alla filer utanför roten och säkerheten är utökad med många %

143 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
140 ms — hämta tråd, inlägg och bilagor (db)