Hide pdf to non registered users - php

I've hit a dead end with this code I'm working on. I have a website where users can register and will be able to view certain pdfs when they are logged in. My question is though, how do I hide this file to make sure that only those currently logged in can subscribe. I keep track of my users with a MySQL database and have been using PHP for all the server side coding. Ideally, the solution won't involve the user having to sign in again or anything like that. I'm not necessarily looking for code (though its always appreciated :D), but any bump in the right direction would be great.
Thanks for any help you guys can offer.

if(isset($_COOKIE['login']))
{
header('Content-Type', 'application/pdf');
readfile('secret/books.pdf');
exit();
}
else
{
include('login.php');
}

The only way to secure the URL to the user is to require a login, which is something you don't want to do. (Obviously as long as the session is open via a cookie or whatever you are using, the person could access it.)
But keep in mind that once a person as the link to the PDF, they can download it and give it to somebody else. So in my opinion, you should simply focus on making it impossible for the average person to guess the URL.
In other words, simply putting the PDF on a URL that is not guessable is sufficient security given that a person can easily duplicate the PDF.
That said, if you want to lock it down a bit, you could give each user his own unique URL for the PDF. Thus if somebody does copy the URL around, you know who did it. Also, you could have URLs expire after a certain time.
That URL could be stored in the database as a url -> pdf lookup. No authentication would be required to access it.

Two thoughts on that:
1) store your PDF outside of your public readable WWW folder and include it to an authenticated user like ayush proposed
2) protect the file with a username and password using htaccess and access it with curl. cURL can provide the correct credentials without making the user re-authenticate.

Related

Login sytem with PHP

Good day.
I have questions about the login system , that disturbed me quite a long time. For this i want you to imagine that i have 2 pages login.php and userpage.php. The login page contains fields for input of user name and password. While userpage contains all the information about the logined user. When user inputs his data, some class Connection checks him in the database and if user exists, creates a session.
When I'm creating a redirection from login.php to userpage.php, how should i redirect users data? (Should I use global arrays (like $_SESSION) to transfer the info or I should connect the db again from the user page?)
Should I create some multi-threading (Do not judge strictly, I'm a newbie) for userpage.php, to be created for multiple users, which are trying to login at the same time?
How should I protect the information (code side), for being hard to read? (For example Facebook pages source-code. because i don't want some "bad guys" to view my sources) and other things.
How can I make some users to see what the others can't ? For example userpage.php shows different links and information for different users and all the information for me .
How can i prevent membership.php from being viewed?(Is there some other way than using header?)
How can i prevent my require and require_once from being viewd at the login.php and userpage.php ?
1.) When I'm creating a redirection from login.php to userpage.php, how should i redirect users data? (Should I use global arrays (like $_SESSION) to transfer the info or I should connect the db again from the user page?)
You need to have a connection to the db everytime you want to get the user's data. You can create a session to store a unique attribute for the user, like $_SESSION['id'], when the user is successfully logged in, and you can use that value on any page to query the db and get the necessary user data.
2.) Should I create some multi-threading (Do not judge strictly, I'm a newbie) for userpage.php, to be created for multiple users, which are trying to login at the same time?
No, you don't need to worry about users connecting at the same time. The server can handle this. When you have a million users or so, you can start considering this. (Although, even then I'm not too sure. Unfortunately I've never had that problem ;) )
3.) How should I protect the information (code side), for being hard to read? (For example Facebook pages source-code. because i don't want some "bad guys" to view my sources) and other things.
You cannot prevent anyone from seeing your markup and styles, that is, your html and css, or any client side scripting, like javascript. However, your php is server side and not displayed in the source. The 'bad guys' will not be able to view source to see your db connections, php logic, etc.
4.) How can I make some users to see what the others can't ? For example userpage.php shows different links and information for different users and all the information for me .
There are different approaches to take. The simplest is probably to store the user's 'permission level' in the db, and then check that every time you load content. For example,
if ($user['permission']==1)
// Show something
elseif ($user['permission']==2)
// show something else
5.) How can i prevent membership.php from being viewed?(Is there some other way than using header?)
The easiest way to do this is by checking to see if there is an active session, and if not, redirect:
if (!isset($_SESSION['id']))
header("Location: login.php");
6.) How can i prevent my require and require_once from being viewed at the login.php and userpage.php ?
Not too sure what you mean by this, but consider this: require and require_once are the exact same as including the code directly in the file. If you are referring to them being viewed directly by the client by hitting 'view source', don't worry - see answer to question 3.
Note:
These answers are simplified, and there are plenty of other complications to consider. Some of this stuff may not make sense, but I wouldn't sweat it too much. I would recommend starting small - find a decent tutorial or two on how to create a simple user database, a registration, and login page, and start there. No answers you get here will substitute research, practice, and trial and error. Start small, and things will quickly become clearer as you progress.
Save the users state in a cookie or in a session. Note that you need the session_start() the userpage.php page as well as the rest of the page were the user is connected.
More info on http://www.wikihow.com/Create-a-Secure-Login-Script-in-PHP-and-MySQL
See the above link.
No one can read PHP code because it is server side and not client side. So your code is secure already from its own structure.
Let users have different level from the swl-database. If a user got auth 1 they see some links, if they got user auth 2 they see other things.
See page from answer 1
See page from answer 1
Considering your stated fact that you are newbie,I will also assume that the login system is more of practice thing and not a real world app.
Now to answer your queries point-wise.
Storing data in SESSION variables is alright.However,do not store too many data in SESSIONS.I would suggest just store the userid for the user and use that to gather and display info in the userpage.php. As the app gets bigger,you will definitely need to make connections in each individual page.
Use SESSION and COOKIE combination to create multiple user logins. However,Refrain from trying to implement/allow same browser multiple logging-in.SECURITY ISSUE.
PHP source code is anyways not readable from client-side.Regarding javascript & css-u can maybe minify it.But that would still not make it client-safe.
There are many ways to implement this.Maybe have a $_SESSION['admin'] =true when a admin logs-in and use it to display/hide info on userpage.php.
Same as NEXT
What it is that u want to hide?If its HTML/JS ,u dont't have much choice. One solution may be to use if-else in ur php code and restrict display of code present in header.php and the pages included via require and require_once.
This is a very basic guide.Your strategies may vary depending on the complexity of your application and also if/when you start using framweorks . Happy logging-in !!
ADDITIONS wrt to application structure.
Considering that your end product would be a system that allows a user to register and login/logout,i would suggest a following structure to begin with.
Structure-
index.php
|--action
|---register.php
|---logged_in_user_landing.php
index.php-- This is main page and used to redirect to individual pages based on actions.
check if SESSION is set.
If yes,include action/logged_in_user_landing.php else include action/register.php.
As actions increase,you can add if-else and include more pages accordingly.
In register.php,u have the form for login. On submit, redirect to index.php (via form action).
establish db connection in index page and check username-password combination.If correct,set the SESSION for that user and include the 'action/logged_in_user_landing.php'.
Have a unique identifier sent along when redirecting from each individual page,So that u can identify what to do in index.php.
This is a very simple architecture that should get u started.Its kind of a controller based architecture and will help you in the future when u go into MVC architectures.

php auth sending specifc users to a specific page

first off third question I've asked and all have been answered well! So thanks to everybody who reads my posts (and others I guess)
I've gotten as far as I can without complete help on this one. I need to create a username and password section. I've done this before using htaccess, htauth files. Works well. Secure, and log's them in fine. What I'm looking for though is some sort of script that will take a specific user to a specific page after login.
User1= user1.php
user2= user2.php
Ect.
Is this possible without a whole lot of work? I can make workarounds where the users login to the main index, then go where they need to, but then anyone logged in can go to anyone's page.
I'm not asking anyone to write the code. But even some guidance to some tutorials would be great!
If the page is authenticated using .htaccess, upon successful login the username is available as $_SERVER['PHP_AUTH_USER'].
So you can either redirect the user using Location, or even better, directly include() the desired file.
You can place the user1.php, user2.php, ... files in a directory of their own, with a .htaccess that disallows direct access. This won't stop PHP from being able to include the files, and this way only the authenticated user can have access to his file.
if (isset($_SERVER['PHP_AUTH_USER']))
{
$pvdir = './user_private_files/';
// "basename" in case we log in little Jack Folders (Bobby Tables's cousin)
$user = basename(strtolower($_SERVER['PHP_AUTH_USER']));
$file = $pvdir.$user.'.php';
if (file_exists($file))
{
include $pvdir."any_common_code_at_the_beginning_of_user_files.php";
include $file;
include $pvdir."any_common_code_at_the_end_of_user_files.php";
exit();
}
include ugly_error.php;
}
htauth is .. old :D
Well, in any case. You can fetch the user credentials from the $_SERVER variable somewhere and switch based on that.
var_dump($_SERVER); to see which property you need.
Then use header("Location: /go/here.html"); to redirect the user.

Security reason url parts hiding?

I have a big security problem with my program, and I need to make parts of my URL's hidden. I have searched on the net for a solution, with no luck. In my program I have admin and user accounts - the program is simply a database for workers dosie. Admins can see all dosies but the other users can only see dosies that are in their work group. So my problem is, when a user comes to see the dosie, the URL to access the information looks like this: "viewdosje.php?album=108. The problem being that the user can simply change album id and he can see other dosies, which is not good. For example:
"viewdosje.php?album=109"
By changing the number in the URL he can see other dosies. It would be great to hide that part of URL, or am I wrong? Please help me with an idea of some kind. I don't know where to start.
You should not hide the url, but validate the access to the resource in the application instead. When you receive the ID, before displaying content, perform a DB query to see if the current logged in user has access to that resource or not.
Relying on "hiding" URLs is a terrible solution - anyone who can get access to the URL can get access to your private data. URLs can be accessed in all sorts of ways - sniffing web traffic (e.g. at insecure WIFI points), through JavaScript, through guessing, through getting access to browser history, and through all kinds of even scarier routes like trojans, keyboard loggers etc.
If the data in these employee records is sensitive/private, in most countries you are legally obliged to protect it adequately; even if there's no legal requirement, your company probably wants to avoid putting everyone's salary into the public domain.
The correct solution is to design a login mechanism, and assign user rights; when a user tries to access a page to which they don't have access, you send them an appropriate error message. There are numerous solutions for this in PHP - PEAR has a good implementation.
I've no real experience with PHP so I can't help there, but if I was tackling this problem with JSP, or Rails I might do the following:
Perhaps store user identifiable information in a cookie, once authenticated, compare this information to the user database ? Prevent the page being served to unauthorised users if they manually edit the url.

PHP possible to lock downloaded content?

I am currently working on a project that will work on a membership system. The theory behind the website is that you can download electronic (PDF) versions of a magazine, if you are a paying member of the website.
The problem arises in that after downloading the PDF it can be sent to anyone and accessed by anyone. Is there a way to only allow the member that paid for the PDF access to it. Is there a 3rd party service that could host the PDF's and allow them to read by the user at a unique URL that holds a random string unique to that download?
Being able to stop the ability to openly distribute the PDF's and view them without being a member is paramount.
Does anyone of have any ideas? Basically I am looking for a DRM like system for PHP (I am assuming it is impossible)
Render their name, credit card number and valid thru date on every single page.
Password protect the PDF with a passkey that is unique to the user who has downloaded it (such as their password for your site). There's nothing to stop the registered user giving away their passkey to anybody else that they give a copy of the file to though.
You can hide the PDF's URL from the user by using a download.php together with an ID that will only deliver files to the user if he/she has the appropriate rights. This way you can prevent users from sending the download-link to somebody else. Users without the proper credentials won't be able to start the download then ...
But: As soon as the PDF left your server (even if a second user may not be able to download it), the first user can do whatever he/she likes with it. Even if you encrypt your PDFs, hide them in password-protected ZIP-archives, lock them in a chest and bury them six feet underground ... the first user must have the information to read the PDF and can give it to anybody else ...
If users can read the text on their computer screen then it's already on their machine. In that case your only ally against unsolicited copying is ignorance.
In other words, it's sensible to make the copying of text as difficult as possible.
For example, don't offer the PDF directly but display it through a Flash-based reader. Then the only way for users to copy it is to make a screenshot of each page. Which is the best "copy-protection" you can get without using heavy-handed encryption in combination with a physical security token.
And of course, you can include sensitive information on every page, such as names, passwords etc to make the theoretical copying process even more ardous.
How about this--rather than --giving-- them a copy that they can do whatever with, why not give them access to a Flash-based "pageflip" system with your pdf on it. You control access to the page via login, and you also control the content.
ANY code or content that you give to the user can be stolen. It just depends on the energy and knowledge of your user as to how many will steal it. Many times, the tougher the protection, the more likely they are to share it with others...hence, the plethora of Adobe CS5 downloads on Warez sites.
(Yes, for those of you who will inevitably point it out, I can steal flash too, but it's a lot of work!)

Controlling Access for Trial Subscription

I've been tasked to build a system that allows someone in our company to send out an email with a link to a pdf file that will be kept on our webserver. The recipient can follow the link to view a newsletter we normally sell. The idea is we do this for three months, then see if they'd like to continue and pay for the full subscription.
I've got the registration portion built, but I'm trying to find the best solution for sending the email. Here's what I've thought of, but am interested if anyone else has something better..
1) When emailing, generate a generic code that gets appended to the URL. The use would follow the url, and it would check our DB for "ok" entries and pass/fail them access. This seems ok, but a link could be passed around or even loaded to a public site where anyone could access.
2) To extend the above, I thought maybe I'd have a "one time click" kind of thing where once I know the link was clicked, it could expire, so any subsequent clicks fail. The downside is if they click to view and close their window, they're done. Likewise, if they click and their computer crashes before download completes, they'd be locked out as well. I don't know if there's a way (in PHP for me) to confirm a file download has completed...
3) I could put the files in a directory like /trials/201009/r#nDomstr1n6.pdf where the file is uploaded and the name for the link is random so it would be hard to guess. Then I could use .htaccess to protect each month's folder with a different password. This could get tedious and would be annoying for users most likely.
We don't want to force them to manage their own passwords b/c having to login and remember yet another account may discourage participation.
Thanks for any ideas or pointers.
D.
I'd say do it with a random code for authentication per email address, and expire that after 5 days. If you limit access to the ip that first hit the url hash, that could work too but could iconvenience legitimate users/customers.
In any case make it easy for legitimate users to request a new authentication code if needed. That way even if any of your limitations inconvenience one of your potential customers, they will not be as ticked off about it.
Finally, consider that if they like the pdf and want to share it, they will probably just share the pdf itself right away and not bother with a link.
First off, realize that there is only so much you can do here on your end. You are allowing users to download a PDF, after which they can do with it what they please (legally or otherwise). So, preventing passing around the link is not necessarily going to prevent people from sharing or posting the PDF itself.
That said, if you do want to make it a little harder, you could do a variation of your suggestion #2 in which you institute a time delay of some kind before the link expires after it is clicked. You could also limit the number of times the link will serve the file. Because people have a variety of connection speeds, and because I do not know how large your PDFs are, I cannot say for sure what the time delay should be if you choose to use it.
Like I said, though, if someone is determined to share the file, they can easily do so.
Another possibility is that since you already know the persons email address, form a specific url for them in their email link.
So a user would click a link http://www.yourdomain.com/download_pdf.php?email=person#test.com
Keep a table with the following data for the email addresses.
id
email_addr
read_date
expire_date
When they click the link check to see if they've read it before and if they have check it hasn't expired. If it hasn't, serve the pdf to them, if it has give them a page that says "Sorry, your trial has expired../"
If its their first time clicking it then set the read_date and calculate the expiry date and set that.
Or optionally you could generate a hash or something and use the hash to id the user instead of their email address.
You could also set up a download column int he table and stop them from downloading it more than twenty times or something by incrementing the download column every time they click the link.

Categories