I know of a few ways (i know there is probably more) to open a file in a browser after the user clicks on a link,
Use PHP headers to simulate a file download
Use an <a> tag to redirect the user to the path of the file
Use javascripts window.location to point to the file location
Iframe tag
Object tag
What is the most efficient, cross browser, or nicest way to open a file in a browser? Or, what do most companies use?
Well personally the best method is to create a script called download.php and then send the file hashes to that, Imagine you had a directory layout like so:
/downloads/
/2010/
/abc8755ghc7659c75678bf78968.file
/abc8755ghc7659c73278ef78998.file
/abc8755ghc7659c75678bf78968.file
/2009/
/abc8755ghc7659c75678bf78968.file
/abc8755ghc7659c75678bf78968.file
And then you had a script called download.php, You can then validate the users information to protect your actual files for scrapers etc.
Storing the files with no extension is ok, just as long as when the file is uploaded you can all the information and store it within your database, so that when we send the file we have the Content-Type, Extension, Original File Name, etc so we can send correctly
The reason for the hashing is that that parsers and scrapers can easily find the actually file on the server, so if a scraper look around your site and then has seen a title called My ebook 2010.pdf, He would not be able to download it form your server like http://mydomain.com/downloads/My ebook 2010.pdf as the file does not exists, it exists in http://mydomain.com/downloads/abc8755ghc7659c75678bf78968.file
Security is always the best measure, Also using PHP Would be able you to validate the actual user before your application decides weather the file should be sent or should b edenied
PHP Example script would be like so:
include 'all.the/files/needed.phhp';
if(!logged_in())
{
header('Location: /');
exit;
}
$FileRequest = FileRequest::getInstance();
$User = User::getInstance();
if($FileRequest->isValid)
{
if($user->canDownload($FileRequest->GetDatabaseID()))
{
$FileRequest->SendFile();
exit;
}
}
This way you can control download being sent, you never reveal your file location, and fiels are stored with a hash that would be hard to find.
All three will work. But, if you want to prevent outside domains (search engines, etc.) from accessing your files, you should use PHP:
getfile.php?id=1 OR getfile.php?name=file.txt
and check the HTTP_REFERER to make sure the request is from your domain.
Because different computers have different plugins, and different browsers and operating systems. If you want to be consistent, my recommendation is your first option, using headers to specify content disposition forcing the file to be downloaded. This will prevent inconsistency where some files open inside the browser, some open in a 3rd party external program.
This is also referring to files that are non images, such as PDF's. You should open images inside the browser. Non-flash movies are questionable as well.
Using download file is the most efficient, cross browser way!
The PHP method you described is just simulating a redirect which would achieve the same thing!
Javascript is the least accessible for people with javascript turned off!
Use an tag to redirect the user to the path of the file
This one. Give me a link I can click on to open using an in-browser handler. Or, so I can right-click on it and save it to my hard drive.
I'd say the best way is to link to the file using an <a> tag setting the attribute target="_blank" that way if the users machine supports opening the document in the browser it will do so. If not it will be prompted to download the file.
Related
I am currently trying to develop an image uploading website by using CodeIgniter.
The thing is, I came across an issue today and I would really appreciate any kind of help in order to solve it.
So basically, the site is working. But the thing is, that the files are not private. A user may want to ensure that the files the users upload are only visible by them, and not by someone who just guesses a bunch of urls. (eg. user1 uploads image1 which he wants to keep private, for himself =>[localhostlocalhost/upload_script/files/image1.jpg], user2 can access image1 by guessing and typing the url [localhost/upload_script/files/image1.jpg] which is what we don't want to happen. )
I have done some research and I think that this would probably require another controller for serving the files (which checks for session data).
I have been "playing" with sessions etc in PHP for quite some time in the past, but I am not that familiar with them in CodeIgniter.
Is this the only way? I don't think I need to create separate directories for each user, do I? Can you please tell me how to head to the right direction or give me an example?
Thanks in advance,
harris21
In order to protect files, you will need keep them outside of your web root, otherwise people will always be able to url hack their way round.
I have used the very handy mod_xsendfile for apache (if you have that kind of access to your server) which will allow you to serve files that can be protected by access control and not accessed without the appropriate credentials.
Code snippet that you could put in your CI controller to display an image (adapted from the mod_xsendfile page):
...
if ($user->isLoggedIn())
{
header("X-Sendfile: $path_to_somefile");
header('Content-Type: image/jpeg');
exit;
}
If you cannot install mod_xsendfile then your only other option would be to use readfile() as TheShiftExchange says.
Use PHP to return images and lock the image directory behind the webserver root. This way, before serving an image you can check the user credentials via session variable, assuring that he is allowed to view the image. Otherwise you can redirect the user straight back to the website alerting him he does not have access. Serving images like this is way slower than just serving them via webserver (apache, nginx,...) but it will enable you to have control over the downloading of the images.
To be more exact, save the image details in a database, for example having columns: id, file_path, title, uid. Everytime a user wants to download an image for example calling http://domain.com/files/download/3 you can check if image with id 3 can be downloaded for the currently logged in user. You need to write your own controller that will be doing that.
I am doing a similar thing here http://www.mediabox.si/ you can check how images are served. I am allowing thumbnail images and I am watermarking larger images visible to ordinary visitors.
The ONLY way is to store the images outside the public_html. Otherwise by definition you are opening the file to direct access.
Use a controller to check if the user is allowed to access the file and the php function readfile() to serve the file
You can read some code at one of my other questions here: Does this PHP function protect against file transversal?
And this is actually VERY fast - you won't notice a performance hit at all
Is there any way to detect in PHP is GET request made by embed src in browser?
<img src="xxxxx.php">
I was trying use "REFFER", but it's very not good solution.
I don't know lot about http, but maybe if browser use tag, it send header accept image or anything like this what i can read in php ?
I just want create script what will display picture if embed, but if open in browser in normal way, like url it will redirect user to other page.
Is there any way to detect in PHP is GET request made by embed src in browser?
No.
If you hide your files in a folder outside the root, created a PHP file that all images routed through (image.php?lovely_duck.jpg) and then looked for $_SERVER['HTTP_REFERER'], that would be possible. But you can forge $_SERVER['HTTP_REFERER'] and it isn’t always reliable.
If you’re trying to find a way to stopping people getting your images, they’ll always find a way.
You can (but i would NOT suggest it) check the Accept header.
If the request was triggered by an <img src=... it should NOT contain "text/html".
Also described here
But again: i would not suggest using this.
At the moment that will break the download image functionality in firefox and possible other browser.
Additionally it won't prevent "evil guys" to download all your images because they simply can set the required HTTP header.
I suspect that this is impossible, but I'm trying to be optimistic...
I'm running a site that uses jquery & php. Via ajax, I'm dynamically loading images to a page. The problem is that the paths to the images are visible when you view the source of the page. I'm trying to figure out if it's possible to prevent the path from displaying? I just don't want anyone seeing those paths or being able to access them. So, I don't know if there's some sort of magical programming solution or something to do with htaccess, but if anyone knows how to accomplish this, I'd appreciate pointers / links / or brilliance...
As the browser needs to know where to fetch the data from, it cannot be hidden easily.
But you can it make the "attacker" a little bit harder. E.g., you can give URLs with a script behind loading the given images. The script does so only if called with the correct Referer: header.
Are Data URIs an option for you?
If not, preventing hotlinking (via Referer) would be the way I would do it, possibly with some obfuscation (depending on your user base).
Everything that's visible to the browser is visible to the clever user in one way or the other
You can hide them from lamers, but not from programmers
Anti-lamer techniques can include:
1) setting data-mangled-src attribute to something like ROT13(real-src), then doing
$('img').each(function () { $(this).attr('src', ROT13($(this).data('mangled-src')))})
2) setting some data-id attr, then AJAX-requesting the src from the server
But anyway, the URL goes to the browser, then it's visible to the user
3) And, of course, you can load your images into flash 'viewer', which is probably the most advanced way of hiding them
So... If you make the load path an internal link in php Requested through Ajax that should hide the path in network inspector... By this I mean maybe query a db that generates a temp path to the image that expires...
Then with the loaded image you could save it a canvas element... Thus no src
There are a few ways you can go about hiding image URLs.
Use a plugin: you can use flash, a java applet, etc to load the images
Use a traffic cop: you can set the source of all the images to a single PHP script, with some kind of parameter to specify which image you want. That script can check sessions variables / referer / whatever you want; if everything checks out, you can do a file_get_contents() to load the actual url of the image, then echo that out to the browser.
I've created a website to help you hide the image src of your precious photos and images.
My website will hide the source path of your image, and it also allows you to 'Lock' your photo to a specific domain eg. example.com so that the photo will only display example.com and not on facebook.com or wherever the link to the photo is reposted.
http://hideimgsrc.com
It's easier and faster than a java script based solution.
I wanted to serve a download of my program on special download page. Something like: http://site.com/download, where there will be a standard HTML page and also a file download prompt. I was wondering how I'd go about implementing this.
The only way I can think of is having a hidden iframe in the page pointing to the file the user wants to download. I also know of the PHP function readfile() but I don't see how I can implement that on the page aswell as have a HTML output shown to the user.
Any help is appreciated, thanks.
You can use a META redirect, which since it points to a download will not leave the page you're on.
On your HTML page, try including something like this:
<META HTTP-EQUIV="REFRESH" CONTENT="1;URL=/download/sitefile.zip">
This will browse to the file after 1 second, which should prompt the visitor to download it without leaving the page.
You can have the site http://example.com/download this can be normal html site. With redirection after few seconds (can be done in js or meta).
It should redirect to PHP site with fpassthru() function in it. That way you can easily implement additional security in the PHP.
HINT: make sure to set proper HEADERS in the PHP file so browsers will start download the file instead of showing the content in browser screen.
I have a php page . I need to make it hard for user to get direct download link.For this i need a js function which start downloading pdf after 10sec automatically after page load. I dont want to provide a download link at all. Also I cant use onpageload . PDF must download.
Since most of the browsers will tell you where the downloaded file came from, i think you may want to mask the file itself behind a 'temporary' link with mod_rewrite or other custom parameters. You don't need to use JavaScript for this.
After then you can simply push the file with PHP similarly like this solution.
There is absolutely no way to hide a URL from an end user - All they need to do is use Fiddler 2, Firebug or similar tools to view the requested URL
Have your download page redirect to the PHP file that will download it. If it can download it, it will redirect the user back to the previous page, because the download doesn't have the right content type, although it could be just a plain .html file. You don't need Javascript to do this:
<meta http-equiv="refresh" content="10;url=http://mysite/d.php?file=resume">
I recommend the Smart File Download, from zubrag.com, if you don't already have a PHP file specifically for downloading.