how to assign unpredictable url for web pages in php - php

I am developing an application in php that contains a lot of html pages that doesnot require user log in for viewing (a requirement actually). The pages are placed in different folders that are highly predictable. e.g www.abc.com/book1/chapter1/lesson1.php, www.abc.com/book1/chapter1/lesson2.php etc.
Hence if someone knows the path to lesson 1, he automatically knows the path to every other lesson in the chapter folder.
Is there a way that if there's a request for www.abc.com/book1/chapter1/lesson1.php, the path shown in the browsers address bar is something like www.abc.com/book1/chapterHFG564/6756/lesson1.php or any other unpredictable URL? i dont even know if it's possible or not!

You could make an MD5 hash of the relative path of the page URL + the server timestamp to make an unpredictable string (let's call this a "page key"), and then store the page key + relative URL association in a persistent store (relational database, or - for speed - constant database) for later lookup.
Then you could write a script (like "http://www.abc.com/page_mapper.php") that takes a "key" parameter, looks up the relative URL for the specified key, reads the associated content (if there is any), and "passes it through" to the client.
Finally, you could add a URL rewriting rule to map incoming requests (e.g. "http://www.abc.com/book1/chapter2/abCvx9100xvz==") to your script (e.g. "http://www.abc.com/page_mapper.php?key=abCvx9100xvz==") and you'd be all set.
Of course then anyone who knows the URL can access the page, but maybe you want that?
i.e. is it OK if user A emails a link (that she can see) to user B and user B can see it?

When it's unpredictable, it's impossible to do so. You can direct all urls to one php file which would then redirect user to correct url

Not sure if u can encode urls in that way... but u could certainly get all scripts to redirect to another MEGA script and use session variables or files to check and see where the user is comong from.. and proceed accordingly. Once the MEGA script directs to another page, it saves a session variable first.. which u can check once the redirect landing page opens up.

Related

Prevent file access on direct http

My question seems to be similar to others here in SO, I have try a few but it doesn't seem to work in my case...
I have develop a site in which you have to fill up a form and then it returns a PDF file that you can download or print, this file is saved so you can retrieve it later
public_html
|_index.php
|_<files>
| |_file_001.pdf
| |_file_002.pdf
|_<asstes> ....etc
that is how my files and folders look on the server, anyone can easily guess other files, .com/folder/file_00X.pdf, where X can be change for any other number and get access to the file... the user after finish with the form the script returns a url .com/file/file_001.pdf so he/she can click on it to download...
a year ago I did something similar an script to generate PDF's but in that case the user needed the email and a code that was sent via email in order to generate the PDF and the PDF's are generated on demand not saved like in this case...
Is there a way to protect this files as they are right now?
or, do I have to make it a little bit more hard to guess?
something like.
.com/files/HASH(MD5)(MICROTIME)/file_(MICROTIME)_001.pdf
and save the file and folder name in the DB for easy access via admin panel, the user will have to get the full URL via email...
Any ideas would be greatly appreciated.
For full security i would move the PDFs out of the public folder and have ascript in charge of delivering the content. If the form is filled correctly, you can generate a temporary hash and store that hash and the pdf path in the database. That way the user will have access to the file as a link through the retriever script, but you will control for how long he will have that link available.
Imagine the temporary link being http://yourdomain/get_pdf/THIS_IS_THE_HASH
Move the PDF's to some non-public folder (that your web server has access to but the public does not). Or you can use .htaccess to restrict access to the pdf's in their current location.
Write a php script that returns the correct pdf based on some passed in http variable.
You can secure/restrict this any way that you want to.
For example, one answer suggested using a temporary hash.
Other options for restricting access:
Store in the user's session that they submit the form and have a download pending, that way no one could direct link.
Check the referrer header. If it is a direct request then do not serve the file.
Here is a code example using the last option:
$hash_or_other_identifier = $_REQUEST["SomeVariable"];
if (!$_SERVER["HTTP_REFERER"])
{
//dont serve the file
} else {
//lookup the file path using the $hash_or_other_identifier
$pdfFile = somelogic($hash_or_other_identifier);
//serve the correct pdf
die(file_get_contents($pdfFile));
}
I don't even think that keeping the file name secret is a very big deal if all you are worried about is people typing it into the URL bar because you can simply check if it is a direct link or not. If you are also worried about bots or clever people who will create a link that points to your file so it looks like a referrer, then you will need to add stricter checks. For example, you can verify that the referrer is your own site. Of course headers can be spoofed so it all just depends how bulletproof it needs to be.
The url would be something like: http://yourdomain/pdf?SomeVariable=12345
However, you don't have to use an http variable. You can also use a url fragment with the same result, eg: http://yourdomain/pdf/12345
General guidelines:
File is not in the directory that's accessible via HTTP
Use a database or any other storage to link up file location with an identifier (an auto incremented number, guid, hash, whatever you deem fit). The location of the file could be in the server's file system or on a shared network location etc.
Instead of hashes, it's also practical to encrypt the ID generated by the database, base64 encode it and provide it back - that makes it nearly impossible to guess the valid string that one needs to send back in order to refer to a file
Use a PHP script that delivers the file if user authentication passes (in case you need authenticated users to be able to retrieve the file)

Avoid users from opening a php page by directly entering parameters

I have a php file which takes in a path and file name and opens a page. Users are able to enter the path and file name directly in the url rather than navigating through the main menu page. Users also are able to change parameters in the url and view other text files which he is not supposed to view. I need to prevent users from changing the url and entering the page directly.
Can anyone help me with a way to avoid users from entering the page directly changing the parameters the url.
You can't control what resources users request.
Solve the real problem instead:
Users also are able to change parameters in the url and view other text files which he is not supposed to view
Authenticate the user so you know who they are
Authorise the user so you know if they are allowed to view the file they are asking for
Give them an error message if they are not
You can encode the parameters of the url.
Instead of having var1=a&var2=b, you can have something like var=thhr6tghfdgfe56
Your users wont be able to guess the encoded format and they will be forced to use your page/menu.
Keep track of which user id tries to access an illegal encoded url - block him after X tries.
You can use the $_SERVER['HTTP_REFERER'] server variable which
referred the user agent of the current page. This is to check
whether the user navigate from your website or directly hit the URL.
You can't control the users to change the request parameters.
Hope this will help you.

Untraceable URL Mask

I want to mask a file URL on my site so that it can be accessed, but they can't find the direct URL of the file, even if the view the HTML source code. I don't know if it is possible with php, but please help me. Anything will do.
If I understand your question correctly, you want to avoid "deep linking", i.e. someone extracting the file URL from your page and using it elsewhere.
This can not directly be done, as the information is needed by the browser to access the file, and a determined attacker will quite easily be able to extract it.
There is a workaround though: Make this URL dynamic.
Place file outside the publically accessible web root
When delivering the HTML page from PHP, create a download token, that has the file path, an expiry time (and maybe other factors such as a session ID, a referrer URL, etc ...) cryptographically secured (i.e. hash it together with a server-known secret)
Deliver a link to a download script, not the file iself
inside the download script, verify the parameters and the hash, exit with a 304 (or maybe 404) if wrong
if verification passes, simply deliver the file
This will protect you from deeplinking in that an attacker will be able to extract an URL, that loses its validity after your expiry time. If you use an AJAX request to create the download token immediately before starting the download, you can make this quite short (few seconds)
You can't.
The browser has to know the URL to request the file from.
The browser is under the control of the user.
Any information you give to the browser, you also give to the user.

How Do I Hide Filename & extention in PHP?

I have a url in this format: "sitename.com/folder/file.php". How do I make it a "sitename.com/randomhash" or "sitename.com/folder/randomhash" format?
I know I can use a GET & Switch system but I need the name to be unique and I need to be able to change it on the fly.
I don't really understand what your point is, but if you don't want you're visitors to know where your php-files are stored, I would recommend reading this:
Tutorial for URL handling in PHP
If you are having a website where people can download stuff, and you don't want people hotlinking your files, you could do the following steps (i'm not writing the code, I'm just going to give you a general idea):
People come to your website.
Person clicks on link because they want to download that particular file.
Person comes on page, where you have the opportunity to set a cookie with a random hash.
Simultaneously you put a value in a database, with the same hash and the filepath of the file they want to download.
On this page, they have to click "DOWNLOAD NOW!", where they are redirected to download.php.
In download.php you read the cookie, then match that with the database and get the filepath.
With the right php-headers, you can force download.php to download the file.
Important in this situation is that you set your settings of Apache (or whatever server you have) that downloading is not allowed unless 'localhost' is requesting it.

built in way to identify each browser window

IS there, a cross browser, way to identify each browser window uniquely?
I need to store some values which are unique for a window.
Even if the user opens two windows on the same browser to the same site.
There is no Ajax involved, every click on a link will load a new page.
And how would I access that name from the server? (for this, assume I use php, but example in any other language, is also good)
You could identify the windows by putting and maintaining unique arguments into the query strings of all the urls. For example, if the current url is /foo.php?windowid=abhn7y76g7hygy7yhnui98u8mc then each url in that pages html would have an id distnct from the url and the others in the document. uniqid() is perfect for this as it uses time, and so they're lexicographically increasing id's.
The one edge case you need to handle is when someone opens the exact same link twice(maybe via clicking, or maybe via copy pasting the url and manually opening a new window). I think the only real solution is to have the server keep track of which id's have been used, and if it notices a second request for the same id, it redirects the request to the same url, but a new id. This would maintain unique id's across all browser windows.
on second thought, dont even bother attaching the ids to urls in the html. Just make the server do the logic if no id, redirect to same url with a new id. if id, and the id has been used before, redirect to same url with new id.
make sure to send no cache headers for the html pages because you need the browsers to recheck with your server if the back button is used.
window.name can be set via JavaScript. Strangely, it can also hold a few megabaytes worth of string data and is sometimes used as client-side storage.
You'd have to pass the name back to the server with each request in order to know which window in the caller.

Categories