Secure upload files in Laravel - laravel-5

I have a Laravel 5 project in which I am uploading files in database in Medium Blob format.
But uploading files in database takes some extra time to execute.
Uploading files in database is a secured way to keep files safe from crawlers or some bots.
I have tried to Upload files to the Public folder. But the crawlers can open these files.
Is there any possible way to upload files in the file system?
So that the Crawlers cannot open these files.
I want these files to be Secured

you can upload them outside of the public scope. For example, storage/ folder is a good place. Also, you can grab them using the file system manager. Take a look:
$image = \Storage::get('file.jpg');
Edit
A correct laravel installation just allow the content of public/ to be accesible via web browser. If other directories as storage/ or resources/ are public too, then you installation is really incorrect.
Said that, once you upload the files in storage/ folder nobody can access them except by you using the \Storage facade. When you call for example \Storage::get('file.jpg'); it returns an stream of bits that you can allocate them in a temporary folder and then display it in the webside. Once the request has finished, the image will disappear again from public domain.

No need to change the directory this can be achieved by two ways
LazyOne Answer using .htaccess
AND
Using robots.txt
I will suggest to implement both .htaccess and robots.txt as some cheap crawlers ignore robots.txt but they can't ignore .htaccess

You can follow this method
image-accessibility-for-authenticated-users-only
As this only allows authorized uses to view image

Related

Symbolic link from public/storage to storage/app/public still makes the files in the storage directory accessible from the web

What I have done
When I researched about storing files in laravel. I came across two approaches.
Storing the assets directly inside the public folder.
Creating a symbolic link from public/storage to
storage/app/public
When I researched about which one two use, I came across this stack overflow link. 👉 Difference between storing files in public directory and in storage in Laravel 5.4
In this link in the top answer it was mentioned,
Public folder means files will be publicly accessible.
For example an image stored in
public/images/my-image.jpegcan be viewed by anyone by
going to mysite.com/images/my-image.jpeg
However, files stored in storage directory are only available to your
app.
👆 Since, including in the mentioned stack overflow post above, and many other posts I have read on different platforms implied the fact that files in the public directory are web accessible whereas the files inside the storage directory are not, I tried to test this by storing files both in the public directory and in the storage directory one at a time, and then checking if the files are accessible through the web url.
My attempts went as below,
First I added the path images/ in the public
directory and placed some images (Let us say
test1.jpg, test2.jpg and
test3.jpg) into that directory. Then inside my blade
template for the src attribute of my
img tags I referred to them as
URL('images/test1.jpg') etc... and they were indeed
rendered on the webpage. Then I also tried to access the images from
the url by going to
http://localhost:8000/images/test.jpg. The result was
as expected, The images were rendered on the web page + they were
accessible from the url
Then I ran the command php artisan storage:link
on the console, which according to the articles I read, should
create a symbolic link between the directories
public/storage and storage/app/public.
As soon as I ran the command, I got a new folder called
storage created in the public
directory. Then I moved all my images to that
public/storage directory. Then set the
src attribute my img tags as
URL('storage/test1.img') etc... the images were
rendered on the web page. Then I tried to check if the images are
still accessible from the url. for that on the url bar I went to
http://localhost:8000/storage/test1.jpg. The
images were STILL ACCESSIBLE from the url.
Problem
However, according to the answer I have mentioned and some other similar links, I expected those images to not be accessible from the url in the 2) above since the images should now be actually in the storage/app/public which we have created a symbolic link to from public/storage. (Files inside the storage directory should not be publicly accessible right?)
This led me to two questions,
Why are the images are still being accessible from the url even after I created a symbolic link from public/storage to storage/app/public and stored the images in the public/storage directory?
As happened with my case, if the files in the
public/storage are still accessible through the web
url, what are the advantages of actually creating the symbolic link?
It does not seem to offer any more security since the files are
still accessible from the url.
It would be really helpful if anyone can help me understand the answers to the above two questions I have. Thanks.
What's happening to you is the expected behavior.
The purpose of Laravel storage is to interact with your local files and make use of Laravel helpers, besides being easily shared across deployments.
Saying that I would avoid moving your files directly to your public folder.
On the other hand, by adding files to your storage/app/public folder you are assuming that those files will be publicly accessible, but they won't be until you create a symbolic link which is a special kind of file that points to another file.
When you create a symbolic link you are saying "hey, if the user reaches http://localhost:8000/storage/ just show the files stored in storage/app/public"
So if you want private files (and you have created a symbolic link) just don't upload them to your storage/app/public folder, instead of that put your private files out from the public folder such as storage/app/myfiles
He are your answers:
1 - Why are the images are still being accessible from the url even
after I created a symbolic link from public/storage to
storage/app/public and stored the images in the public/storage
directory?
Because in fact, you have created a symbolic link for that purpose, making the storage/app/public publicly accessible.
2 - As happened with my case, if the files in the public/storage are
still accessible through the web url, what are the advantages of
actually creating the symbolic link? It does not seem to offer any
more security since the files are still accessible from the url.
As said, the advantage is to make use of Laravel filesystem. The public link doesn't determine the privacy of your files
You might have many different types of files in one project. Some are accessible to the public, like images embedded in a website (as your example shows), and some are private files, let's say, for example, a pdf of a private report.
Any file that is accessible to the public can be stored in either storage/public or directly in public. As you have observed, no difference there since the former would have a symlink established.
However, private files cannot be stored storage/public (if symlink is established) and especially not directly in public folder for obvious reasons.
Those files can go in storage/app/NOT_PUBLIC_REPO. These files should be made accessible via protected routes (along with signed routes if you want extra protection).

directory for public and private file in laravel

I want to create a website for selling quality photos using Laravel framework.
I want to show everyone the photo mockup on the home screen.
But the original file(zip) can be downloaded after purchase.
Is it best to place the mockup file in the Storage/app/public path and the zip file in the Storage/app/files path?
If I do, I can access the mockup file using php artisan storage:linkand display it on the home screen. But I have no idea how to download the zip file.
If this method of storing files and mockups is correct, secure and standard, please tell me how to access the zip file.
But if this is the wrong way, tell me the right place to put the files and mockups
If it's public to everyone then there is no problem to make it public, so If you were to use your local driver and would want to make files accessible in your storage folder then you would run an artisan command like below
php artisan storage:link
This will ensure that files are accessible publicly as example.com/public/storage/whateverfile.
However, for the people who have purchased the image, you need to use authentication or authorization to handle it, eg. if you want the files to be only accessible to authenticated user then maybe you can put the files in storage/myViewFile which will make sure that files in the folder aren't publicly accessible. Then using a controller with an auth middleware or route with middleware you can make files accessible.
Route::get('/storage/files/{file}', 'FilesController#show')->middleware('auth');
and for downloading files you can do it in the show method using laravel download response
return response()->download($pathToFile);
//or
return response()->download($pathToFile, $name, $headers);
//or
return response()->download($pathToFile)->deleteFileAfterSend();

What should be the better way to store images or files to folder in laravel application

I am doing a project using Laravel. Now, I have to store customers, users etc images both in the database and application folder. There are two ways to store images or files in laravel application.
Inside public folder I can store.
Another one is, inside storage/app/public
From these two ways, what should be better to do this. Would someone suggest me please?
Thanks in advance.
There's not an enormous difference, but in general, it's better to put things in storage/app/public.
This allows you to give Laravel write permissions to the storage folder, while leaving its permissions on public as read-only. This is a bit more secure.
Generally, if your files need to be publicly available you it is recommended you use the laravel "Public Disk" which exposes yoursite.com/storage/ as a symbolic link to your_app/storage/app/public.
You can activate the public disk by running
php artisan storage:link
If files uploaded do not need to be directly accessed via the web, it is recommended that you use the "Local Driver" - these files are kept securely inside your_app/storage/app - one level up from the public folder and are not directly accessible by a web browser.
You are of course free to create any file structure in these directories as you need for your customers etc.
The Storage class helper is extremely useful.

Where should we store data (files) from users in Laravel architecture?

I have a project that is meant to work for some countries. For now, in this example lets says USA-(us) and France-(fr).
So, when the user write in the URL us_mySite.com, the system should open the files, or display some pictures related to us only, not fr
At some point the user will need to update some file (pdf, excel, pictures, videos, etc) and the system must store these files inside the correct country.
So now we have in the site root a structure like this:
www/myStie/
...
...
data/
us/
excel/
pdf/
fr/ ...
img/
us/
fr/
...
...
Now I am migrating the system to Laravel 5 and I would like to know where should I put this data folder. Should it be inside Public/ folder? This folder should be accessible for delete, read, changes and save files trough the process.
This is quote from laravel doc: https://laravel.com/docs/master/structure#the-public-directory
The storage/app/public directory may be used to store user-generated
files, such as profile avatars, that should be publicly accessible.
You should create a symbolic link at public/storage which points to
this directory. You may create the link using the php artisan
storage:link command.
Store them in public folder.
https://laravel.com/docs/master/structure#the-public-directory.
That's where all the assets go. Check the above link for more info.

Hide and Secure files on server in Code igniter

I am developing a web application for my client using Code Igniter and i need to hide and secure some ZIP, JPG and PDF files on server so that they are not accessible by non users. Only people who are logged in and are the owners of Files can access the files. This is very similar to secure file sharing websites.
it is very similar to any paid file sharing site like only people who paid for files can download files. In my case only those who have uploaded and who shared the files with other can download files.
Please tell me how can i do this..
Thanks
Sajid
One method is to keep the files above the web root (so not publicly accessible) and have the link to them point to a function that will check if logged in (or other parameters you want) and if everything is OK, then serve the file(s).

Resources