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.
Related
At the moment, I'm working on a website that could use some extra user usability, so I want to launch a couple of modal windows to aid users on their first time visiting of a couple pages.
I want to check if it is a users time time viewing a specific page. I've read about how you can run into problems when using cookies to do this. They can be deleted, the user can use a different PC or device, etc.
Also, I want to check for multiple pages if it's their first time viewing, not only directly after login.
I'm guessing a good idea for this would be to make a separate table with the pages in it that I need and setting a boolean for it if it is viewed or not.
Would this be the best way going about doing this?
There isn't a highly reliable way of doing that:
You can use cookies, but as you said, they are not reliable, a user can change PC, delete cookies, change browser, etc.
You can try using an IP address, but that's also not reliable. If a user switches address (which can today happen as you walk down the street with your mobile phone) he'll see the page over and over again. Moreover, if some other user happens to stumble upon the IP address the first user used, he won't see your tour/tutorial.
What I can suggest you is that you use cookies to detect if the user is new, but don't automatically throw the help modules on him, but prompt him using an non-obstructive toolbar at the top or bottom (never a popup window or lightbox).
That way, you get most of the users (because many people use the same browser and computer and rarely delete all their cookies), and even if a user has deleted his cookies/he still won't be disturbed that much.
There is no reliable approach if user is not registered and logged in with her/his username & password.
As mentioned before, there is no reliable way of detecting users ( and detecting if the user visits the site the first time), I also recomend Madara Uchiha's aproach, also you colud use html5 local storage in addition to cookies, both are not 100% reliable
u can however try user recognition without relying on cookies or html5 storage, but this is extremly complicated, u dont want to do this.
Just to satisfy your curiosity about how to do this, check this epic answer on a related question:
User recognition without cookies or local storage
I think, as I believe, there is no way with no solution. I think, a possible way consists of some parameters which first to be said and and finally by considering those, we can be able to talk about possibilities and impossibilities.
My parameters are in the below;
talk about features of a webpage as "User Detection" and detail them
think about reactions (I mean being fast to click on any elements of a page or not) on a webpage
inspect elements
URL injection
other reactions like click on some parts as spots placed on the page
stay on that page up to a time defined for being and checking authorizing
and so some solutions like the ones above.
I'm currently working on my Referral System, but I have a problem with protecting it of frauds.
Okay, here's how it works for now:
user registers and activate it's account
user now have access to the control panel and there is it's uniqe link in following format: domain.tld/ref/12345
when someone other click to user's link, he or she must to click a specific button to confirm that is not some kind of fraud (like "click here, you'll get $100" or something)
system writes visitor's IP in a database and some data to cookies to prevent re-pressing the button. User now have +1 point.
But, the problem is that visitor can change it's IP, clear cookies and hit button again. It takes a few seconds, and that's not OK, that's cheating.
How to prevent it? Is there some trick to get some unique computer ID or something can't be changed that easy?
Really the only options are to tie the process to something which is not so easily manipulated by the user - super cookies, browser fingerprints, OpenID, Email addresses and telephome numbers (the latter 2 using some sort of validaton step before a vote is counted)
The only way you can be certain a referred party does not reuse a referral code is for the original user to send different one-time-use-only referral URLs to each person. Once the code has been used, it is flagged as such in (or removed entirely from) your database so that it can not be used again.
How you prevent the original user from sending multiple links out to the same person is another matter - and not an easy one to resolve.
Who do you perceive to be the threat?
Although it's certainly not 100% accurate, you can still fingerprint visitors using for example a combination of their ip, browser user agent, and with some javascript you can even go for screen size or installed fonts. Using these pieces of information you can set up a system where you save the fingerprints in datatable and in the same record you store the session id (from the cookie). Now when a new visitor arrives you can test their fingerprint against the db of recent fingerprints with different visitor ids. If you find a large number of matching fingerprints (you define the threshold) with different sessions then you can alert for the possibility of fraud.
Cheers
How about storing the link with with the user when they navigate to the link. then in the database you will have the link and if the users has already been to the link then deny them. Seems like it could work then you wouldn't have to worry about the cookies etc...
I currently have a website built in PHP, I'm hoping to build a referral system tonight.
My theory is that if I dynamically generate a url and place it on my users' homepage such as
"Referral url = www.mysite.co.uk/referral.php?user=myuser"
Then I could have a script in the page referral.php which gets the username and runs an sql query updating their corresponding row in my table.
The only thing is anybody could then add there own name and sign up multiple accounts.
What is the best way to go about building something like this?
Thanks
Suppose to get the referral url my users had to click a button which generates the referral url as a rand ie mysite.com/refer.php?user=234234, at the same time storing it in a the db.
Once somebody visits the page refer.php, the referrer then gets his credits or benefit added to his row in the db, at the same time setting his referral code to 0, making the code only available once.
Each time he hits the button on his page, his referal code would change.
Would this be valid do you think?
You generally have the right idea, but protecting against fraud in a referral system is difficult. You can check for unique IP addresses in $_SERVER and add that to the database for each request, throwing away duplicates or limiting referrals from IP addresses that don't come from the user who signed up. Like HTTP_REFERRER, this can be spoofed as well with ease (using TOR for example).
It's a tough problem that isn't something you can truly "solve." Like most fraud cases, you can only do your best to mitigate the effect.
EDIT TO ADD: You can also require referrals to "mature" by forcing the referred user to be active on the site for a defined period of time (say, 30 days) to increase the effort of spammers/cheaters. But again, this doesn't "solve" the problem - all you can do is make it tougher for them to game the system. And occasionally, by doing this stuff, you can ruin user experience. So how do you balance it? Tough question. :)
EDIT TO ADDRESS YOUR EDIT: Contemplate the following scenarios if we implement your plan:
1) I click the button and get my code. Then I paste it to... who exactly? One person? That's not particularly good for sharing on Facebook, MySpace (does this exist?), or my personal blog. I have to generate a referral code for EVERY person I send to the site? That not only scales terribly, but is a horrible user experience as well.
2) Let's say I figure out what you're doing. I develop a bot that clicks that button 4 trillion times. What now?
You could use the 'HTTP_REFERER' value to check what page the request came from, and only allow votes for that user from their page. This can be spoofed, but most people won't know how.
You can count the referral points for some additional action on your site, for example registration or payment or anything that is behind captcha check.
But do not build any obstacles for your regular legit users!
you could embed this information in the POSTDATA - it's a tad more secure.
Or you can add a restriction that any user may be upvoted ONLY by any other EXISTING user only once. And to make it more "secure", generate userIds with a random seed.
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!)
I want to allow users as well as me(the admin) to delete data in mysql.
I used to have remove.php that would get $_GETs from whatever that needed to be deleted such as... remove.php?action=post&posting_id=2. But I learned that anyone can simply abuse it and delete all my data.
So what's the safest way for users and me to delete information without getting all crazy and hard? I am only a beginner :)
I'm not sure if I can use POSTs because there is no forms and the data isn't changing.
Is sessions good? Or would there be too many with postings, user information, comments, etc.
Ex: James wants to delete one of his postings(it is posting_id=5). So he clicks the remove link and that takes him to remove.php?action=post&posting_id=5.
EDIT: Alright, so now I am a little confused. While I can't be 100% secure, how do I do this with $_POSTs?
SOO I should use GETs to get all the data to remove.php, THEN have a confirmation submit button and when users click on it, it put all the data into POSTs and delete from the dbc?
Deleting records is a kind of a scary practice. If you or someone makes a mistake there's no real recourse to resolve the issue. Expunged records are very hard to resurrect.
Instead of deleting records, you could add an "active" bit (e.g. Boolean) column that is toggled off when users "delete" records. Essentially your users would be suspending records by toggling them off and the records would be saved in case mistakes or abuse but appear "deleted" to the user. To make this work with your other queries, just add a where clause of active = 1.
You could then have a utility script that's run at some specific date interval that would clean out deprecated, past dated records. You'd also need some type of timestamp for this type of maintenance.
Just a thought. Take if for what it's worth.
I'll echo gurun8 in preferring to 'mark' records as deleted, instead of actually removing data. And then obviously, you'll need to check that the authenticated user has permission to delete the post.
However, it seems very important to mention that $_GET is not safe even with authentication because of cross-site request forgery.
Imagine if Amazon adding things to your cart based on a GET request. All I'd have to do is put an image on my page with that URL, and everyone who visited that page and logged into Amazon will have products added automatically.
To match your example, I don't like Jame's post, so i put an image on my site like this:
<img src='http://example.com/remove.php?action=post&posting_id=5'>
And I send him a link to my page, and ask him to check it out, hoping that at the time he's logged in to your site. Because, of course, he clicked that little 'keep me logged in' button.
So you are right to be concerned about using GET. If you don't want to litter pages with forms, then confirm the action by POST.
Well you have to start by authenticating the users with a login script.
If you want the simplest solution possible, then I'd suggest protecting the directory in which you have remove.php with a simple .htaccess username and password.
If different users have different rights for deleting database entries, then you probably should create a PHP login script and use PHP session.
Bonk me if I'm stupid, but I searched for quite some time for a simple PHP login tutorial that could be placed on a real site (doesn't use session_register(), uses mysql_real_escape_string(), htmlspecialchars() etc) and I simply couldn't find one!
Probably this one comes the closest, you just have to replace session_register() variables with $_SESSION ones for it to work without register_globals (default in PHP5).