-2

I'm trying to make a website where users have their own creative spaces where anyone can see said spaces. The problem is that those users might hack my website by accessing the parent folders. I was wondering if there was a way to ensure the exclusivity of those folders.

the following is the structure I mentioned:

parent/
  child1/
     file1
     file2
     folder/
     image
  child2/
     file

I just want to make sure files from child1 will only be able to access others within child1 only. meaning that file1 can access folder/image, but not ../child2/file or ../../other_file

Also, I use PHP.

Martin
  • 22,212
  • 11
  • 70
  • 132

1 Answers1

1

Briefly;

  • Use a database to control authentication.
  • Use mod_Rewrite to hide PHP file locations.
  • Store user data files off the public area of your server account.
    • ABSOLUTELY CLEAN UPLOADED USER FILES FIRST!!
  • Use PHP Headers and file_get_contents() to present files as if they are native.

The below is only an example of one way to approach this broad topic

For example; let's look at Instagram; they use a complex version of the above system.

This is an instagram image:

https://instagram.flhr1-2.fna.fbcdn.net/v/t51.2885-15/e35/20987296_218244025372607_4512699619393667072_n.jpg?_nc_ht=instagram.flhr1-2.fna.fbcdn.net&_nc_cat=111&_nc_ohc=LwKoP3yHB_AAX-QA9yR&oh=d6d19ba6381de558e7260f44897f6010&oe=5E8FE8D7

You see all the stuff after the image file?

  • _nc_ht
  • _nc_cat
  • _nc_ohc
  • oh

These are trackers and definitions. These are used to ensure the image loaded is correct; if you load the URL without these you get:

https://instagram.flhr1-2.fna.fbcdn.net/v/t51.2885-15/e35/20987296_218244025372607_4512699619393667072_n.jpg

Which gives you:

"Bad URL Timestamp"

Because the .jpg file is NOT A JPEG. It is a PHP file which is pretending to be a core file, the file name also does not exist but is used to generate a .htaccess mod_rewrite,

so, applying this example to your scenario:

Request: /myfolder/mark/20987296_218244025372607_4512699619393667072_n.jpg

is

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/myfolder/(*.[^/]+)/([0-9]+)_([0-9]+)_([0-9]+)_n.jpg$ /imageProcessor.php?folder=$1&image=$2&var3=$3&var4=$4 [NC,L,QSA]

The PHP file imageProcessor.php will look something like:

<?php
// headers
// PHP tells the browser it is a JPEG file type.
Header("content-type: image/jpeg");

// validate $_GET data and  
if(is_numeric($_GET['image']) && $_GET['oh'] > (time() - 3600) ){ 

// check database of values; such as if this image is visible 
$imageData = $DatabaseObject->getImage((int)$_GET['image']);

// Load the result file path from the database, 
// check it fits the database value
if($_GET['folder'] === $imageData['user_folder'] && file_exists($imageData['user_folder'])){

// load the file with file_get_contents
$image = file_get_contents($imageData['image_path']);

}

print $image; 

Therefore you can build a complete system whereby what the user and browser sees at the front end is entirely different from what actually happens on the server; you can contain users in certain spaces defined by their database attributes according to their account values.

the above is AN EXTREMELY SIMPLE EXAMPLE but the core concepts should be enough to get you started, how you authenticate your users based on folder could be:

The user login hash can be any string of a fixed length that is generated when that user logs in and is unique in the database. This string can be uses in filenames or in Query Strings to identify the user, however $_SESSION data is far more reliable and can be more secret.

So $_SESSION['login_hash'] = "randomGeneratedCodeX";

MySQL:

user_id | user_name | user_folder | user_login_hash  
------------------------------------------------------------
  1     |   userA   |   mark      | randomGeneratedCodeX
  2     |   userB   |  jason      | randomCodeGeneratedZ

Therefore when the user accessses /myfolder/mark/234_464_7681.jpg the Mod_rewrite would actually access /imageProcessor.php?image=234....

Then your code can look in the database and find if the $_SESSION hashes compare; and find the folder:

SELECT user_folder FROM `users_table` WHERE user_login_hash = :sessionString

Where $_SESSION['login_hash'] === :sessionString = randomGeneratedCodeX. Then you can check if the image exists:

$imagePath = "/path/to/data/folders/".$imageData['user_folder']./".$_GET['image'].".jpg";
if(file_exists($imagePath) && $imageData['user_folder'] === $_GET['folder']){
    //File exists so load it into PHP and outpout the image to the browser!
    print file_get_contents($imagePath);
}

PLEASE NOTE that you should use a basic .htaccess to stop direct access to the data file by the browser, or store the file outside of the public_html directory so it is never accessible from the browser:

For example:

FILE: /yourServerAccount/path/to/data/folders/mark/234.jpg

URL: /yourServerAccount/public_html/imageProcessor.php

So this can give each of your users their own pseudo space and as they're logged in as one user they'd be hardcoded not to be able to load data from another users directory.

THE ABOVE IS AN EXTREMELY SIMPLE AND IMPERFECT EXAMPLE ONLY.

You need to read up on the concepts and ballparks presented above.

Bibilography:

... and many, many other links and useful informations ...

Martin
  • 22,212
  • 11
  • 70
  • 132
  • thank you for your comprehensive answer. You solve many problems I have. However, in my case I need to have actual html files running and they could access other files outside of themselves... So I could potentially get file thieves by just having them play with '../../writers/...' that's why I'm asking in the first place. I just want said html files to only have access within their own directory. Again, thank you for your answer. – Alex Blattner Feb 20 '20 at 22:26