preventing outside linking to a page - php

I have a download script that processes my downloads:
download.php?file=file_refrence_here
How can I prevent someone from putting a link on their site such as:
http://www.mysite.com/download.php?the_file_refrence
Apparently $_SERVER[HTTP_REFER] is not secure.
Although I am just worried about general linking not people smart enough to change their header strings.

One way would be to include a time-limited hash which is validated before you allow the download. A distributed link then only has a small window of time in which it can be used.
For example
$file="foo.mp3";
$salt="youpeskykids";
$expiry=time()+3600;
$hash=md5($salt.$file.$expiry);
$url="download.php?file=$file&e=$expiry&h=$hash";
Now, when you process such a request, you can recalculate the hash and check that the presented hash is equal: this ensures that whoever made the URL knows the salt, which one hopes is just your site. If the hash is valid, then you can trust the expiry time, and if it hasn't expired, allow the download.
You could include other things in the hash too if you like, like IP address and user-agent, if you wanted to have more confidence that the user-agent which requested the download link is the one which actually does the download.

You cannot prevent someone from linking to your page as you cannot prevent someone to write the word sunflower on a sheet of paper.
But if you want to prevent that following such a link will result in downloading that resource, you would need to authenticate the request in some way. This could be done by generating random, temporary valid authentication tokens that only your page can create.

Another way would be to, when the download link is generated, encrypt a data packet that contains the user's IP address and pass this in the URL. The download script decrypts the packet and denies access if the IP address doesn't match the current remote address.
That way, there's no time limit (not that one of those couldn't also be included if you liked), but the file can't be downloaded from any IP address other than the one that viewed the initial page.

Related

How to hide a piece of text in header ("Location:") using php

HTMLCODE IMG
PHPCODE IMG
I used the HTML file to redirect to the php file and from there i want to redirect to address below
header( "Location: https://csp-thanhhung123213.c9users.io/FINAL/HOME.php?username = thanhhung" );
My only question is that is there any way I can hide "username = thanhhung" from the link when redirect to the address above
THKS for helping me, have a nice day
There's no way you can hide any information that goes through the client. You're trying to redirect the client to another site, and make it carry some information with it. That means in one way or another, the client will need to know about the information to carry it to the other site.
The only way to not expose information to the client is to… well, not expose it. If you control both the origin and the target server, you store the information in a session server-side instead of transporting it client-side. If the two servers are separate, you could encrypt the information you give the client so the client can transport, but not read it. Another option is to give the client a meaningless token, and exchange the actual information associated with that token directly server-to-server behind the scenes.
You want a POST field, you should not use GET variables for sensitive information.
https://www.w3schools.com/tags/ref_httpmethods.asp
Edit:This question wasn't as clear when I initially posted, so here's the revised solution.
Solution 1:Nonce
What you want here is a nonce, a nonce is a value held on your server that represents a hidden value. It stands for number-once. A one time value. that way the sensitive information never leaves the server.
Before rewriting the location, store a map from nonce->username on the server, then rewrite with the nonce instead of the username. In the receiving script map the nonce back to the username, and proceed as usual.
Solution 2: Less secure
You could encrypt the string by XORing it with a secret hardcoded into each script, but since that's constant, an attacker could easily recover the key if they are able to manipulate username.

Embedded iframe - Verify source/origin of GET request

I'm seeking to utilize an iframe to embed some html in customers websites that will list some information from my database using a simple GET request like so:
// customer would copy/paste this code onto their site
// value of key would be unique key for that customer
<iframe src='http://mydomain.php/api?key=1234j1lj1hj124kh' ></iframe>
Now I want to be able to verify that the request is coming from customer that owns the key, and not just anybody who copy/pasted that code onto their page.
I've done some research and found that $_SERVER['HTTP_REFERRER'] can give me this information, but with mostly mixed reviews saying it isn't always reliable (and most of the questions I came across were a couple years old).
QUESTIONS
1.) Is this method of using an iframe/GET request the standard way of achieving this functionality?
2.) Is there a standard, SECURE and RELIABLE way to verify the origin of the GET request?
Unfortunately this is not possible in a secure way.
To answer your questions: In fact this is not a standard functionality itself. I mean, there is no standard secure way of allowing content to be loaded only through iframes from allowed websites.
There are three parties in this communication:
1) Your website
2) Customer website that loads your website's data in an iframe
3) End user visiting customer website
When an end user visits customer web site, he will perform a GET request to your website through the iframe. At this connection, 2nd party above (customer website) is not involved. In this case, there is no reliable way for your website to know whether this request is coming through the iframe or not. Only favor that party 2 does here is adding HTTP_REFERER header to end-user's request. But this header cannot be trusted.
For example, if I want to abuse this and show that content on my website, I can create a proxy page on my application, where I perform a back-end call to your app (adding a valid HTTP_REFERER header) and display results back.
Personally I would never use iFrames for this functionality. I am assuming that this has to be reasonably secure, which is why only your specified customer can view it? If for whatever reason you can't use PHP to embed the content you need to display (through the use of an "included" file for example), I would instead use AJAX which would still use any PHP user verification you have in place to dynamically load content into a secure webpage.
This is because your PHP user verification will (should!) use cookie/session information to determine which customer is viewing the page and therefore decide whether the content should be delivered, since Session variables are determined by a single unique code stored client-side, which match up to as much information as you want to collect about a user server-side (Which could include the last page they visited, which is what the "HTTP_REFERRER" variable would give you, if they came from another page on your website).
'$_SERVER' variables aren't reliable because they rely on the information given to them by the web browser when the request is made, and such information can easily be forged, by most people who have a basic understanding about how headers are sent.
In summary, use a NONCE (cookied), validate IP and user agent.
Steps:
When you deliver the outer frame, generate a unique identifier
(totally random, long string) and return that in a cookie with the
HTML content.
At the same time, note the IP and the user agent string you have
sent that unique identifier to, and store in a DB with the time.
When requesting the inner frame, assuming the same domain, the
cookie will come too. (If a different domain, you'll need to attach
the unique identifier as a visible string, but that's not really of
concern, just uglier)
If the user agent or IP do not match those you stored against the
unique string, or the request is too long (i.e. after an hour, or
whatever is reasonable for your application) or the unique string is used more than once
(or whatever other restrictions you place on it) then reject the
request and invalidate (delete) the unique identifier.
Not 100% foolproof, but just combine more options to make it less and less likely to be abused.

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.

Secure way to store files in web server?

I want my files to be secure in my web server. Only authenticated users to access those files should be able to access those files. I thought of storing files in database as "Long BLOB" but it supports only upto 2MB of data. The file size may exceed beyond 50MB. is there any other better way to secure the files? please help me.thanks in advance.
Don't store them in a database. Put them in your web directory and secure them using .htaccess.
If you want to authenticate via other means, then store the files in a directory that isn't web-accessible but is readable by the user php runs as.
Discussion
If you opt to keep high value downloadable content files directly on the filesystem, the best thing to do is to keep them outside of the webroot.
Then, your application will have to solve the problem of creating URLs (url encoding when necessary) for content (PDF's, Word Docs, Songs, etc..).
Generally, this can be achieved by using a query to retrieve the file path, then using the file path to send content to the user (with header() etc ..) when he or she clicks on an anchor (all of this without the user ever seeing the true, server side file path).
If you do not want user A sharing URLs for high value downloadable content to user B, then your application must somehow make the links exclusively tied to user A. What can be done? Where should I start?
Obviously, you want to make sure user A is logged in during a session before he or she can download a file. What is not so obvious is how to prevent a logged in user B from using a URL sent from user A (to user B) to download A's digital content.
Using $_SESSION to store the logged in user's ID (numerical, or string) and making that part of the eventual query (assuming content is tied to user purchases or something) will prevent a logged in user B from downloading things they have not purchased, but you will still incur the resource hit for processing the SQL empty set for items they have not purchased. This sounds like a good step two.
What about step one? Is there something that can prevent the need to do a query to begin with?
Well, let us see. In HTML forms, one might use a XSRF token in a hidden field to verify that a submitted form actually originated from the web server that receives the POST/GET request. One token is used for the entire form.
Given a page of user specific things to download (anchors), one could embed a single token (the same token, but different per page request) into each anchor's href attribute in the form of a query string parameter and store a copy of this token in $_SESSION.
Now, when a logged in user B attempts to use a logged in user A's shared URL, the whole thing fails because user A and user B have different sessions (or, no session at all), and thus different tokens. In other words, "My link is the same as yours, but different." Anchors would be tied to the session, not just to the page, user, or content.
With that system in place, PHP can determine if a request for content is valid without getting the database involved (by comparing the submitted token to the one in $_SESSION). What is more, a time limit can be established in $_SESSION to limit the duration/lifetime of a valid XSRF token. Just use the time() function and basic math. Sixty minutes might be an ideal token lifetime for an anchor in this situation. Have the user login again if the token for a clicked anchor has expired.
Summary
If you use files on a filesystem and store the paths in the database, make sure you do the following (at minimum), too.
Apply proper file permissions to your content directory (outside of webroot).
Use random names for uploaded files.
Check for duplicate file names before saving a file from an upload.
Only logged in users should be able to download high value content.
Have an effective $_SESSION system that deters session fixation.
Make URLs for high value downloadable content unique per page by using hashed XSRF tokens.
XSRF tokens cover more scenarios when they have a terminal life time.
Make SQL queries for user content based on the logged in user's ID, not the product exclusively.
Filter and validate all user input.
Use prepared statements with SQL queries.
A few options come to mind.
If you are using Apache you can use htaccess to password protect directories. (first googled link : http://www.javascriptkit.com/howto/htaccess3.shtml)
or
Store the files above the web server.
Create a script in php that will allow authorised users to access them.
If you want to do it Via FTP, and you are running cpanel you may be able to create new ftp accounts. check yourdomain.com/cpanel to determine if you have it installed.
Storing files in DB is very bad practice. Very good practice to store only information about file. Name, extension. Files save on server like $id.$ext. It will be a good architecture. And when user download file, he take file with name in DB.Sorry for my english.
The best way is to store the file reference in Database. The file itself will be stored in the server filesystem. The complexity of this is making sure there is reference integrity between the database file reference and the existing file in the server filesystem. Some database such as sql server 2008 have feature that maintain the integrity of the file references to the actual file itself.
Other than that securing the file itself in the server depends on the OS where permissions can be configured to the specific folder where the file reside.
If the files are purely static you could use read-only or WORM media to store the data files or indeed run the complete web server from a "LiveCD". It's certainly not suited to everyone's needs but for limited cases where the integrity of the data is paramount it works.
Downloadable files can be stored in htaccess protected folder/s. A script like the one below can be used to generate dynamic links for downloadable files.
for ex. Secure download links. http://codecanyon.net/item/secure-download-links/309295

Secure a PHP file; how?

I have a classifieds website, and a partner of us (who runs another classifieds website) need to have access to a file on our server.
The file is called 'partner.php'.
This file simply prints out some information about the classifieds on our site.
So for our partners, they would just need to access "www.domain.com/partner.php?id=1234" to have access to that information.
I am planning to add a hash to the Url, so that outsiders don't have access to the file. But I don't know how to do this...
Is there anybody who could point me in the right direction?
I have been told on phone that I can use a "32 length MD5 string and add it to the URL", but I have really no clue how to start, or what they meant by this?
Anybody know what they mean?
Examples is appreciated.
Thanks
I am planning to add a hash to the Url, so that outsiders don't have access to the file. But I don't know how to do this...
don't do it this way. A hash is fine for one-time links like E-Mail confirmation, but not for sensitive info. The hash will be present in the user's history, cache and in Proxy protocols; it can be shared accidentally.
You need to look into building proper, login-based authentication.
Some starting points:
Secure authentication in PHP
Actively maintained PHP libraries for user authentication?
Basic authentication and session management library for PHP?
Or you can use both the Hash key and IP verification. If your partner is using just one computer/server to access your file you can check the hash key and the users IP address.
$ip = $_SERVER['REMOTE_ADDR'];
Is it possible to use a different approach?
Maybe you can use a .htaccess to only allow access to the file from certain IP addresses.
Check out this page on .htaccess. There is a section called Restricting by IP Address
You could use HTTP Authentication, for example via .htaccess
Adding a hash to the URL means that you pass a GET-Parameter to the script and check it when the script starts. If the value is not the expected one, the script can simply die(); or throw some kind of error.
But I'd really NOT recommend the hash-thing, it's a bad idea.

Categories